C语言学习小结:
指针的初始化
指针变量可以初始化为0,NULL或一个地址[16进制]
0和NULL等价,相当于一个空地址
//使用(变量类型 *变量名)这样一个组合就可以声明一个指定类型的指针变量 int *a;
- 指针变量就是用来存储变量地址的一种变量
- 指针的存储的地址指的是该变量的起始位置
指针运算符
- *指针运算符,用于把指针指向变量,可用于获取变量的值
- &取址运算符,用于获取变量的地址
- *(&a)和&(*a)的效果相同,都是获取变量的地址,只是处理的次序不同
例子:
#include <iostream> int main(){ int *a,i=100; printf("a的位置%p,i的值:%d\n",a,i); a=&i; printf("a的位置%p,a的值是%d\n",&a,*a); }
运行结果:
为什么要指定指针变量的类型?
指针变量不仅仅是要存储变量的地址,同时也要记录变量的空间大小。
因为C语言传递变量时需要把数据传入已确定的内存地址及其所占的空间,
所以一个char类型的指针不可以直接指向一个int型的变量,如果强制操作将会导致越界的bug。
指针偏移:
#include <iostream> void main() { int *a[3];//初始化整型指针 int b[3] = { 1,2,3 }; a[0] = &b[0];//将b[0]的地址赋值给a[0]存储 a[1] = &b[1]; a[2] = &b[2]; printf("a的原来指向的值%d\n", **a);//*a仅仅是获取到b的地址,**a才是获取到b的值 printf("a的变化后指向的值%d\n", **(a+1));//a+1指的是a[1]然后再重复上一行的操作 }
指针指向多维数组
#include <iostream> void main(){ int a[3][3]={1,2,3,4,5,6,7,8,9}; int *b[3]; b[0]=a[0];//在多维数组中,b[0]=a[0]会自动指向a[0]的地址,不用像一维数组,使用取址符指向a[0] b[1]=a[1]; b[2]=a[2]; printf("a[1][2]的值%d\n",*(*(b+1)+2));//现将b指向b[1],然后将b[1]指向b[1][2] }
为啥指针指向一维数组时,需要使用取址符,但是指向多维数组时的第一维时不用取址符?
因为指针指向一维数组时,b[0]代表的是一个值,而不是一个地址,所以需要使用取址符来获取这个值得地址,
但是当指针指向二维数组时,b[0]的身份是一个地址,所以就不用使用取址符就可以直接获取到地址了。
One More Thing
数组p[i]是c语言中的一种语法糖
即使函数被设计成void fun(int array[5], int n),array依然被看成是指针。也就是说即使数组带了长度,该长度也会被编译器忽略掉。(即:a[i]=>*(a+i))
一句话:形参中的数组统统看成指针。
既然如此,还不如直接写成void fun(int *array, int n)。指针的形式,更能表达本意。
array和&array都是指针,但类型不同。array的类型是int*,而&array的类型是int(*)[2]。array是指向普通int类型的指针;&array是数组指针,该数组元素是int类型的,且数组大小是2。