前天看到一同事在研究指针,当下好奇,就过去看了一眼,用来测试的代码是这样子的
例子1
int TestDatas[5] = { 0, 1, 2, 3, 4 };
printf("%8p\r\n", &TestDatas);
printf("%8p\r\n", &TestDatas + 1);
printf("%8p\r\n", *(&TestDatas + 1));
printf("%8p\r\n", *(&TestDatas + 1) - 1);
printf("%d\r\n", *(*(&TestDatas + 1) - 1));
然后他问我,你知道每句输出是什么吗?我心中鄙视,当然知道了,其结果不言而喻,我错的很离谱,因当时在忙,只能暂记心中,直到现在才有功夫来搭理它。
这小段代码,其实是有问题的,先不管他是对是错,我们一行一行的来分析它。
printf("%8p\r\n", &TestDatas);
&TestDatas 这个表明是取TestDatas这个数组的地址的,没什么疑问,主要是看下面这两句
printf("%8p\r\n", &TestDatas + 1);
printf("%8p\r\n", *(&TestDatas + 1));
而我们出错就容易错在这两句话上,如果有些同学不小心,肯定以为这两句打印出来就是首地址+1sizeof(int),那这样就错了,请看下图
为什么呢?为什么两个都是地址,并且地址都一样呢?打印出的第二行,我们的预期是首地址+1sizeof(int),但是为什么不是呢?我们拆开来分析一下,TestDatas是地址吧,这个没有什么疑问吧,那&TestDatas就是数组地址的地址,也没有问题吧,而数组占用的存储空间是20个BYTE也没有问题吧,那么+1,就是加一个数组的大小的空间,这样就明白了,为什么首地址是0x0043FDB4 +1 后就是0x0043FDC8了。
printf("%8p\r\n", *(&TestDatas + 1));
就更有迷惑性了,有些同学可能张口就说,这个打印出来的是1,那就大错特错了,这个地方需要重点注意,仔细点,再仔细点,不要轻敌,同样的,TestDatas 是地址,&TestDatas 是地址的地址,那数组地址+1,就是加整个数组,然后再取地址的地址,结果当然还是地址了。若是这样写
printf("%8p\r\n", *(TestDatas + 1));
那结果铁定是1了。就是大部分人第一眼看到后心里想的结果了。
printf("%8p\r\n", *(&TestDatas + 1) - 1);
printf("%d\r\n", *(*(&TestDatas + 1) - 1));
这两个就是中规中矩的了,没什么好说的取到下一个数据空间的首地址,然后再减去一个1*sizeof(int) 另外一个就是对这个地址取值了。
网友评论