• 指针和数组笔试题解析


    目录

    1.一维数组

    2.字符数组

    2.1    char arr[] = {'a','b','c','d','e','f'}

     2.2    char arr[] = "abcdef"

    2.3    char *p = "abcdef"

    3.二维数组


    全面分析指针和数组笔试题,带你加深了解数组和指针,努力学习,加油!

    1.一维数组

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

     

    int a[] = {1,2,3,4};      一维数组四个元素,每个元素是int 类型(四个字节)

    1. int数组sizeof(数组名)计算整个数组的大小,答案为16
    2. int数组sizeof(数组名+其他)此处数组名并未单独放在sizeof内部,为数组首元素地址,答案为4或8
    3. 数组名为数组首元素地址,解引用后指向数组第一个元素  ‘1’  ,答案为4
    4. int型指针+1跳过四个字节,地址(指针)加1或者-1仍然是地址(指针),答案为4或8
    5. 数组第二个元素的大小,答案为4
    6. &a意义是整个数组的地址,但是整个数组的地址仍然是个指针,因此指针大小还是4或8
    7. 此处可以理解为&符号和*符号相互抵消,等价于sizeof(数组名),为整个数组的大小,答案为16
    8. &a+1跳过整个数组,但是仍然是地址,地址取决于编译环境,答案为4或8
    9. 数组首元素的地址,答案为4或8
    10. 数组首元素地址+1,跳过四个字节指向第二个元素,但仍然是地址,答案为4或8

    2.字符数组

    2.1    char arr[] = {'a','b','c','d','e','f'}

    1. char arr[] = {'a','b','c','d','e','f'};
    2. printf("%d\n", sizeof(arr));
    3. printf("%d\n", sizeof(arr+0));
    4. printf("%d\n", sizeof(*arr));
    5. printf("%d\n", sizeof(arr[1]));
    6. printf("%d\n", sizeof(&arr));
    7. printf("%d\n", sizeof(&arr+1));
    8. printf("%d\n", sizeof(&arr[0]+1));
    9. printf("%d\n", strlen(arr));
    10. printf("%d\n", strlen(arr+0));
    11. printf("%d\n", strlen(*arr));
    12. printf("%d\n", strlen(arr[1]));
    13. printf("%d\n", strlen(&arr));
    14. printf("%d\n", strlen(&arr+1));
    15. printf("%d\n", strlen(&arr[0]+1));

    解析如下:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. int main()
    5. {
    6. char arr[] = { 'a','b','c','d','e','f' };
    7. printf("%zd\n", sizeof(arr));//字符数组,数组名为首元素地址,但是单独放在sizeof()内部为整个数组大小,打印6
    8. printf("%zd\n", sizeof(arr + 0));//数组名为首元素地址,并未&并且并未单独放在sizeof内部,地址的大小,4或者8
    9. printf("%zd\n", sizeof(*arr));//数组名为首元素地址 *arr为数组第一个元素'a',打印第一个元素大小,打印1
    10. printf("%zd\n", sizeof(arr[1]));//打印数组第二个元素的大小,为1
    11. printf("%zd\n", sizeof(&arr));//地址的大小,为4或者8
    12. printf("%zd\n", sizeof(&arr + 1));//地址的大小。为4或者8
    13. printf("%zd\n", sizeof(&arr[0] + 1));//地址的大小,为4或者8
    14. printf("%zd\n", strlen(arr));//计算字符串长度,从数组首元素开始计算,但是字符串中并未有结束符“ \0 ”,因此为随机值
    15. printf("%zd\n", strlen(arr + 0));//计算字符串长度,从数组首元素开始计算,但是字符串中并未有结束符“ \0 ”,因此为随机值
    16. printf("%zd\n", strlen(*arr));//站在strlen角度认为 将字符'a'---97当作字符串起始地址,非法地址,访问错误
    17. printf("%zd\n", strlen(arr[1]));//站在strlen角度认为 将字符'b'---98当作字符串起始地址,非法地址,访问错误
    18. printf("%zd\n", strlen(&arr));//&arr类型为 char (*)[6] 传入strlen会进行转化为const char*,因此还是从数组首元素开始计算长度,为随机值
    19. printf("%zd\n", strlen(&arr + 1));//&arr+1跳过一个数组后往后数,仍然为随机值,
    20. printf("%zd\n", strlen(&arr[0] + 1));//&arr[0]+1跳过一个字符后往后数,但仍然为随机值
    21. return 0;
    22. }

     2.2    char arr[] = "abcdef"

    1. printf("%d\n", sizeof(arr));
    2. printf("%d\n", sizeof(arr+0));
    3. printf("%d\n", sizeof(*arr));
    4. printf("%d\n", sizeof(arr[1]));
    5. printf("%d\n", sizeof(&arr));
    6. printf("%d\n", sizeof(&arr+1));
    7. printf("%d\n", sizeof(&arr[0]+1));
    8. printf("%d\n", strlen(arr));
    9. printf("%d\n", strlen(arr+0));
    10. printf("%d\n", strlen(*arr));
    11. printf("%d\n", strlen(arr[1]));
    12. printf("%d\n", strlen(&arr));
    13. printf("%d\n", strlen(&arr+1));
    14. printf("%d\n", strlen(&arr[0]+1));

    解析如下:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. int main()
    5. {
    6. char arr[] = "abcdef";
    7. //arr数组中实际有"abcdef\0"
    8. printf("%d\n", sizeof(arr));//sizeof(数组名)计算整个数组大小,包括了\0,答案为7
    9. printf("%d\n", sizeof(arr + 0));//sizeof(首元素地址+0),计算第一个元素的地址大小,4或者8
    10. printf("%d\n", sizeof(*arr));//第一个元素大小,答案为1
    11. printf("%d\n", sizeof(arr[1]));//第一个元素大小,答案为1
    12. printf("%d\n", sizeof(&arr));//计算指针大小。4或者8
    13. printf("%d\n", sizeof(&arr + 1));///计算指针大小。4或者8
    14. printf("%d\n", sizeof(&arr[0] + 1));///计算指针大小。4或者8
    15. printf("%d\n", strlen(arr));//计算\0之前的字符个数,为6
    16. printf("%d\n", strlen(arr + 0));//答案为6
    17. printf("%d\n", strlen(*arr));//strlen认为字符'a'---97为字符起始地址,非法访问,错误
    18. printf("%d\n", strlen(arr[1]));//strlen认为字符'b'---98为字符起始地址,非法访问,错误
    19. printf("%d\n", strlen(&arr));//&arr类型为--char (*)[6] 传入strlen函数会被转化为const char *,因此从首元素位置开始向后计数。为6
    20. printf("%d\n", strlen(&arr + 1));//&arr类型为---char (*)[6] +1 后跳过一个数组大小,为随机值
    21. printf("%d\n", strlen(&arr[0] + 1));//&arr[0]类型为---char * +1跳过一个字符指针大小,答案为5
    22. return 0;
    23. }

    2.3    char *p = "abcdef"

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

    解析如下:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. int main()
    5. {
    6. char* p = "abcdef";//字符指针,将字符串首位置字符'a'的地址传给 p
    7. printf("%zd\n", sizeof(p));//计算字符指针p的大小,4或者8
    8. printf("%zd\n", sizeof(p + 1));//计算指针的大小,4或者8
    9. printf("%zd\n", sizeof(*p));//计算字符'a'的大小,为1
    10. printf("%zd\n", sizeof(p[0]));//计算字符'a'的大小,为1,可以理解为p[0]--> *(p+0)
    11. printf("%zd\n", sizeof(&p));//计算指针的大小,4或者8
    12. printf("%zd\n", sizeof(&p + 1));//计算指针的大小,4或者8
    13. printf("%zd\n", sizeof(&p[0] + 1));//计算指针的大小,4或者8
    14. printf("%d\n", strlen(p));//计算字符个数,为6
    15. printf("%d\n", strlen(p + 1));//计算字符个数,为5
    16. printf("%d\n", strlen(*p));//*p指向a,将字符'a'---97看作起始地址,非法访问,错误
    17. printf("%d\n", strlen(p[0]));//同样是将字符'a'---97看作起始地址,非法访问,错误
    18. printf("%d\n", strlen(&p));//&p为二级指针,该地址中的字符未知,所以是随机值
    19. printf("%d\n", strlen(&p + 1));//跳过了该数组,后续未知,所以为随机值
    20. printf("%d\n", strlen(&p[0] + 1));//字符串首元素地址+1后指向字符'b',计算长度为5
    21. return 0;
    22. }

    3.二维数组

    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]));

    解析如下:

    我们可以将二维数组存储看作如下图:

    但是二维数组在内存中真实情况是连续存放的

     

     

     二维数组可以理解为一维数组的数组,a[0]相当于第一行数组的数组名

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. int main()
    5. {
    6. int a[3][4] = { 0 };
    7. //
    8. printf("%d\n", sizeof(a));//二维数组 a 也是数组名,数组名单独放在sizeof内部,表示整个数组,计算整个数组的大小,为3*4*4 =48
    9. printf("%d\n", sizeof(a[0][0]));//计算a[0][0]元素大小,为4
    10. printf("%d\n", sizeof(a[0]));//,二维数组可以理解为一维数组的数组,a[0]相当于第一行数组的数组名,单独放在sizeof内部,计算的是整个第一行数组的大小,为4*4 =16
    11. printf("%d\n", sizeof(a[0] + 1));//a[0]并没有单独放在sizeof内部,也没有&,所以代表第一行第一个元素的地址,相当于a[0]-->&a[0][0],计算的是第一行第二个元素的地址的大小为4或者8
    12. printf("%d\n", sizeof(*(a[0] + 1)));//代表计算第一行第二个元素的大小,int类型大小为4
    13. printf("%d\n", sizeof(a + 1));//地址的大小,4或者8,a作为二维数组数组名并没有单独放在siezof内部,也没有&,所以a表示数组首元素地址,也就是第一行的地址,第一行的地址+1为第二行的地址
    14. printf("%d\n", sizeof(*(a + 1)));//解引用第二行数组的地址拿到整个第二行数组,大小为16
    15. printf("%d\n", sizeof(&a[0] + 1));//计算第一行第二个元素的地址,4或者8
    16. printf("%d\n", sizeof(*(&a[0] + 1)));//a[0]是第一行的数组名,&a[0]取出的是第一行的一维数组的地址,+1后为第二行的地址,解引用访问第二行,大小为16
    17. printf("%d\n", sizeof(*a));//a表示数组首元素地址,也就是第一行的地址,*a对第一行解引用,计算第一行数组大小为16
    18. printf("%d\n", sizeof(a[3]));//虽然不存在a[3],但不会越界,因为sizeof运算并不会真的在内存中去访问该数组,所以仍然能计算出大小为16,相当于编译器已经确定了类型a[0]--int [4] a[3]--int [4]
    19. //表达式有两个属性,一个是值属性,一个是类型属性
    20. return 0;
    21. }

    谢谢大家的支持与鼓励!下次再见!

  • 相关阅读:
    微服务设计:Spring Cloud API 网关概述
    (十)死信队列
    基于Spring Boot应用Java的Stream流API
    JavaFx 生成二维码工具类封装
    Spring 微服务:数据压缩技术
    美国RAKsmart:裸机云站群服务器配置详解
    含文档+PPT+源码等]精品微信小程序ssm超市购物系统小程序+后台管理系统|前后分离VUE[包运行成功]微信小程序项目源码Java毕业设计
    MapReduce理论
    MIP精确算法的关键——确定界 篇一
    【C++面向对象】7. 类的静态成员
  • 原文地址:https://blog.csdn.net/AlanTZT/article/details/132916368