地址和指针的概念
这种方法不能实现将a,b的值互换, 这种方法不能实现将 的值互换, 的值互换 的值, 因为只交换形参p1和p2的值 使它 们 的指向发生改变, 的指向发生改变 但是main函数中 的a和b的值并没有进行交换所以输 出为: 出为 a=5, b=9
main pt1 &a a 5
swap3 &b p1 &a
等价于 ++p ; d = *p ; 执行后 d 的值为 3 , *p 的值为 3
= *p ; p++ ;
由于p的数据类型为 所以 由于 的数据类型为int所以 的数据类型为 p++等价于 等价于p=p+2。参看课本 等价于 。 P212 第二自然段的说明。 第二自然段的说明。
输入a和 两个整数 两个整数, 例10. 2输入 和b两个整数,按先大后小的顺 输入 序输出a和 。 序输出 和b。 &a p1 &b 5 a #include <stdio.h> void main( ) p2 &b &a 9 b { int *p1 , *p2 , *p , a , b ; scanf(“%d%d”, &a , &b); p1 = &a ; p2 = &b ; p &a if (a<b) 输出结果: 输出结果 { p = p1 ; p1 = p2 ; a=5 , b=9 p2 = p ; max=9 , min=5 } printf(“a=%d, b=%d \n”, a , b); printf(“max=%d, min=%d \n”,*p1 ,*p2) ; } 本程序的目的是:实现在指针变量 中存放值较大的 本程序的目的是:实现在指针变量p1中存放值较大的 变量的地址; 中存放值较小的变量的地址 中存放值较小的变量的地址。 变量的地址;p2中存放值较小的变量的地址。
2012 int a , *p ; 指向a 让p指向 指向 p = &a ; scanf ( “%d” , p ) ; printf (“%d\n” , *p ) ; *p = 12 ; printf (“%d\n” , *p ) ; 2. & 与* p = &a ; &*p &(*p) &a 1010 p 等价于&a 等价于 对a 重新赋值 等价于 a=12
2. 指针与指针变量 (1) 变量的访问方式 ① 直接访问 : 通过变量名或地址访问变量的存储区 例 : scanf ( “%d” , &x ) ; x = sqrt(x) ; printf ( “%d” , x ) ; ② 间接访问 : 将一个变量的地址存放在另一个变量中 2012 1010 如将变量 x 的地址存放在 变量p 访问x 时先找到p, 变量 中, 访问 时先找到 1010 再由p 再由 中存放的地址找到 x p x (2) 指针 一个变量的指针就是该变量的地址 指针就是地址 指针: 一个变量的指针就是该变量的地址 指针就是地址) 变量的指针就是该变量的地址(指针就是地址 如变量x的指针为 的指针为1010。 如变量 的指针为 。 (3) 指针变量 存放某个变量的地址的变量 它用来指向另一 指针变量: 存放某个变量的地址的变量, 个变量。 个变量。如p
2012 1014 1010 1012 p
1010 2 3 5 3 3 a b c d
p 的值为 的地址 *p 的值为 的值为a 的地址, 的值为2 语句执行之后p 语句执行之后 的值不变 , *p 的值为 3 (2) c = *p++ ;
关于*p++的说明:由于*和 关于*p++的说明:由于*和++ 的说明 等价于 c = *p ; p++ ; 运算符的优先级一样,遵从从 运算符的优先级一样, 右到左的顺序, 执行后 c 的值为 3 , *p 的值为 5 右到左的顺序,所以等价于 *(p++)。由于 在p的后面, 的后面, 。由于++在 的后面 (3) d = *++p ; 则先操作后加一, 则先操作后加一,所以写成c
说明: 这种方法可以实现将a,b的值互 说明 这种方法可以实现将 的值互 换,但是可能会破坏系统的正常工作 状态,因为 状态,因为temp是一个指针变量但 是一个指针变量但 是 在函数中并没有给temp一个确定的 一个确定的 在函数中并没有给 地 址,这样它所指向的内存单元是不可 预见的,而对*temp的赋值可能带来 预见的,而对 的赋值可能带来 危害
三、 指针变量作函数参数 例: 2个数按大小顺序输出 个数按大小顺序输出 (整型变量做参数) 整型变量做参数) 整型变量做参数 #include <stdio.h> void swap( int x , int y) { int temp; temp = x ; x = y; y = temp; }
main a b 5 9
swap 9 5 5 9 5 x y temp
void main( ) { int a , b ; scanf(“%d%d”,&a, &b); if (a<b) swap(a , b); printf(“a=%d, b=%d\n”, a, b); }
说明: 该程序不能实现a 和b 说明 的交换因为实参a , b 对形参 x , y 是“值传递”, x 和y 的 值传递” 变 化不影响a 和b 所以输出为: 所以输出为 a=5, b=9
main swap1 例 10. 3 ① 指针变量做参数) (指针变量做参数) &a p1 pt1 &a #include <stdio.h> void swap1(int *p1 , int *p2) a 9 { int temp; 5 temp = *p1 ; *p1 = *p2; pt2 &b &b p2 *p2 = temp;/*交换的是指针变 交换的是指针变 量指向的变量的值*/ 量指向的变量的值 b 5 } 5 temp 9 void main( ) 说明: 说明 这种方法是交换p1和 { int a , b , *pt1 , *pt2 ; p2所指向的变量的值 即 所指向的变量的值, scanf(“%d%d”,&a , &b); 交换main函数中a 和b的值 pt1 = &a ; pt2 = &b ; 所以输出为: 所以输出为 a=9, b=5 if (a<b) swap1( pt1 , pt2) ; printf(“a=%d, b=%d\n”, a, b); }
10.2 变量的指针和指向变量的指针变量
一、 指针变量的定义 1. 格式 : 数据类型 * 指针变量名 ; int *p1 ; 例 char *p2 ; 2. 说明 : (1) 在变量定义时 * 号表示该变量是指针变量 在变量定义时, ( 注意 指针变量是 , p2 , 不是 注意: 指针变量是p1 不是*p1 , *p2 ) (2) 定义指针变量后 系统为其分配存储空间 用以存放 定义指针变量后, 系统为其分配存储空间, 其他变量的地址, 但在对指针变量赋值前, 其他变量的地址 但在对指针变量赋值前 它并没有 确定的值, 确定的值 也不指向一个确定的变量 2012 1010 例: int x , *p ; x=5; 指针变量p的值是随机值 的值是随机值, 注: 指针变量 的值是随机值 此时p 此时 和 x 并无关联 1234 p 5 x
例 10. 3 ② main #include <stdio.h> pt1 &a 指针变量做参数) (指针变量做参数) void swap2( int *p1, int *p2) { int *temp; a 9 5 *temp = *p1 ; *p1 = *p2; pt2 &b *p2 = *temp; }
swap2 &a p1
&b
随机值
p2 temp ?
b
5 9
5
例 10. 3 ③ #include <stdio.h> 指针变量做参数) (指针变量做参数) void swap3( int *p1, int *p2) { int *p; p = p1 ; p1 = p2; p2 = p; /*交换的是指针变 交换的是指针变 量的值*/ 量的值 }
将数组a中全部元素加 再输出a 中全部元素加1, 例: 将数组 中全部元素加 再输出 p #include <stdio.h> void main( ) { int a[5] = {1, 3, 5 ,7 ,9 }, *p , j ; for ( p=a ; p<a+5 ; p++ ) printf(“%3d”, *p);/*按指针访问数组 按指针访问数组*/ 按指针访问数组
第十章 指针
10.1 10.2 10.3 10.4 10.5 10.6 地址和指针的概念 变量的指针和指向变量的指针变量 数组的指针和指向数组的指针变量 字符串的指针和指向字符串的指针变量 函数的指针和指向函数的指针 返回指针值的函数
10.1 地址和指针的概念
一. 地址与指针 1. 地址与取地址运算 C程序中的变量在内存中占有一个可标识的存储区 程序中的变量在内存中占有一个可标识的存储区, 程序中的变量在内存中占有一个可标识的存储区 每一个存储区是由若干个字节组成, 每一个字节都有 每一个存储区是由若干个字节组成 自己的地址, 自己的地址 而一个存储区的 地址是指该存储区中 第一个字节的地址 C语言允许在程序中使用变量的地址 语言允许在程序中使用变量的地址 地址运算符&可得到 ( 通过地址运算符 可得到 通过地址运算符 可得到) 如: float x ; 变量 x 的地址 ---- &x int a[10] ; 数组变量 a 的地址 ---- 数组名 a