【一】引言:
1;scanf函数中的&其实就是输入一个值的地址。
2;用printf输出一个地址,例如:printf(“%p”,&i);这表示的是输出i的地址。
……
【二】取地址的值:
在32位架构下取地址的值,等于该地址强制转换为整数的值。
但64位架构下取地址的值,不等于该地址强制转换为整数的值。
所以不能将取地址的值,看成是一个整数。
……
【三】取地址的对象:
只能对一个变量取地址,例如&a,不能取诸如&(a+b)这种的地址。
……
【四】变量和数组取地址的方式:
以自顶向下的方式,存在堆栈。
比如int a,b;
则是将a的值放在上面,将b的值放在下面,而且由于是int类型,所以占据的空间是4。
如果是int c[10];
这是数组类型,同样遵循自顶向下的规律,并且a[0]和a[1]之间间隔是4。
注意:a[0]的地址等同于数组a的地址。
……
【五】指针在函数中的运用1:
指针,是保存地址的变量。
比如可以定义int *p=&i;(实际上就是用指针来保存i的地址。)
比如int i=1的地址是ox2000,那么p的值就是ox2000,p的值便是i的地址;而*p=1,*p表示的是变量i的值。
所以在调用函数时,要输入f(&a,&b),将地址输入函数中。
而在定义函数时,则要写f(*m,*n),用指针来接受地址。
以这种方式来定义的函数,是可以直接修改变量a和b的值,这也是指针很重要的一个用途。
注意:*p并不是一个变量,而是一个值。类似a[0]这样的数组也同样是一个值,可以近似来理解。
……
【六】指针在函数中的运用2:
使用指针,有一个最大的好处:指针可以让函数返回多个值。
在写函数的时候,一般是用return返回一个值。
如果要返回多个值呢?
显而易见,return没办法返回多个值。
那只能使用指针。
……
【七】数组变量是特殊的指针:
在函数的参数表中,f(int a[])等价于f(int *a)。
实际上。
数组变量是特殊的指针。
因为数组变量本身表达地址。(在scanf输入字符串的时候,可以不加&,字符串实际上就是数组)
如果定义一个数组int p[10],那么*p=p[0],*p代表的是数组中的第一个元素。
注:数组是const指针,不能进行赋值。(比如有两个数组a[10],b[10],不能让a[10]=b[10]。)
……
【八】指针与const:
取不同位置的const,所获得的效果也不一样。
第一种情况:
int * const a=&i;
上面的语句指的是a是常量,a的值其实就是i的地址,所以这个语句的意思是a的值不能改变。
如果进行a++操作,编译器就会报错。
第二种情况:
const int *a=&i;//1
int const *a=&i;//2
//1和2是相等的。
上面的语句指的是*a是常量,*a的值其实就是变量i的值,所以这个语句的意思是*a的值不能改变。
如果进行*a++操作,编译器就会报错。
……
【九】指针运算:
如果指针所指向的数是char类型,那么p++,表示的是p加上一个1。
如果指针所指向的数是int类型,那么p++,表示的是p加上一个4。
这是因为sizeof(char)=1,sizeof(int)=4。
所以,当要让指针加1的时候,不是在地址值上加1,而是加一个sizeof。
由于指针拥有这种特性,所以可用指针来遍历数组。
注:指针可以作比较、加减,但不能作乘坐。
……
接下来是三个典型的例子,可以帮助理解指针:
- #include<stdio.h>
-
- void swap(int *p,int *q);
- int main(){
- int a,b;
- scanf("%d%d",&a,&b);
- swap(&a,&b);
- printf("%d %d",a,b);
- return 0;
- }
-
- void swap(int *p,int *q){
- int t=*p;
- *p=*q;
- *q=t;
- }
- /*上面是两个数进行交换的代码。
- 如果不利用指针的话,其实可以直接在swap函数中输出交换后的值。
- 但如果使用指针,便可以让两个数在swap函数中交换,然后在主函数中输出交换后的值。*/
- #include<stdio.h>
-
- void minmax(int a[],int len,int *max,int *min);
- int main(){
- int a[]={1,2,3,4,5,6,7,8,9,12,13,14,16,17,22,33,};
- int min,max;
- minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
- printf("min=%d,max=%d",min,max);
-
- return 0;
- }
-
- void minmax(int a[],int len,int *min,int *max){
- int i;
- *min=*max=a[0];
- for(i=0;i<len;i++){
- if(*min>a[i])*min=a[i];
- if(*max<a[i])*max=a[i];
- }
- }
- /*这是输出数组中最大值和最小值的代码。
- 参数表里使用了两个指针变量,所以可以从minmax()函数中返回min和max这两个数回到主函数*/
- #include<stdio.h>
-
- int divide(int a,int b,int *result);
- int main(){
- int a,b,c;
- scanf("%d%d",&a,&b);
- if(divide(a,b,&c)){
- printf("%d/%d=%d",a,b,c);
- }
- return 0;
- }
- int divide(int a,int b,int *result){
- int ret=1;
- if(b==0)ret=0;
- else *result=a/b;
- return ret;
- }
- /*这是一个计算两个数相除的代码。
- 函数中不仅可以用return返回一个值ret,还可以同时用指针返回除数的计算结果。
- 可以返回多个值,这便是使用指针带来的巨大好处。*/