C语言-a+1/&a+1

a与&a
    int a[5]={1,2,3,4,5};
    printf("%p,%p,%p\n", a,&a[0],&a);//0x7fff5f989670,0x7fff5f989670,0x7fff5f989670;64位系统

    int *p=(int *)a+1;
    int *k=(int *)&a[0]+1;
    int *q=(int *)(&a+1);
    printf("%d,%d,%d\n", *p, *k, *(q-1));//2,2,5

    a则是数组首元素的地址
    &a[0]是数组第一个元素的地址
    &a是整个数组的首地址

    a+i = a + i*sizeof(a[0]); 偏移的是一个数组元素。
    &a[k]+i = a + (k+i)*sizeof(a[0]); 偏移的是k+i个数组元素。
    &a+i = a + i*sizeof(a);偏移的是一个数组长度。

其他
    int *n=(int *)((int)a+1);
    printf("%p\n", n);//0xfffffffff5b2b791;偏移一个字节
    printf("%#x\n", *n);//测试时打印出:Segmentation fault,可能与编译器和Linux系统有关;
    如果不报错的话,那么数据元素在小端情况下排列:
    0x7fff5f989670:01 00 00 00 02 00 00 00 
    0x7fff5f989678:03 00 00 00 04 00 00 00
    0x7fff5f989680:05 00 00 00
    n指针是int类型,对*n取值就取4个字节数据:00 00 00 02,打印出应该是:0x02000000

    在大端情况下排列:00 00 00 01 00 00 00 02,那么应该打印出:0x100

扩展

void FunPointArray()
{
	char a[5]={'A','B','C','D','\0'};
	char (*p1)[5]=&a;//没有问题,p1是指向5个元素的数组指针,而&a代表5个元素数组的地址
	char (*p2)[5]=a;//报类型不匹配警告,a代表数组的首地址
	printf("p1=%s\n", p1);//p1=ABCD
	printf("p2=%s\n", p2);//p2=ABCD

	char (*p3)[2]=&a;
	char (*p4)[2]=a;
	printf("p3=%s\n", *(p3+1));//p3=CD
	printf("p4=%s\n", *(p4+1));//p4=CD

	char (*p5)[10]=&a;
	char (*p6)[10]=a;
	printf("p5=%s\n", *(p5+1));//p5=乱码说明已经越界
	printf("p6=%s\n", *(p6+1));//p6=乱码说明已经越界

	char (*p7)[]=&a;
	char (*p8)[]=a;
	printf("p7=%s\n", p7);///p7=ABCD,不能用p7+1,报数组边界无固定错误
	printf("p8=%s\n", p8);///p8=ABCD,不能用p8+1,报数组边界无固定错误
}

    得出:指向数组的指针+1,加的长度为指向的数组长度。

    总结:指针变量与一个整数相加减并不是用指针变量里的地址直接加减这个整数,这个整数的单位不是字节而是元素的个数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值