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

 数组名的意义:

  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跳过整个数组,后下一块空间的地址

    C语言指针就该这样学!!!_第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 计算b的大小
        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 取得整个数组的地址,也是首地址呀,往后读

    C语言指针就该这样学!!!_第2张图片
        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这块空间的下一个地址 ,还是一个地址

    C语言指针就该这样学!!!_第3张图片

     

    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' 在哪

    C语言指针就该这样学!!!_第4张图片
        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列的元素大小

    C语言指针就该这样学!!!_第5张图片

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

    C语言指针就该这样学!!!_第6张图片

    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内部,也没取地址,所以表示第一行的第一个元素地址,再加一就是第一行第二个元素的地址,再解引用找到了该元素,计算该元素的大小

    C语言指针就该这样学!!!_第7张图片

     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就找到了二维数组的第二行,再解引用计算的二维数组第二个元素大小,即第二行的大小

    C语言指针就该这样学!!!_第8张图片

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

    C语言指针就该这样学!!!_第9张图片

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

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

    C语言指针就该这样学!!!_第10张图片

    第二部分:笔试题

    第一题

    #include
    int main()
    {
        int a[5] = { 1, 2, 3, 4, 5 };
        int *ptr = (int *)(&a + 1);
        printf("%d,%d", *(a + 1), *(ptr - 1)); return 0;
    }
    //程序的结果是什么?

    C语言指针就该这样学!!!_第11张图片

    第二题

     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;
    }C语言指针就该这样学!!!_第12张图片

  5. 第4 题

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

    C语言指针就该这样学!!!_第13张图片

    C语言指针就该这样学!!!_第14张图片

    第五题

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

    C语言指针就该这样学!!!_第15张图片

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

    C语言指针就该这样学!!!_第16张图片

    第7题

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

    C语言指针就该这样学!!!_第17张图片

你可能感兴趣的:(C语言,c语言)