“写出printf的输出结果”——你能看到什么?
2010-08-01 09:27
309 查看
<!--
@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
的输出结果。假设这些代码运行在intel
cpu, 32bit. integer
四个bytes.
//code starts
:
@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
的输出结果。假设这些代码运行在intel
cpu, 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("%*d",5,10);这个表达式正确?如果正确输出什么?怎么实现的?
- printf()输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf命令_Linux printf 命令用法详解:格式化并输出结果
- 编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。
- free结果输出中的-/+ buffers/cache是什么意思
- 什么是行缓冲?printf输出的条件
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d",5.01)和printf("%f",5)的输出结果
- printf("%d", -1<0u); 这个输出什么呀, 0或1?
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。
- 猜下输出结果是什么?
- 一小段C++代码分析,看看你能写出输出结果吗,很简单的!
- printf("%f",10/3);的结果是什么?
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。
- printf("%d",5.01)和printf("%f",5)的输出结果
- 以下代码的输出结果是什么?
- odbc 的 c api实现简单的select*结果printf 输出
- 文章标题编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。
- 将根据字符查询转换后输出结果,规则为:’A’转换为’男’,’B’转换为’女’,其他字符转换为’未知’,请用一个SQL语句写出。