关于&a和a (a为数组名)

1. a和&a的区别:
&a是整个数组的首地址,a是数组首元素的首地址,其值相同,但是意义不同。

eg:

char a[5] = {'A','B','C','D'};
char (*p1)[5] = &a; //没有问题,char (*p1)[5]是数组指针,指向数组a[5]的首地址。
char (*p2)[5] = a; //编译出错,提示类型无法从“char [5]”转换为“char (*)[5]。
需要把a进行强制转化:(char (*)[5])a;
其中:
char (*p1)[5] = &a; //p1指向地址为0x0012ff58;
p1++; //p1此时指向地址为0x0012ff5D;
备注:p1 + 5*sizeof(数组元素类型)
p1++操作越过了这个char a[5]数组的地址范围。


2. 强制转化
eg:
struct Test
{
   int Num;
   char *pcName;
   short sDate;
   char ch[2];
   short sBa[4];
}*p;
假设p的值为0x100000,那么如下表达式的值分别为多少?
a. p + 0x1 = 0x????
b. (unsigned long)p + 0x1 = 0x????
c. (unsigned int*)p + 0x1 = 0x????
a: 我们会遇到一个误区,那就是指针变量与一个整数相加减的问题,并不是我们想象
的那样用指针变量里的地址直接加减这个整数,这个整数的单位不是byte而是元素的个数。
从而p + 0x1的值为:0x100000 + sizeof(Test)*0x1,而sizeof(Test)大小为20byte,
所以p + 0x1的值为:0x100014
b: 这里涉及强制转换,将指针变量p保存的值强制转换成无符号的长整型数,任何数值一旦被
强制转换,其类型就改变了,从而这个表达式其实就是一个无符号的长整型数加上另外一个整数,
所以其值为:0x100001
c: 这里p被强制转化成一个指向无符号整型的指针,所以其值为:0x100000 + sizeof(unsigned int*) * 0x1 = 0x100004

我们再来看一个具体例子:

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


对于ptr1: 将&a + 1的值强制转换成int *类型,赋值给int *类型的变量ptr1,那么ptr1的指向如下图所示:
ptr1[-1]被解析成*(ptr1 - 1),即ptr1往后退4个byte,从而其值为4.
对于ptr2: 按照上述b中的解释,(int)a是强制转化,就是把一个地址强制转化为了一个int类型的整数,(int)a + 1
就是从a或者a[0]开始往后加1个字节,也就是(int)a + 1的值为元素a[0]的第二个字节的地址(注意:a[0]占4个字节),然后把
这个地址强制转化成int *类型的值赋值给ptr2,也就是说*ptr2的值应该为元素a[0]的第二个字节开始连续4个byte的内容,内存布局如下图所示:


i.按照大端模式存放:
a[0]                                                                      a[1]
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000010
提取后为:
高                                低
00000000 00000000 00000001 00000000
值为0x100


ii.按照小端模式存放:
a[0]                                                                      a[1]
00000001 00000000 00000000 00000000 00000010 00000000 00000000 00000000
提取后为:
低                                高
00000000 00000000 00000000 00000010
值为0x2000000
这里一定注意大小端模式在计算机内的存储数据的顺序和模式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值