• 指针笔试题讲解(让指针变得简单易懂)


    数组名的理解 :   数组名就是首元素地址 

     但是有两个例外:

      1. sizeof(数组名)这里的数组名表示整个数组的大小,sizeof(数组名)计算的是整个数组的大小,单位是字节 

     2. &数组名   这里的数组名表示整个数组 ,&数组名取出的是数组的地址

    目录

    一.笔试题 ( 1 )

    sizeof的解释

    二.笔试题 ( 2 )

    strlen函数的解释 

    三 .笔试题 ( 3 )

    四. 笔试题 ( 4 )

    五.笔试题 ( 5 ) 

    一.笔试题 ( 1 )

    博主个人建议 : 自己先做一遍,看看哪个做错了,然后再看博主的解释

                              做对的题,自己想想因为什么得这个数,看看与博主的解释一样不

    sizeof的解释

    sizeof ()是C语言中常用的运算符,可以计算操作数的大小。. sizeof的结果是无符号整数类型,通常用size_t表示。. sizeof可以应用于各种数据类型,包括基本的数据类型,例如整数和浮点类型,指针类型和符合数据类型,结构体等等。

    1. int main()
    2. {
    3. //一维数组
    4. int a[] = { 1,2,3,4 };
    5. printf("%d\n", sizeof(a));
    6. printf("%d\n", sizeof(a + 0));
    7. printf("%d\n", sizeof(*a));
    8. printf("%d\n", sizeof(a + 1));
    9. printf("%d\n", sizeof(a[1]));
    10. printf("%d\n", sizeof(&a));
    11. printf("%d\n", sizeof(*&a));
    12. printf("%d\n", sizeof(&a + 1));
    13. printf("%d\n", sizeof(&a[0]));
    14. printf("%d\n", sizeof(&a[0] + 1));
    15. return 0;
    16. }

    博主自己做了一遍    printf("%d\n", sizeof(&a));   我认为这个打印的是16                                        因为 ,&数组名  ,这里的数组名表示整个数组 ,但是事实上我只想对了一半 

    &a - 是取出数组的地址,但是数组的地址也是地址,是地址就是4/8个Byte (在32位下是4个字节,64位下是8个字节)  数组的地址 和 数组首元素的地址 的本质区别是类型的区别,并非大小的区别

    上面的代码解释如下:

    1. int main()
    2. {
    3. //一维数组
    4. int a[] = { 1,2,3,4 };//4个元素,每个元素使int类型(4个字节)
    5. printf("%d\n", sizeof(a));
    6. //数组名a单独放在sizeof内部,数组名表示整个数组,计算的是整个数组的大小单位是字节,是16字节
    7. printf("%d\n", sizeof(a + 0));
    8. //a并非单独放在sizeof内部,也没有&,所以数组名a是数组首元素的地址,a+0还是首元素的地址
    9. //是地址大小就是4/8 Byte
    10. printf("%d\n", sizeof(&a));
    11. // &a - 是取出数组的地址,但是数组的地址也是地址,是地址就是4/8个Byte
    12. //数组的地址 和 数组首元素的地址 的本质区别是类型的区别,并非大小的区别
    13. printf("%d\n", sizeof(*&a));
    14. //对数组指针解引用访问一个数组的大小,单位是字节
    15. //sizeof(*&a) --- sizeof(a)
    16. printf("%d\n", sizeof(&a + 1));
    17. //&a数组的地址,&a+1还是地址,是地址就是4/8个字节
    18. printf("%d\n", sizeof(&a[0]));
    19. //&a[0]是首元素的地址, 计算的是地址的大小 4/8 个字节
    20. printf("%d\n", sizeof(&a[0] + 1));
    21. //&a[0]是首元素的地址,&a[0]+1就是第二个元素的地址,大小4/8个字节
    22. return 0;
    23. }

    拓展:&a[0] + 1是第二个元素的地址,大小 4/8 个字节

    同样表示第二个元素地址的写法还有 &a[1]   &a[0]+1   a+1


    二.笔试题 ( 2 )

    指针变量的大小和类型无关,不管什么类型的指针变量,大小都是4/8个字节
    指针变量是用来存放地址的,地址存放需要多大空间,指针变量的大小就是几个字节
    32位环境下,地址是32个二进制位,需要4个字节,所以指针变量的大小就是4个字节
    64位环境下,地址是64个二进制位,需要8个字节,所以指针变量的大小就是8个字节 

    strlen函数的解释 

    strlen函数,只有遇到 ' \0 ' 时才停止  

    1. #include
    2. int main()
    3. {
    4. //字符数组
    5. char arr[] = { 'a','b','c','d','e','f' };
    6. printf("%d\n", strlen(arr));
    7. printf("%d\n", strlen(arr + 0));
    8. printf("%d\n", strlen(*arr));
    9. printf("%d\n", strlen(arr[1]));
    10. printf("%d\n", strlen(&arr));
    11. printf("%d\n", strlen(&arr + 1));
    12. printf("%d\n", strlen(&arr[0] + 1));
    13. printf("%d\n", sizeof(arr));
    14. printf("%d\n", sizeof(arr + 0));
    15. printf("%d\n", sizeof(*arr));
    16. printf("%d\n", sizeof(arr[1]));
    17. printf("%d\n", sizeof(&arr));
    18. printf("%d\n", sizeof(&arr + 1));
    19. printf("%d\n", sizeof(&arr[0] + 1));
    20. return 0;
    21. }

    自己要先做一遍!!!!!!!!!!!!!!!!再看解释

    博主,自己做的时候,printf("%d\n", sizeof(*arr)); 

    我认为它应该是4个字节,又是想对了一半

    arr是首元素的地址,正常来说地址是4/8个字节,但是它是*arr

    *arr就是第一个元素所以它是 1 个字节
        

    1. int main()
    2. {
    3. //字符数组
    4. char arr[] = { 'a','b','c','d','e','f' };//6
    5. printf("%d\n", strlen(arr));//随机值,arr是首元素的地址
    6. printf("%d\n", strlen(arr + 0));//随机值,arr是首元素的地址, arr+0还是首元素的地址
    7. printf("%d\n", strlen(*arr));//err,arr是首元素的地址, *arr就是首元素 - 'a' - 97
    8. //站在strlen的角度,认为传参进去的'a'-97就是地址,97作为地址,直接进行访问,就是非法访问
    9. printf("%d\n", strlen(arr[1]));//err, 'b' - 98
    10. printf("%d\n", strlen(&arr));//随机值
    11. //&arr -- char (*)[6]
    12. //const char*
    13. printf("%d\n", strlen(&arr + 1));//随机值
    14. printf("%d\n", strlen(&arr[0] + 1));//随机值
    15. printf("%d\n", sizeof(arr));//6 数组名arr单独放在sizeof内部,计算的是整个数组的大小,单位是字节
    16. printf("%d\n", sizeof(arr + 0));//arr是首元素的地址==&arr[0],是地址就是4/8个字节
    17. printf("%d\n", sizeof(*arr));//arr是首元素的地址,*arr就是首元素,大小就是1Byte
    18. printf("%d\n", sizeof(arr[1]));//1
    19. printf("%d\n", sizeof(&arr));//&arr是数组的地址,sizeof(&arr)就是4/8个字节
    20. printf("%d\n", sizeof(&arr + 1));//&arr+1 是跳过数组后的地址,是地址就是4/8个字节
    21. printf("%d\n", sizeof(&arr[0] + 1));//第二个元素的地址,是地址就是4/8Byte
    22. return 0;
    23. }

        


    三 .笔试题 ( 3 )

    1. int main()
    2. {
    3. char arr[] = "abcdef";
    4. printf("%d\n", strlen(arr));
    5. printf("%d\n", strlen(arr + 0));
    6. printf("%d\n", strlen(*arr));
    7. printf("%d\n", strlen(arr[1]));
    8. printf("%d\n", strlen(&arr));
    9. printf("%d\n", strlen(&arr + 1));
    10. printf("%d\n", strlen(&arr[0] + 1));*/
    11. printf("%d\n", sizeof(arr));
    12. printf("%d\n", sizeof(arr + 0));
    13. printf("%d\n", sizeof(*arr));
    14. printf("%d\n", sizeof(arr[1]));
    15. printf("%d\n", sizeof(&arr));
    16. printf("%d\n", sizeof(&arr + 1));
    17. printf("%d\n", sizeof(&arr[0] + 1));
    18. return 0;
    19. }

     自己要先做一遍!!!!!!!!!!!!!!!!再看解释 ( 重要的事情说三遍)

     printf("%d\n", sizeof(arr));我认为这个是 6 但是结果是7,因为我少算了一个 ' \0 '

    a b c d e f \0   共7个

    (每个笔试题必须要错一个,脑袋疼)
     

    1. int main()
    2. {
    3. char arr[] = "abcdef";
    4. printf("%d\n", strlen(arr));//字符串长度,遇到'\0'停止所以是6
    5. printf("%d\n", strlen(arr + 0));//字符串长度,遇到'\0'停止,6
    6. printf("%d\n", strlen(*arr));//err 传参错误,应该传的是字符串的地址
    7. printf("%d\n", strlen(arr[1]));//传参错误,道理同上
    8. printf("%d\n", strlen(&arr));//数组首元素地址,6
    9. printf("%d\n", strlen(&arr + 1));//随机值
    10. printf("%d\n", strlen(&arr[0] + 1));//从b开始往后所以答案是5
    11. printf("%d\n", sizeof(arr));//整个数组包括'\0'所以是7
    12. printf("%d\n", sizeof(arr + 0));//第一个元素地址
    13. printf("%d\n", sizeof(*arr));//第一个元素地址
    14. printf("%d\n", sizeof(arr[1]));//第二个元素地址
    15. printf("%d\n", sizeof(&arr));//整个数组地址
    16. printf("%d\n", sizeof(&arr + 1));//跳过整个数组后的地址
    17. printf("%d\n", sizeof(&arr[0] + 1));//第二个元素地址
    18. return 0;
    19. }

    四. 笔试题 ( 4 )

    1. int main()
    2. {
    3. char* p = "abcdef";
    4. printf("%d\n", strlen(p));
    5. printf("%d\n", strlen(p + 1));
    6. printf("%d\n", strlen(*p));
    7. printf("%d\n", strlen(p[0]));
    8. printf("%d\n", strlen(&p));
    9. printf("%d\n", strlen(&p + 1));
    10. printf("%d\n", strlen(&p[0] + 1));
    11. printf("%d\n", sizeof(p));
    12. printf("%d\n", sizeof(p + 1));
    13. printf("%d\n", sizeof(*p));
    14. printf("%d\n", sizeof(p[0]));
    15. printf("%d\n", sizeof(&p));
    16. printf("%d\n", sizeof(&p + 1));
    17. printf("%d\n", sizeof(&p[0] + 1));
    18. return 0;
    19. }

    我这次错了很多 (可能是眼睛太大了,没看见是 char* p )

     大家在看东西的时候一定要观察仔细!!!!

           printf("%d\n", strlen(p + 1));首元素地址+1,从b开始所以应该是5

           printf("%d\n", strlen(&p)    随机值,

           printf("%d\n", strlen(&p + 1));随机值
    大家有什么不懂的可以去看笔试题 ( 3 )的解释

    1. printf("%d\n", strlen(p)); //6
    2. printf("%d\n", strlen(p + 1)); //5
    3. printf("%d\n", strlen(*p)); //err
    4. printf("%d\n", strlen(p[0])); //err
    5. printf("%d\n", strlen(&p)); //随机值
    6. printf("%d\n", strlen(&p + 1));//随机值
    7. printf("%d\n", strlen(&p[0] + 1)); //5
    8. printf("%d\n", sizeof(p));//4/8 计算的是指针变量的大小
    9. printf("%d\n", sizeof(p + 1));//p+1还是地址,大小是4/8个字节
    10. printf("%d\n", sizeof(*p));//1个字节, *p == 'a'
    11. printf("%d\n", sizeof(p[0]));//1个字节, p[0]--> *(p+0) --> *p == 'a';
    12. printf("%d\n", sizeof(&p));//4/8个字节,&p 是地址
    13. printf("%d\n", sizeof(&p + 1));//&p是地址,&p+1还是地址,是地址就是4/8个字节
    14. printf("%d\n", sizeof(&p[0] + 1));

    五.笔试题 ( 5 )

    1. int a[3][4] = { 0 };
    2. printf("%d\n", sizeof(a));
    3. printf("%d\n", sizeof(a[0][0]));
    4. printf("%d\n", sizeof(a[0]));
    5. printf("%d\n", sizeof(a[0] + 1));
    6. printf("%d\n", sizeof(*(a[0] + 1)));
    7. printf("%d\n", sizeof(a + 1));
    8. printf("%d\n", sizeof(*(a + 1)));
    9. printf("%d\n", sizeof(&a[0] + 1));
    10. printf("%d\n", sizeof(*(&a[0] + 1)));
    11. printf("%d\n", sizeof(*a));
    12. printf("%d\n", sizeof(a[3]));

    1. int main()
    2. {
    3. int a[3][4] = { 0 };
    4. printf("%zd\n", sizeof(a));//48-数组名a单独放在了sizeof内存,表示整个数组,sizeof(a)计算的是数组的大小,单位是字节
    5. printf("%zd\n", sizeof(a[0][0]));//4-a[0][0]是数组的第一行第一个元素,这里计算的就是一个元素的大小,单位是字节
    6. printf("%zd\n", sizeof(a[0]));//16 - a[0]是第一行这个一维数组的数组名,数组名单独放在了sizeof内部
    7. //a[0]就表示整个第一行这个一维数组,sizeof(a[0])计算的整个第一行这个一维数组的大小
    8. printf("%zd\n", sizeof(a[0] + 1));//4/8 - a[0]并非单独放在sizeof内部,也没有&,所以a[0]表示第一行这个一维数组首元素的地址
    9. //也就是第一行第一个元素的地址
    10. //a[0] <---> &a[0][0]
    11. //a[0]+1 ---> &a[0][1]
    12. printf("%zd\n", sizeof(*(a[0] + 1)));//4 - a[0] + 1是第一行第二个元素的地址,*(a[0] + 1))就是第一行第二个元素
    13. //
    14. printf("%zd\n", sizeof(a + 1));//4/8
    15. //a 作为二维数组的数组名,并没有单独放在sizeof内部,也没有&,a就是数组首元素的地址,也就是第一行的地址, a 的类型是 int(*)[4]
    16. //a+1 就是第二行的地址,类型是:int(*)[4]
    17. //
    18. printf("%zd\n", sizeof(*(a + 1)));//16 a+1是第二行的地址,*(a+1)就是第二行,计算的就是第二行的大小
    19. //另外一个角度理解:*(a+1) -- a[1]
    20. //sizeof(a[1]) - a[1]这个第二行的数组名,单独放在了sizeof内部,计算的是第二行的大小
    21. printf("%zd\n", sizeof(&a[0] + 1));//4/8
    22. //a[0]是第一行的数组名,&a[0]取出的是数组的地址,取出的是第一行这个一维数组的地址,类型就是int(*)[4]
    23. //&a[0]+1 就是第二行的地址,类型就是int(*)[4]
    24. printf("%zd\n", sizeof(*(&a[0] + 1)));//*(&a[0] + 1)得到的就是第二行,计算的就是第二行的大小
    25. printf("%zd\n", sizeof(*a));//16
    26. //a表示数组首元素的地址,也就是第一行的地址
    27. //*a 就是第一行,也就相当于是第一行的数组名
    28. //*a--> *(a+0) -- a[0]
    29. //
    30. printf("%zd\n", sizeof(a[3]));//16-不会越界,
    31. //a[3] -- arr[0]
    32. //int [4] int [4]
    33. //int a = 10;
    34. //sizeof(a);//sizeof(int)
    35. //表达式 有2个属性:值属性,类型属性
    36. //2+3 = 5
    37. // = int
    38. return 0;
    39. }

    新人博主,如果有地方解释的不对或者不清晰,麻烦大佬们海涵,如果可以麻烦从评论区指出,我一定会加以修改,万分感谢

    最后麻烦大佬们动一下发财的小手一键三连,千万分感谢

  • 相关阅读:
    HEC-RAS水动力模型的一维二维及耦合建模
    网络丢包问题,敢不敢这样定位?
    神经网络的优势及特点,神经网络方法特点
    安装这个IIS-Applicationlnit
    python模块(二)
    MySQL注入绕安全狗脚本 -- MySQLByPassForSafeDog,以及端口爆破工具 -- PortBrute配置使用
    如何把图片转化成excel表格?
    [附源码]计算机毕业设计万佳商城管理系统Springboot程序
    FlinkSql中的聚合查询
    车牌识别C#项目源代码
  • 原文地址:https://blog.csdn.net/2201_75886757/article/details/132942375