指针强化练习(详解)

文章详细比较了C语言中的sizeof和strlen在处理不同类型数据时的行为,以及对一维数组、字符指针、二维数组和指针运算的示例,展示了内存对齐的概念,并提供了函数指针的实例。内容涵盖了结构体内存布局和面试中常见的指针问题剖析。
摘要由CSDN通过智能技术生成
更多学习内容
结构体内存对齐 和 位段-CSDN博客
指针初级(基础知识)-CSDN博客
指针进阶(深入理解)-CSDN博客

目录

1.sizeof与strlen的区别

2.一维数组

3.字符指针

4.二维数组

5.指针运算(笔试题)

6.函数指针


1.sizeof与strlen的区别

请思考以下运行结果

        #include <stdio.h>
        int main()
        {
                char arr1[3] = {'a', 'b', 'c'};
                char arr2[] = "abc";
                printf("%d\n", strlen(arr1));
                printf("%d\n", strlen(arr2));
                printf("%d\n", sizeof(arr1));
                printf("%d\n", sizeof(arr1));
                return 0;
        }

结果为: 随机值,3,3,4
 

2.一维数组

请思考以下运行结果

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

结果为164或844或844或8164或84或84或8

3.字符指针

请思考以下运行结果

代码1

        char arr[] = {'a','b','c','d','e','f'};
        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));

结果为6,1,1,4/8,4/8,4/8

代码2

        char arr[] = {'a','b','c','d','e','f'};
        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));

结果为随机值n,随机值n,?,?,随机值n,随机值n-6,随机值n-1

代码3

        char arr[] = "abcdef";
        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));

结果为7,4/8,1,1,4/8,4/8,4/8

代码4

        char arr[] = "abcdef";
        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,6,?,?,6,随机值,5

代码5

        char *p = "abcdef";
        printf("%d\n", sizeof(p));
        printf("%d\n", sizeof(p+1));
        printf("%d\n", sizeof(*p));
        printf("%d\n", sizeof(p[0]));
        printf("%d\n", sizeof(&p));
        printf("%d\n", sizeof(&p+1));
        printf("%d\n", sizeof(&p[0]+1));

结果为4/8,4/8,1,1,4/8,4/8,4/8

代码6

        char *p = "abcdef";
        printf("%d\n", strlen(p));
        printf("%d\n", strlen(p+1));
        printf("%d\n", strlen(*p));
        printf("%d\n", strlen(p[0]));
        printf("%d\n", strlen(&p));
        printf("%d\n", strlen(&p+1));
        printf("%d\n", strlen(&p[0]+1));

结果为6,5,?,?,6?,随机值,5

4.二维数组

请思考以下运行结果

        int a[3][4] = {0};
        printf("%d\n",sizeof(a));
        printf("%d\n",sizeof(a[0][0]));
        printf("%d\n",sizeof(a[0]));
        printf("%d\n",sizeof(a[0]+1));
        printf("%d\n",sizeof(*(a[0]+1)));
        printf("%d\n",sizeof(a+1));
        printf("%d\n",sizeof(*(a+1)));
        printf("%d\n",sizeof(&a[0]+1));
        printf("%d\n",sizeof(*(&a[0]+1)));
        printf("%d\n",sizeof(*a));
        printf("%d\n",sizeof(a[3]));

结果为48,4,16,4/8,4,4/8,16,4/8,16,16,16

5.指针运算(笔试题)

请思考以下运行结果

试题1

        #include <stdio.h>
        int main()
        {
                int a[5] = { 1, 2, 3, 4, 5 };
                int *ptr = (int *)(&a + 1);
                printf( "%d,%d", *(a + 1), *(ptr - 1));
                return 0;
        }

结果为2,5

试题2

        struct Test
        {
                int Num;
                char *pcName;
                short sDate;
                char cha[2];
                short sBa[4];
        }*p = (struct Test*)0x100000;
        int main()
        {
                printf("%p\n", p + 0x1);
                printf("%p\n", (unsigned long)p + 0x1);
                printf("%p\n", (unsigned int*)p + 0x1);
                return 0;
         }

结果为00100020,00100001,00100004(32位机器)

以上结构体内存布局如下:

这里涉及到结构体内存对齐的知识,不理解可以点击链接学习

试题3
        #include <stdio.h>
        int main()
        {
                int a[3][2] = { (0, 1), (2, 3), (4, 5) };
                int *p;
                p = a[0];
                printf( "%d", p[0]);
                return 0;
         }

结果为1

试题4

        #include <stdio.h>
        int main()
        {
                int a[5][5];
                int(*p)[4];
                p = a;
                printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
                return 0;
        }

结果为FFFFFFFC ,4

注意:二维数组在物理内存上储存其实是连续的

内存布局为:

注意:指针减指针得到的是指针之间的元素个数,而不是地址的差值

试题5

        #include <stdio.h>
        int main()
        {
                int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
                int *ptr1 = (int *)(&aa + 1);
                int *ptr2 = (int *)(*(aa + 1));
                printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
                return 0;
        }

结果为10,5

试题6

        #include <stdio.h>
        int main()
        {
                char *a[] = {"work","at","alibaba"};
                char**pa = a;
                pa++;
                printf("%s\n", *pa);
                return 0;
        }

结果为at

试题7

        #include <stdio.h>
        int main()
        {
                char *c[] = {"ENTER","NEW","POINT","FIRST"};
                char**cp[] = {c+3,c+2,c+1,c};
                char***cpp = cp;
                printf("%s\n", **++cpp);
                printf("%s\n", *--*++cpp+3);
                printf("%s\n", *cpp[-2]+3);
                printf("%s\n", cpp[-1][-1]+1);
                return 0;
        }

结果为POINT ER ST  EW

做这样的题一定要学会画图,画出图结果就一幕了然了,如下:

:看题解的时候要看图理解

6.函数指针

请解释以下代码:

这段代码表示把0强制类型转化为void(*)()这样的函数再进行解引用进行调用

这段代码出⾃:《C陷阱和缺陷》这本书以下图片为书中所取

请解释以下代码:

这是表示一个函数名signal参数类型int和void()(int)返回类型void(*)(int)的函数指针。

指针练习就到此结束,感谢阅读

  • 28
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值