持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
指针常见的错误
未初始化就直接使用
代码如下(示例):
#include<stdio.h>
int main()
{
int* p;
*p = 3;
return 0;
}
注意:int* p;//局部变量未初始化是随机值。*p = 3;//这里访问了未初始化的空间报错
指针越界访问
代码如下(示例):
int main()
{
int a[10] = { 0 };
int* p = a;
for (int i = 0; i <= 10; i++)
{
*p = 1;
p++;
}
return 0;
}
注意:int* p = a;//这个地方 a表示数组名,数组名sizeof(a)和单独&a的时候是指向整个数组的地址,其他情况都是首元素地址。还有就是指针越界了其实不会造成影响,但是这里修改了指针指向内容的值会报错
代码的练习
先给出下面做题的结论:sizeof里面得到的结果是类型属性,不是值属性,是不会去计算的。
sizeof(数组名) - 数组名表示整个数组的 - 计算的是整个数组的大小
&数组名 – 数组名表示整个数组,取出的是整个数组的地址
此外的所有数组名都是数组的首元素大小
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));
- 16
- 这里的a就是首元素地址,是地址就是4字节(32位)
- 这里的a也是首元素地址,1的地址被解引用找到1,int的大小就是4
- 4*这里的a也是首元素地址,这里是第二个元这里的a也是首元素地址,1的地址被解引用找到1,int的大小就是4是多少就不用说了吧
- 4 --2的大小,那肯定是4个字节
- 4 --这里就是整个元素的地址,满足&数组名
- 16 -- 这里就是整个数组解引用,拿到整个数组的元素
- 4 -- &a + 1数组后面的空间的地址
- 4 -- a[0]是第一个元素,&a[0]第一个元素的地址
- 4 --a[0]+1是第二个元素,&a[0] + 1第二个元素的地址
char arr[] = "abcdef";,//这里是用常量区的"abcdef"初始化了arr,在栈区上开辟了一块空间
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
//printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
- 7 --算的是整个数组的大小加'\0'
- 4 --算的是首元素地址的大小
- 1 --arr首元素地址,这里计算'a'的大小
- 1--‘b'的大小
- 4--整个数组的地址的大小
- 4--f后面的地址,地址的大小
- 地址的大小 4字节
- 6
- 6
- error 代码报错
- error 代码报错
- 6 指针有类型差异,结果和 strlen(arr)一样,上面解释过相似的题目
- 随机值
- 5
//字符数组
char arr[] = { 'a','b','c','d','e','f' };//6个字符
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
//printf("%d\n", strlen(*arr));
//printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
- 6 --整个元素的地址单独放在sizeof内部,满足要求,计算整个数组的总大小
- 4--arr为首元素地址,即第一个元素的地址,字符的地址也是4字节
- 1-- 第一个元素'a'放在sizeof内部
- 1 --第二个元素 'b'
- 4--整个数组的地址
- 4--下一个整个数组的地址 (类似上面那张图的情况)
- 4--&arr[0]的指针类型是int*,加1跳过一个整形,‘b’的地址
- 随机值 --无\0
- 同理
- 'a' -- 出错 这里相当于strlen一个整数,错误的strlen的参数是(const char * str),这里把一个整数当成地址,代码出错
- 同理
- 随机值 ,整个数组的地址,值与第一个元素的地址相同,但意义不同,图如下
- &arr的类型为char(*)[6],随机值-6 ,整个数组的地址,图如下
- &arr[0]的类型为char*,'b'的地址找到\0就停 ,值为:前面的随机值-1