一道c语言指针问题!
2010-10-31 19:35
260 查看
今天闲着无聊,逛了一下别人的blog~发现了这么一道题,我郁闷了,做错了~~晕死~
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *pa = (int)(&a) + 1;
printf("%x/n", *pa);
return 0;
}
你觉得答案会是多少涅?
哈哈,没错了,就是2000000!,如果你知道是这个数了,那么请你离开吧,别浪费时间了,你想的是对的!带着你的不屑去看大牛的文章吧
看到这里的人,估计都跟我一样,算错了吧~哈,那就多担待,看看我废话吧!
首先,考查点:一看到这样的题,我想到的是内存的分配图,字节对齐,字节序等问题。
所以我们应该先假定这程序运行的平台,假设该程序运行在intel 32位机上吧,那么我们就可以确定以下几个事:
1 int 是32位的
2 字节序是小端字节序(小端不知道的,自已查去!)
(&a)这个值求的是字符串的地址,即字符串的首地址,但又与a这个字符串的首地址有所差别@
把该地址值强制转化为int型,再把int型的数+1,把该值赋值给pa指针,即此时,该pa指针,指的就是a[0]的第二个字节的地址!
由于pa是整数指针,所以*pa的值就等于,a[0]字节的第二个字符起到a[1]的第1个字节组合而成的整数!
内存分布图如下:
pa指向a[1] 的第一个字节[0xbf9968b0]
然后*pa即是取从该地址开始的四个字节所存储的内容,pa所指向的那个整数值,因为是小端字节序,所以02应在高位,所以该整数变为
02000000!
这就是为什么答案是02000000!明白了吧。
好吧,引申再复习下内存分配与指针的问题吧~
再看下面一个例子:
运行环境:gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
运行结果如下:
从上面代码可得出:
1)该程序的所有变量存放在栈里,栈的分布情况是从高地址往低地址分布,
注意:这里有一点需要关注一下,可能是编译器相关的问题,就是数组并不满足先定义先分配的规律,数组分布位置会在所有变量分布完
后的后面分配;当x的地址却要比a数组的地址要高,因为x先定义,
但after_array1的值也比a高!这里我也还没问明白,估计是编译器优化!
2)数组的内存分配是从低到高!即a[0]的地址比a[1]的地址要低。
3)int a[5]={...}
定义该数组之后,a与&a数值相同,但表示的意义完全不一样,可从a+1,&a+1的值可以看出,a+1的步长是4个字节,而&a+1的步长 却是整个数组的长度。
4)内存字节序的问题,*(char *)((int)(&a) + x)从低地址到高地址每个字节的内容,注意:14存放的地址比11的地址要低,如果刚刚第一 个例子看得明白的话,这里应该也知道怎么来的了,包括最后一个输出的值,其实就是跟第一个例子是完全一样的!
这里需要注意的是不能忘了把(&a)强制转化为int型,这里(&a)也可以替换为a,因为这里只需要的是该数组首地址这个“值”在这一点 上这两个是没有区别的!
最后,last but not least!
上面所有的测试都是与平台相关的,如果是64位,或者是16位机那又要另当别论了,所以一开始我就是采用假设是在32位机上的测试!
#include <stdio.h>
int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *pa = (int)(&a) + 1;
printf("%x/n", *pa);
return 0;
}
你觉得答案会是多少涅?
哈哈,没错了,就是2000000!,如果你知道是这个数了,那么请你离开吧,别浪费时间了,你想的是对的!带着你的不屑去看大牛的文章吧
看到这里的人,估计都跟我一样,算错了吧~哈,那就多担待,看看我废话吧!
首先,考查点:一看到这样的题,我想到的是内存的分配图,字节对齐,字节序等问题。
所以我们应该先假定这程序运行的平台,假设该程序运行在intel 32位机上吧,那么我们就可以确定以下几个事:
1 int 是32位的
2 字节序是小端字节序(小端不知道的,自已查去!)
(&a)这个值求的是字符串的地址,即字符串的首地址,但又与a这个字符串的首地址有所差别@
把该地址值强制转化为int型,再把int型的数+1,把该值赋值给pa指针,即此时,该pa指针,指的就是a[0]的第二个字节的地址!
由于pa是整数指针,所以*pa的值就等于,a[0]字节的第二个字符起到a[1]的第1个字节组合而成的整数!
内存分布图如下:
|
然后*pa即是取从该地址开始的四个字节所存储的内容,pa所指向的那个整数值,因为是小端字节序,所以02应在高位,所以该整数变为
02000000!
这就是为什么答案是02000000!明白了吧。
好吧,引申再复习下内存分配与指针的问题吧~
再看下面一个例子:
int x = 1; int after_array = 2; int a[5] = {0x11121314,0x21222324,0x31323435, 0x41424344,0x51525354}; int after_array1 = 1; char ch_a; printf("&x = %x/n",&x); printf("&after_array = %x/n",&after_array);//数组后的一个变量的地址 printf("&after_array1 = %x/n",&after_array1);//数组后的一个变量的地址 printf("&ch_a = %x/n",&ch_a); printf("a = %x/n",a);//数组第一个元素的值 printf("&a = %x/n",&a);//数组的地址(即第一个元素的地址) printf("a + 1 = %x/n",a+1);//数组第二个元素的地址 printf("a + 4 = %x/n",a+4);//数组第五个元素的地址 printf("&a + 1 = %x/n",&a + 1);//数组后面的一个变量的地址, for(x = 0;x < 20;x ++) { printf("%2x ",*(char *)((int)(&a) + x));//打印每一个字节的内容 } printf("/n"); int *pa = (int)(&a) + 1; printf("%x/n",*pa);
运行环境:gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
运行结果如下:
&x = bfc89e18 &after_array = bfc89e14 &after_array1 = bfc89e10 &ch_a = bfc89e1f a = bfc89df8 &a = bfc89df8 a + 1 = bfc89dfc a + 4 = bfc89e08 &a + 1 = bfc89e0c 14 13 12 11 24 23 22 21 35 34 32 31 44 43 42 41 54 53 52 51 24111213
从上面代码可得出:
1)该程序的所有变量存放在栈里,栈的分布情况是从高地址往低地址分布,
注意:这里有一点需要关注一下,可能是编译器相关的问题,就是数组并不满足先定义先分配的规律,数组分布位置会在所有变量分布完
后的后面分配;当x的地址却要比a数组的地址要高,因为x先定义,
但after_array1的值也比a高!这里我也还没问明白,估计是编译器优化!
2)数组的内存分配是从低到高!即a[0]的地址比a[1]的地址要低。
3)int a[5]={...}
定义该数组之后,a与&a数值相同,但表示的意义完全不一样,可从a+1,&a+1的值可以看出,a+1的步长是4个字节,而&a+1的步长 却是整个数组的长度。
4)内存字节序的问题,*(char *)((int)(&a) + x)从低地址到高地址每个字节的内容,注意:14存放的地址比11的地址要低,如果刚刚第一 个例子看得明白的话,这里应该也知道怎么来的了,包括最后一个输出的值,其实就是跟第一个例子是完全一样的!
这里需要注意的是不能忘了把(&a)强制转化为int型,这里(&a)也可以替换为a,因为这里只需要的是该数组首地址这个“值”在这一点 上这两个是没有区别的!
最后,last but not least!
上面所有的测试都是与平台相关的,如果是64位,或者是16位机那又要另当别论了,所以一开始我就是采用假设是在32位机上的测试!
相关文章推荐
- C语言指针的赋值问题
- 关于c语言中double指针的初始化问题
- 一道简单题--解释C语言的指针,结构体等基本用法
- c语言纠结问题之一,调试正确,运行正确----二级指针的作用
- 还是C语言的指针问题。。
- C语言 指针相关问题--调用函数实现空间动态申请
- C语言指针作为形参的一些问题
- 小小的C语言问题指针数组赋值----关于指针和数组。
- C语言中指针和自增运算符结合时的运算顺序问题
- 一道一维数组与二级指针的问题
- C语言中动态分配数组指针的释放问题
- 关于C语言野指针的问题
- c语言 函数 用指针传递参数 问题
- C语言中指针和自增运算符结合时的运算顺序问题
- c语言字符串和指针十个问题
- 一道C语言的指针笔试题
- C语言指针问题
- c语言指针问题
- c语言中的指针问题
- 一道C语言的问题(转)