“写出printf的输出结果”——你能看到什么?
来源:互联网 发布:下载打扑克软件 编辑:程序博客网 时间:2024/04/30 18:05
<!--@page { margin: 2cm }P { margin-bottom: 0.21cm }PRE.western { font-family: "DejaVu Sans Mono", monospace }PRE.cjk { font-family: "DejaVu Sans", monospace }PRE.ctl { font-family: "DejaVu Sans Mono", monospace }A:link { so-language: zxx }-->
刚才在 CSDN-CSDN社区-C/C++-C语言里面发现了网友们在讨论一个 printf函数输出结果的问题。因为自己最近在看一个和 scanf函数相关的问题,也就进去看了看(原帖链接:http://topic.csdn.net/u/20100801/07/9775eb1c-d6da-4cb1-a968-c16bc72cc958.html?77377)。
-------------------------------------------------------------
下面就网友们的观点进行描述:
楼主: winematrix
写出(以下程序中)printf的输出结果。假设这些代码运行在intelcpu, 32bit. integer 四个bytes.
//code starts:
#include <stdio.h>int main(){int a[5]={10, 20, 30, 40, 50};int b[5]={100, 200, 300, 400, 500};int *ptr = (int *)(&a+1);int *t = (int *)(&a -1);printf("%d %d %d /n", *(a+1), *(ptr-1), *(t+1));}
//code ends.
1#:bluejays:
*(a+1) 输出 a[1],也就是20
*(ptr-1) 输出a[4],也就是50。
ptr指向a[5]的位置,所以ptr-1就是a[4]
*(t+1)这个就不一定了。t指向a[-5],*(t+1)就是a[-4],这个位置是什么值,我觉得依赖于编译器。
2#bluejays:
我的编译器a的地址是0x22ccc0,b的地址是0x22cca0,也就是说编译器给b分配了8个int的空间,b[0]在a[-8]的位置上,所以a[-4]
的位置是b[4],*(t+1)输出500,
ptr和t分别是0x22ccd4、0x22ccac
5#wibnmo:
b地址为:12ff58
a地址为:12ff6c
&a+1的地址为:12ff80(这里的1是指a整个数组)
10:12ff6c
20:12ff70
30:12ff74
40:12ff78
50:12ff7c
同样&a-1为:12ff58这正是b数组的起始地址。
int *ptr = (int *)(&a+1);
ptr为指向12ff80的指针,ptr-1为12ff7c,即元素50.
int *t = (int *)(&a -1);
t为指向12ff58这块区域的指针,这里正是数组b的区域,t+1即是元素200的地址。
【以上内容在编辑格式上与原帖略有不同,望原作者见谅。】
--------------------------------------------------
以下网友们的问答,我学习总结如下:
[1]:
关于编译后 两个数组 的地址
(b地址为:12ff58----a地址为:12ff6c,这里引用 wibnmo网友的分析,没有自己的分析着实不该,这里暂且用以说明问题。)
解释如下:
由于 a[5] b[5]
同为局部变量,编译器在进行内存分配时,把他们放在了数据栈之上。 而栈的生长方式为向下增长,即在源代码中
出现较晚的变量将会在较低地址上获得自己的存储区域。
[2]:
有关地址运算int *ptr = (int *)(&a+1);int *t = (int *)(&a -1);的问题:
根据网友们的分析,我得出以下结论,
int *ptr=(int *)(&a+1)
所做的是 在以a[]为“格式单元”(0x12ff6c--0x12ff7c)的内存地址之上,加上一个 int *类型长度的内存空间(这里是4
个字节长度),所得的地址(0x12ff80)放入ptr中。
int *t = (int *)(&a -1);
所做的工作同以上分析类似,在此不再说明。
[补—1]
:以上分析不妥,再行分析。
int *ptr=(int *)(&a+1);这里 (&a + 1)经过测试,等价于(0x12FF7F + 1)。
而我的测试: int *t1 = &a,则有0x12FF6C。这是可以理解的。至于上面一行的情况,目前我的解释和原来的讨论大体一致,采用
“格式单元”的说法(有待学习纠正)。不同之处在于所加的内存空间长度为1个字节长度,而不是 int * 类型的长度。
[3]: int *t = (int *)(&a + 1);与 int t= &a + 1;的区别。
经过测试,在实现的结果上没有区别。至于更多的讨论,这里先不去考虑。
[4]:贴出我的一些测试及其结果:
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
int b[5] = {6,7,8,9,a};
int *t1 = &a + 1;
int *t2 = (int *)(&a + 1);
//printf("a==%X;/nb==%X;/nt1==%X;/nt2==%X;/n",&a,&b,&t1,&t2);
//printf("a[0]==%X;/nb[0]==%X;/nt1==%X;/nt2==%X;/n",&a[0],&b[0],&t1,&t2);
//printf("int * ==%d;/na[5]==%X;/nb[5]==%X;/nt1==%X;/nt2==%X;/n",sizeof(int *),&a[4],&b[4],&t1,&t2);
printf("int * ==%d;/na[5]==%X;/nb[5]==%X;/nt1==%X;/nt2==%X;/n",sizeof(int *),&a[4],&b[4],t1,t2);
return 0;
}
// [Conclusions]:
/*------------
<1>
printf("a==%X;/nb==%X;/nt1==%X;/nt2==%X;/n",&a,&b,&t1,&t2);
a==13FF6C;
b==13FF58;
t1==13FF54;
t2==13FF50;
Press any key to continue
<2>
printf("a[0]==%X;/nb[0]==%X;/nt1==%X;/nt2==%X;/n",&a[0],&b[0],&t1,&t2);
a[0]==13FF6C;
b[0]==13FF58;
t1==13FF54;
t2==13FF50;
Press any key to continue
<3>
printf("a[5]==%X;/nb[5]==%X;/nt1==%X;/nt2==%X;/n",&a[4],&b[4],&t1,&t2);
a[5]==13FF7C;
b[5]==13FF68;
t1==13FF54;
t2==13FF50;
Press any key to continue
<4>
printf("int * ==%d;/na[5]==%X;/nb[5]==%X;/nt1==%X;/nt2==%X;/n",sizeof(int *),&a[4],&b[4],&t1,&t2);
int * ==4;
a[5]==13FF7C;
b[5]==13FF68;
t1==13FF54;
t2==13FF50;
Press any key to continue
<5>
printf("int * ==%d;/na[5]==%X;/nb[5]==%X;/nt1==%X;/nt2==%X;/n",sizeof(int *),&a[4],&b[4],t1,t2);
int * ==4;
a[5]==13FF7C;
b[5]==13FF68;
t1==13FF80;
t2==13FF80;
Press any key to continue
-------------*/
[5]:
关键的问题没有解决,看来得在 指针方面 再做加强了。
- “写出printf的输出结果”——你能看到什么?
- 一小段C++代码分析,看看你能写出输出结果吗,很简单的!
- 写出程序的输出结果
- 一个现象,你能看到什么?
- 股市的火爆能看到什么
- 偶尔看到的一篇文章,如果你能读出点什么思想
- 217 写出输出结果
- printf函数使用—针对不同数据类型的输出结果详解
- Chapter9——分析下面的程序,写出其运行时的输出结果/将程序第5行改为Date(int=1,int=1,int=2005);修改程序使之能通过编译
- 关于printf输出结果的一些问题
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- 使用Repo在Windows平台下載Android原始碼
- 【转】10个著名的思想实验
- ZOJ 1713 haiku AC代码!
- HDU 1575(数论,矩阵乘法+求幂)
- Qt学习之路(16): Qt标准对话框之QColorDialog
- “写出printf的输出结果”——你能看到什么?
- 查找记录行 vb.net 2003
- Qt学习之路(17): Qt标准对话框之QMessageBox
- Qt学习之路(18): Qt标准对话框之QInputDialog
- 配置微博StatusNet
- Qt学习之路(19): 事件(event)
- php实现ftp上传功能的类
- Qt学习之路(20): 事件接收与忽略
- Qt学习之路(21): event()