指针是一种保存变量地址的变量,指针存储的内容是它指向的变量的地址。
一、指针的基础
类似于int *p;
int a = 10; int *p = &a;
则a存储的是10,而p存储的则是a的地址。操作则是*p+10,这其实就是a+10。指针是变量,所以可进行操作
二、指针与函数
前段时间就是说的交换的函数,函数要实现传入值得交换,就要使用指针。函数正确的方式应该这样写
void swaps(int *a,int *b) { int temp; temp = *a; *a = *b; *b = temp; } //使用 swaps(&a,&b);
因为如果不使用指针,则交换的仅仅只是传进来的副本,而真正的变量并没有改变。所以当时就迷惑了下面这种交换方式为什么不正确
void swaps(int *a,int *b) { int *temp; temp = a; a = b; b = temp; } swaps(&a,&b);
这个错就错在了交换是副本的问题。
如图所示,p指向a,q指向b,如果是第二种方法,其实就是创建了一个临时的副本i,j,里面存储的是和p,q一样的指针,如果第一种方法,则直接交换的是i,j指向的变量,也就是a和b,而如果是采用的第二种方法,其实只是交换的i和j,导致的就是i指向了b,j指向了a,如果在函数体内执行下面的函数打印,会发现的确变了,但是跳出函数体后,并没有设计外边的改动。
void swaps(int *a,int *b) { printf("%p,%p\n",a,b); int *temp; temp = a; a = b; b = temp; printf("%p,%p\n",a,b); printf("%d,%d\n",*a,*b); }
这时候打印的
0x7fff5fbff95c,0x7fff5fbff958
0x7fff5fbff958,0x7fff5fbff95c
20,10
可见的确交换了,但是不影响真正的变量。
三、指针与数组
指针和数组关系十分密切,比如说这个
int a[5];
int *pa;
指针照样是存储的地址,比如说第四个地址的话就是
pa= &a[4];
而数组名a其实也是一个指针,指向的是数组的第一个
所以 pa=&a[0]和pa=a是一样的。
pa和a不同的是:a是一个数组名,他不是变量,而pa则是一个变量,所以pa可以执行pa+1,pa++等变量的操作,而pa+1就是指向的pa的下一个元素的地址,所以如果pa==a,则pa+1==&a[1];
所以pa+n就是指向的pa的第n个元素,计算pa+n的时候,n会根据pa指向的对象的长度按比例缩放,而pa指向的对象的长度就取决于pa的声明,比如说int 类型占4个字节的存储空间,那么在int类型的计算中,对应的n就按4的倍数来计算,所以就是第n个元素了。
C语言保证,0永远不是有效的数据地址,所以虽然指针与证书之间不能相互转换,但是0却是唯一的例外。常量0可以赋值给指针,也可以将指针和0比较,当然也可以使用NULL代替0。
有效的指针运算包括相同类型指针之间的赋值运算,指针和整数之间的加法或减法运算,指向相同数组中元素的两个指针间的减法或者比较运算,将指针赋值为0,或指针与0之间的比较运算,其他所有形式的指针运算都是非法的。
版权属于:东哥笔记 - DongGe.org
本文链接:https://dongge.org/blog/231.html
自2017年12月26日起,『转载以及大段采集进行后续编辑』须注明本文标题和链接!否则禁止所有转载和采集行为!