先看下面的例子:(环境gnu linux)
#include <>
int main(void)
int a[5] =
int *p1 = int *)a + 1);
printf("%x ", p1[-1]);
return 0;
请问,打印结果是什么?为什么?
这里考大家的c语言功底了,呵呵。ok,不卖关子了,看结果:
对,你没有看错,结果就是这样,高手已经明白这是为什么,可是毕竟还有很多初学者,所以斗胆在此说一下为什么是这样的结果(个人理解,不一定对,如果您有更好的理解可以告诉我)。下面分解来看:
1、 先来看p1的结果:
int *p1 = int *)a + 1);
printf("%x", p1[-1]);
首先在前面定义了一个有5个元素的int型数组,然后定义一个整型指针p1,赋值的时候先取a的地址&a,再加 1, 然后将(&a + 1)强制类型转换为int *。重点来了,此时p1指向**?只有解答了这个问题,我们才能解答为什么p1[-1] =5。
这里就涉及到一些概念了,首先&a 是取a的地址,而且是首地址,这个没有什么问题了,紧接着 &a + 1。其实这才是整个表达式的关键(个人认为)。我们知道,&a是取数组a的首地址,&a + 1这个表达式它操作的对象是基于数组a的,因此&a + 1就等于在a数组的结尾再加1,偏移对象是整个数组。
怎么印证呢?很简单,把&a、 &a+1、 &a+2 …(打2个够了) 的地址打印出来就知道了:
printf("addr a: %p", a);
printf("addr a+1 : p", a + 1);
printf("addr a+2: %p", a + 2);
addr a: 0xbff14a44
addr a+1 : 0xbff14a58
addr a+2: 0xbff14a6c
从打印结果很容易看出刚才说的结论,&a+1的地址和&a的地址相差20(0x14),正好是数组a的长度,所以&a + n 是基于a 这个数组做的偏移。
因此后面的就不难理解了,int *p1 = int *)a + 1); 就是将以a数组为基准做+1偏移后的地址赋值给p1,printf("%x", p1[-1]);中的p1[-1],自然就减去4个字节指向数组a的最后一个元素5,所以打印出来是5就是这样来的。
C语言数组作业
数组。1 将数组a中的偶数送给b数组。void main int a 10 int b 10 k 0 for i 0 i 9 i int i,j,t for i 0 i 7 i 2 for i 0 i 9 i printf 3d a i 3 下面程序的运行结果是。void main int i,f ...
C语言数组答案
c第5次上机练习 数组。1 输入n个整数,用一维数组存放,然后将这n个整数逆序存放并输出。2 将1 200中所有11的倍数存放到一个一维数组中,并输出。3 有n个已经按由小到大排好序的整数,再输入一个整数,将其插入到这批数据中,要求插入该元素后仍然按由小到大的顺序排列。4 二维数组 求一个n n矩阵...
C语言练习 数组 附答案
一 基础知识 数组的定义 初始化 引用和遍历 1 定义一个整型数组 a,长度为 10,全部赋值为 0 9,以 d t 格式输出所有元素。2 定义一个整型数组 b,长度为 6,第 1 个元素为 2,第 3 个元素 4,第 4 个元素为 5,其它赋值为 0,以 d t 格式输出所有元素。3 定义一个浮点...