关于数组与指针的元素大小得例题

目录

测试题1

测试题2

测试题3

测试题4

测试题5

测试题6

测试题7

测试题8


测试题1

#include <stdio.h>
int main()
{
    int a[5] = {1,2,3,4,5};
    int *ptr = (int *)(&a + 1); //&a代表取得是整个数组的地址,+1后指向跳过整个数组,将他强转为(int *)并赋给ptr
    printf("%d,%d\n",*(a + 1),*(ptr - 1));//输出为 2,5
    //(a + 1)只想第二个元素的地址,解引用得2
    //*(ptr - 1)将指针-1后,变为了a[4],解引用 得出5
    return 0;
}

测试题2

#include <stdio.h>
//测试题2
//假设p 的值为0x100000。如下表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p;
int main()
{
    p = (struct Test*)0x100000;
    printf("%p\n",p + 0x1);//0x1代表十六进制的1 +1,加在了指针上,越过了整个结构体 所以为 0x100014
    printf("%p\n",(unsigned long )p + 0x1);//将p强转为数字1048576,+1加在了数值上得1048577 即0x100001
    printf("%p\n",(unsigned int*)p + 0x1);//将p强转为无符号int*的指针,+1,unsigned int 通常是 4 个字节,0x1代表4个字节
}

测试题3

#include <stdio.h>
//测试题3
int main()
{
    int a[4] = {1,2,3,4};
    int *ptr1 = (int*)(&a + 1);
    //&a代表整个数组的大小,+1后指向数组后边那个地址,(int*)将其装换为数值指针,用ptr1接收
    int *ptr2 = (int*)((int)a + 1);
    //a是指针,(int)a代表转化为int类型数值,+1,即数值加一,
    // 就比如:0x00 00 00 05  +1后转为
    //       0x00 00 00 06
    //以下在内存中(小端存储)表示
    // 01 00 00 00 | 02 00 00 00 | 03 00 00 00 | 04 00 00 00 ...
    //^(开始指向位置)
    //   ^(偏移后)此时指针指向
    //于是4个字节为一个字符
    //00 00 00 02 | 00 00 00 .......
    // 后将其转化为(int*)类型的指针,指针偏移一个字节,赋值给ptr2
    //转为16进制整数 20 00 00 00 的地址
    printf("%x,%x",ptr1[-1],*ptr2);
    //ptr1[-1] == *(ptr1+(-1)) == *(ptr1-1)
    //于是ptr1[-1] == 4
    return 0;
}

测试题4

#include <stdio.h>
//测试题5
int main()
{
    int a[5][5];
    int(*p)[4];//数组指针
    p = a;//这里会报警告 因为p的类型是int(*)[4]  ---  a的类型是 int [5]
    //p[4][2] == *(*(p+4)+2)
    printf("%p,%d\n",&p[4][2] - &a[4][2] , &p[4][2] - &a[4][2]);//输出结果 为FFFFFFFFFFFFFFFC,-4
    //通过图像可知 相差为 4 个元素 ,即如下十六进制的地址计算
        //1000 0000 0000 0000 0000 0000 0000 0100
    //1111 1111 1111 1111 1111 1111 1111 1011
    //1111 1111 1111 1111 1111 1111 1111 1100
    //以%p来打印,编译器就认为我这里放的是地址,输出:
    // F    F     F    F    F   F     F    C
}

测试题5

#include <stdio.h>
//测试题6
int main()
{
    int aa[2][5] = {1,2,3,4,5,6,7,8,9,10};
    //&aa + 1 代表指针 ,跳过了第二行的整个数组
    //将数组指针强转为int*指针 ,赋值给*ptr1
    int *ptr1 = (int*)(&aa + 1);
    //aa + 1  == aa[1]表示第二行数组整个数组,aa[1]找到数组名,解引用找到第二行第一个元素地址
    int *ptr2 = (int*)(*(aa + 1));
    //如下图所示:
    printf("%d,%d",*(ptr1 - 1),*(ptr2 - 1));//输入结果为  10,5
    return 0;
}

测试题6

#include<stdio.h>
//测试题6
int main()
{
    //(0,1),(2,3),(4,5) 逗号表达式,从放了1,2,3
    int a[3][2] = {(0,1),(2,3),(4,5)};
    int *p;
    p = a[0];
    //p[0]  == *(p + 0)
    printf("%d",p[0]);//输出为 1 
    return 0;
}

测试题7

#include <stdio.h>
//测试题7
int main()
{
    char *a[] = {"work","at","alibaba"};
    //这个a指针数组里边存放的 是 w a a 的首地址
    //将a 赋值给 char** 就是将pa指向指针数组a的首地址
    //如下图解释:
    char**pa = a;
    //pa++就是指向指针数组的第二个元素的地址
    pa++;
    //解引用操作,找到指针数组的第二个元素的内容,打印字符串
    printf("%s\n",*pa);//输出 at
    return 0;
}   

测试题8

#include <stdio.h>
//测试题8
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);//* *(cpp + (-2)) + 3  其中cpp的指向位置是不变的
    printf("%s\n",cpp[-1][-1] + 1);//*( *(cpp - 1) -1 ) + 1 这里的指针指向改变( *(cpp - 1) -1 )
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值