写点什么

【C 语言难点突破】指针的常见易错点

作者:Geek_65222d
  • 2022 年 10 月 06 日
    河南
  • 本文字数:1798 字

    阅读完需:约 6 分钟


指针常见的错误

未初始化就直接使用

代码如下(示例):


#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));
复制代码


  1. 16

  2. 这里的 a 就是首元素地址,是地址就是 4 字节(32 位)

  3. 这里的 a 也是首元素地址,1 的地址被解引用找到 1,int 的大小就是 4

  4. 4*这里的 a 也是首元素地址,这里是第二个元这里的 a 也是首元素地址,1 的地址被解引用找到 1,int 的大小就是 4 是多少就不用说了吧

  5. 4 --2 的大小,那肯定是 4 个字节

  6. 4 --这里就是整个元素的地址,满足 &数组名

  7. 16 -- 这里就是整个数组解引用,拿到整个数组的元素

  8. 4 -- &a + 1 数组后面的空间的地址

  9. 4 -- a[0]是第一个元素,&a[0]第一个元素的地址

  10. 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));
复制代码


  1. 7 --算的是整个数组的大小加'\0'

  2. 4 --算的是首元素地址的大小

  3. 1 --arr 首元素地址,这里计算'a'的大小

  4. 1--‘b'的大小

  5. 4--整个数组的地址的大小

  6. 4--f 后面的地址,地址的大小

  7. 地址的大小 4 字节

  8. 6

  9. 6

  10. error 代码报错

  11. error 代码报错

  12. 6 指针有类型差异,结果和 strlen(arr)一样,上面解释过相似的题目

  13. 随机值

  14. 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));
复制代码


  1. 6 --整个元素的地址单独放在 sizeof 内部,满足要求,计算整个数组的总大小

  2. 4--arr 为首元素地址,即第一个元素的地址,字符的地址也是 4 字节

  3. 1-- 第一个元素'a'放在 sizeof 内部

  4. 1 --第二个元素 'b'

  5. 4--整个数组的地址

  6. 4--下一个整个数组的地址 (类似上面那张图的情况)

  7. 4--&arr[0]的指针类型是 int*,加 1 跳过一个整形,‘b’的地址

  8. 随机值 --无\0

  9. 同理

  10. 'a' -- 出错 这里相当于 strlen 一个整数,错误的 strlen 的参数是(const char * str),这里把一个整数当成地址,代码出错

  11. 同理

  12. 随机值 ,整个数组的地址,值与第一个元素的地址相同,但意义不同,图如下

  13. &arr 的类型为 char(*)[6],随机值-6 ,整个数组的地址,图如下

  14. &arr[0]的类型为 char*,'b'的地址找到\0 就停 ,值为:前面的随机值-1

发布于: 刚刚阅读数: 3
用户头像

Geek_65222d

关注

还未添加个人签名 2022.09.09 加入

还未添加个人简介

评论

发布
暂无评论
【C语言难点突破】指针的常见易错点_10月月更_Geek_65222d_InfoQ写作社区