4

C语言指针就该这样学!!!

 2 years ago
source link: https://blog.csdn.net/m0_56398287/article/details/120232893
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

 数组名的意义:

  1. 温馨提示,切记这几句话,对下面的题很有帮助,都是面试真题!!!

  2. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。

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

  4. 除此之外所有的数组名都表示首元素的地址。


    //一维数组   

    //int a[] = { 1, 2, 3, 4 };
        //printf("%d\n", sizeof(a));//16    sizeof(数组名)计算的是整个数组的大小
        //printf("%d\n", sizeof(a + 0));//4/8 这里不是单独的数组名,a+0表示首元素地址加0,还是首元素地址,地址占4或8个字节
        //printf("%d\n", sizeof(*a));//4    a是首元素的地址对首元素地址解引用,找到第一个元素,大小是4个字节
        //printf("%d\n", sizeof(a + 1));//4或8  首元素地址加1是第二个元素地址,还是地址就是4或8字节
        //printf("%d\n", sizeof(a[1]));//4   第二个元素的大小
        //printf("%d\n", sizeof(&a));// 4 取地址a 取的是整个数组地址,还是地址呀,所以占4或8字节
        //printf("%d\n", sizeof(*&a));//16   --先取整个数组的地址,再解引用找到这个数组,计算数组的大小
        //printf("%d\n", sizeof(&a + 1));//4或8   &a 是整个数组的地址,再加1跳过整个数组,后下一块空间的地址


        //printf("%d\n", sizeof(&a[0]));//4或8   取得是数组数组首元素的地址
        //printf("%d\n", sizeof(&a[0] + 1));// 4或8  取首元素的地址再加1是第二个元素的地址

    //字符数组
        char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
        printf("%d\n", sizeof(arr)); //6 数组名单独放在sizeof,计算整个素组的大小
        printf("%d\n", sizeof(arr + 0)); // 4或8  数组首地址+0,还是地址
        printf("%d\n", sizeof(*arr)); // 1  对数组的首地址解引用找到‘a’ 计算a的大小
        printf("%d\n", sizeof(arr[1]));//1 计算a的大小
        printf("%d\n", sizeof(&arr));//4或8 取数组名是取得整个数组的地址,也是地址呀
        printf("%d\n", sizeof(&arr + 1));// 4或8   &arr取整个数组的地址再+1 挑个一个数组之后的地址
        printf("%d\n", sizeof(&arr[0] + 1));// 4或8 &arr[0],首元素地址加一,第二个元素的地址

        printf("%d\n", strlen(arr));//随机值    不知道'\0'的位置
        printf("%d\n", strlen(arr + 0));// 随机值  数组首地址+0 还是从指向a,从a开始向后读 还是找不到'\0'
        printf("%d\n", strlen(*arr)); //err arr数组名首元素地址,解引用找到a,a的ASCII是97,在97向后读肯定错了
        printf("%d\n", strlen(arr[1]));//err  strlen(字符b),ASCII是98
        printf("%d\n", strlen(&arr));// 6  取数组名,在strlen看来整个数组的地址,和数组的首地址一样,还是从a向后读
        printf("%d\n", strlen(&arr + 1));// 随机值-6,跳过一个数组,在向后读,还是找不到'\0'
        printf("%d\n", strlen(&arr[0] + 1));//随机值-1  首地址+1 第二个元素地址向后读

    char arr[] = "abcdef";
        printf("%d\n", sizeof(arr)); //7 计算整个数组的大小
        printf("%d\n", sizeof(arr + 0));// 4或8 计算首元素地址的大小
        printf("%d\n", sizeof(*arr));//1 数组名解引用,找到第一个元素,计算第一个元素的大小
        printf("%d\n", sizeof(arr[1]));//1 计算第一个元素的大小
        printf("%d\n", sizeof(&arr)); //4或8  取的整个数组的地址,也是地址呀
        printf("%d\n", sizeof(&arr + 1)); // 4或8  整个数组地址+1,跳过整个数组的后的第一个地址
        printf("%d\n", sizeof(&arr[0] + 1));// 4或8 &a的地址+1 是b的地址

        printf("%d\n", strlen(arr));//6  计算有几个元素
        printf("%d\n", strlen(arr + 0)); //6  和上面一样
        //printf("%d\n", strlen(*arr)); //err 解引用arr找到a a的ASCII是97 向后读不对滴
        //printf("%d\n", strlen(arr[1]));// err 找到a 向后读是不对滴
        printf("%d\n", strlen(&arr)); // 6 取得整个数组的地址,也是首地址呀,往后读


        printf("%d\n", strlen(&arr + 1));// 随机值  跳过这个数组
        printf("%d\n", strlen(&arr[0] + 1));//5 取第一个元素的地址在+1 就第二个元素地址

        char *p = "abcdef";
        //首先要想是吧整个字符赋給指针变量P了吗?
        //当然不是,是吧字符串首元素的地址给了P
        printf("%d\n", sizeof(p));// 4或8  p是指针变量,4或8个字节
        printf("%d\n", sizeof(p + 1));//4或8  p存的是a的地址加一是b的地址,还是地址
        printf("%d\n", sizeof(*p));// 1  p->a 再解引用找到a 大小1个字节
        printf("%d\n", sizeof(p[0]));// 1  找到的a  大小1个字节 ~*(p+0)
        printf("%d\n", sizeof(&p));// 4或8  &p的地址也是地址呀

    printf("%d\n", sizeof(&p + 1)); //4或8  &p的地址再加一跳过p这块空间的下一个地址 ,还是一个地址

    printf("%d\n", sizeof(&p[0] + 1));//4或8  p[0] 是a 再&地址,+1后是b的地址

    printf("%d\n", strlen(p));// 6 p->a  向后读一共6个
        printf("%d\n", strlen(p + 1));//5 p指向a 再加1 指向b
        printf("%d\n", strlen(*p));//err  p是首地址,解引用找到a a的ASCII是97 向后读是错滴
        printf("%d\n", strlen(p[0]));//err  *(p+0) 找到a
        printf("%d\n", strlen(&p)); //随机值  &p 是取得p的地址,往后找谁™知道'\0' 在哪
        printf("%d\n", strlen(&p + 1)); // 随机值  跳过p这块空间 往后读 也不知道'\0' 在哪

        printf("%d\n", strlen(&p[0] + 1));// 5 p[0] 是a  再取a的地址,再+1 是b的地址 再向后读

        //二维数组
        int a[3][4] = { 0 };
        printf("%d\n", sizeof(a));//48  sizeof(数组名)求的整个数组的大小,4*4*3=48
        printf("%d\n", sizeof(a[0][0]));//4  计算第0行 0列的元素大小

         printf("%d\n", sizeof(a[0]));//16  解释:a[0]可以理解为第一行的数组名,
        //此时就是sizeof(a[0])---数组名单独放在了sizeof内部,计算的是第一行的大小

    printf("%d\n", sizeof(a[0] + 1));//4或8   a[0]是第一行的数组名,并没有单独放在sizeof里面,也没有&地址,所以a[0] 表示第一行第一个元素的地址 再加1就是第二个元素的地址

     printf("%d\n", sizeof(*(a[0] + 1)));//4  a[0]是第一行的数组名,没有单独放在sizeof内部,也没取地址,所以表示第一行的第一个元素地址,再加一就是第一行第二个元素的地址,再解引用找到了该元素,计算该元素的大小

     printf("%d\n", sizeof(a + 1));//4或8  a是二维数组的数组名,a表示二维数组首元素的地址,即是二维数组的第一行的地址,二维数组首地址加1跳过这一行,找到了第二行的地址

        printf("%d\n", sizeof(*(a + 1)));//16  *(a+1)~a[1] a是二维数组的名,没有单独放在sizeof内部,也没有&数组名,a表示二维数组首元素的地址,即二维数组第一行的地址,+1就找到了二维数组的第二行,再解引用计算的二维数组第二个元素大小,即第二行的大小

    printf("%d\n", sizeof(&a[0] + 1));//4或8 &a[0],取的是第一行的数组名表示整个数组的地址,加1是第二行的地址,也是地址呀,所以计算的是地址的大小
        printf("%d\n", sizeof(*(&a[0] + 1)));//16   然后再解引用是计算第二行的大小 

         printf("%d\n", sizeof(*a));//16 ~*(a+0)~a[0]  a没有单独的放在sizeof内部,也没有&数组名,a表示二维数组首元素的地址,也就是 一维数组的地址,再解引用找到的是这个一维数组,计算一维数组的大小

    printf("%d\n", sizeof(a[3]));//16  a[3]其实是第4行的数组名(如果有的话,其实不存在)但是可以给通过类型计算大小

    第二部分:笔试题

    #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;
    }
    //程序的结果是什么?

    第二题

     struct Test
    {
        int Num;
        char *pcName;
        short sDate;
        char cha[2];
        short sBa[4];
    }*p;
    //假设p 的值为0x100000。 如下表表达式的值分别为多少?
    int main()
    {
        printf("%p\n", p + 0x1);//p是结构体类型指针,(结构体大小是20字节)+1就是跳过20字节,十六禁止的20是14
               //100014
        printf("%p\n", (unsigned long)p + 0x1);//把P转换成无符号长整形,再+1 就是100001
                      //100001
        printf("%p\n", (unsigned int*)p + 0x1);//把p转换为无符号整形指针,+1就是向后跳4个字节,
                     //100004
        return 0;
    }

    第三题

    int main()
    {
        int a[4] = { 1, 2, 3, 4 };
        int *ptr1 = (int *)(&a + 1);
        int *ptr2 = (int *)((int)a + 1);
        printf("%x,%x", ptr1[-1], *ptr2);
        return 0;
    }


  5. 第4 题

    #include <stdio.h>
    int main()
    {
        int a[3][2] = { (0, 1), (2, 3), (4, 5) };
        int *p;
        p = a[0];//这是把第1行的a[0]的首地址给了p,而不是把二维数组的首元素地址给了p
        printf("%d", p[0]);
        return 0;
    }

    第五题

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

     第6题

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

    第7题

    int main()
    {
        char *a[] = { "work", "at", "alibaba" };
        char**pa = a;
        pa++;
        printf("%s\n", *pa);
        return 0;
    }


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK