【c语言】深入理解指针1
深入理解指针1
- 一、数组名的理解
- 二、使用指针访问数组
- 三、一维数组传参本质
- 四、二级指针
一、数组名的理解
数组名就是数组首元素的地址,类型是指针类型,但是存在两个例外:
sizeof(arr) : 整个数组在内存中的大小
&arr : 整个数组的地址
但是&arr的值和arr的值是一样的,本质上都是数组首元素的地址,因为整个数组的地址也是从数组第一个元素的地址开始的
结果上来看 arr == &arr == &arr[0]
二、使用指针访问数组
- 用p来存放数组首元素的地址,p和arr等价
- 在编译过程中,编译器会把 arr [ i ] 转化成 *( arr + i )的形式进行编译, 因此两者也是等价的
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9 };int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;int* p = arr;for (i = 0;i < sz;i++){printf("%d ", arr[i]);}printf("\n");for (i = 0;i < sz;i++){printf("%d ", *(arr + i));}printf("\n");for (i = 0;i < sz;i++){printf("%d ", p[i]);}printf("\n");for (i = 0;i < sz;i++){printf("%d ", *(p+i));}return 0;
}
三、一维数组传参本质
- 一维数组传参实际上传递的是数组首元素的地址
比如计算函数内部和函数外部数组元素个数
可以看出,数组的实际元素个数是9个,但在函数内部只算出1个,因此传参只传递了一个元素的地址,即首元素地址
- 一维数组传参,形参部分可以写成数组形式,也可以写成指针形式,因为本质还是指针,写成数组形式只是便于理解
示例:编写函数打印数组
void print1(int arr[], int len)
{int i = 0;for (i = 0;i < len;i++){printf("%d ", arr[i]);}printf("\n");
}
void print2(int* p, int len)
{int i = 0;for (i = 0;i < len;i++){printf("%d ", *(p + i));}
}
int main()
{int arr[] = { 2,3,4,5,6,7,8,9 };int sz = sizeof(arr) / sizeof(arr[0]);print1(arr, sz);print2(arr, sz);return 0;}
四、二级指针
- 二级指针:存放一级指针变量的地址的变量,本质是指针类型,大小是4/8个字节
进而可以类比出三级、四级…指针
p存放的是a的地址,p是一个指针变量,它的地址存放在pp中,pp则是二级指针变量
- 二级指针的运算
用上图举例,*pp
得到的是一级指针存放的内容,即a的地址,**pp
等价于*p
, 得到的就是a的值10.
从调试窗口可以看到:
一级指针p存放的是整型变量a的地址0x009dfdfc
,类型是int*
;
二级指针pp存放的是一级指针变量p的地址0x009dfdf0
,类型是int**
;
*p
得到的是a的值10;
*pp
得到的是p存放的内容,即a的地址;
**pp
得到的是变量a的值10.