printf("%d, %d\n", i++, ++i)的输出结果是确定的吗???
1. 问题描述
以下代码的输出结果是什么?
题目1:
int i=;
printf("%d, %d\n", i++, ++i);
题目2:
int i = ;
printf("%d, %d, %d, %d, %d\n", i++, ++i, i, i++, i);
2. 解题思路【错误】
printf参数是从右至左入栈的,故:
- 题目1的输出为:11,12
- 题目2的输出为:
3. 反思
- 注意:该类题目编译器不一样,结果就会不一样,即这种行为依赖编译器!!!不必纠结。
- 原因分析:
- C/C++语言没有规定具体压栈顺序,没有标准化时C语言支持没有固定参数的函数,所以为了实现这个当时多数编译器都采用从右往左压栈,但是标准化的要求至少有一个固定参数,这个限制就没有必要了。不过从右到左几乎已经成为了C编译器惯用的顺序。C++的_stdcall方式也是采用从右到左,不同的只是不需要调用者自己手动清栈。
- 另外求值顺序和压栈顺序是两回事,C语言里几乎没有对求值顺序做规定,编译器完全可以先求出值再决定如何压栈。
- 简单说,这种问题与编译器实现语言的规定有关。不同编译器下生成的代码可能不同,出现的结果就不同。对于这种可能造成错误的代码,不用纠结。
What's the value of i++ + i++?
It's undefined. Basically, in C and C++, if you read a variable twice in an expression where you also write it, the result is undefined. Don't do that. Another example is:
v[i] = i++;
Related example:
f(v[i],i++);
Here, the result is undefined because the order of evaluation of function arguments are undefined.
Having the order of evaluation undefined is claimed to yield better performing code. Compilers could warn about such examples, which are typically subtle bugs (or potential subtle bugs). I'm disappointed that after decades, most compilers still don't warn, leaving that job to specialized, separate, and underused tools.
printf("%d, %d\n", i++, ++i)的输出结果是确定的吗???的更多相关文章
- linux下printf函数为什么不加\n就不能输出相关的内容 ?
转载请注明出处:http://blog.csdn.net/qq_26093511/article/details/53255970 原因: 输出缓冲区的问题. unix上标准输入输出都是带有缓存的, ...
- C语言中printf的规范输出
1.调用格式为 printf("<格式化字符串>", <参量表>); 其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出; 另 ...
- printf格式输出总结
#include<stdio.h> #include<string.h> int main() { ]; ; floa ...
- win32程序调试OutputDebugString 类似printf格式化输出
有没有win32编程因为打印变量调试程序而头疼呢.方法二的函数完全类似printf.非常完美.方法一:不带参数输出如printf("hello world"); OutputDeb ...
- 7.20.01 java格式化输出 printf 例子
java格式化输出 printf 例子 importjava.util.Date; publicclassPrintf { publicstaticvoidmain(String[] args) { ...
- shell之 printf 输出语句
总结: (1)printf 使用引用文本或空格分隔的参数,外面可以在printf中使用格式化字符串,还可以制定字符串的宽度.左右对齐方式等.默认printf不会像 echo 自动添加换行符,我们可以手 ...
- php输出语句 echo print printf print_r var_dump sprintf
php的几种输出方式: echo 常用的输出语句,例如:echo 'helloworld!'; print() 输出语句,有返回值.例如:print('helloworld!'); 输出成功返回1,失 ...
- C编程中printf不加'\n'不输出
有时,使用printf("a=%d",a);并不一定会输出显示,只有当在格式化输出时加上'\n'才能输出,如printf("a=%d\n",a); 由于unix ...
- Java面向对象 第2节 Scanner 类和格式化输出printf
§Scanner 类 java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入. 1.创建 Scanner 对象的基本语法:Scanner s = ...
随机推荐
- 有趣的keil MDK细节
1.MDK中的char类型的取值范围是? 在MDK中,默认情况下,char 类型的数据项是无符号的,所以它的取值范围是0-255.它们可以显式地声明为signed char 或 unsigned.因此 ...
- 取PE文件的引入表和导出表
直接上代码(这里列出C++和Delphi的代码),Delphi代码中包含导入及导出文件和函数列表,PE结构可参阅资料,很多很详细,需要注意的是,本例中是映射到内存,不是通过PE装载器装入的,所以对于节 ...
- Delphi常见图象格式转换技术
TJPEGScale = (jsFullSize, jsHalf, jsQuarter, jsEighth);//图片大小(全部,1/2,1/4,1/8)TBitmap.pixelFormat:=pf ...
- php-GD库的函数(一)
<?php //getimagesize - 取得图片的大小[即长与宽] //print_r(getimagesize("./logo_i.gif")); //Array ( ...
- OC运行时和方法机制笔记
在OC当中,属性是对字段的一种特殊封装手段. 在编译期,编译器会将对字段的访问替换为内存偏移量,实质是一种硬编码. 如果增加一个字段,那么对象的内存排布就会改变,需要重新编译才行. OC的做法是,把实 ...
- [置顶] Mysql存储过程入门知识
Mysql存储过程入门知识 #1,查看数据库所有的存储过程名 #--这个语句被用来移除一个存储程序.不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程 #SELECT NAME FROM ...
- android开发之Animations的使用(二)
android开发之Animations的使用(二) 本博文主要讲述的是android开发中的animation动画效果的使用,和上一篇博文不同的是,此次四种动画效果,主要使用的是xml文件实现的,提 ...
- IsNullOrEmpty和s == null || s.Length == 0哪个快
在写扩展方法时,看到有人用==null这个方法,说快,上网找了些资料,最后在csdn的博客上看到了一篇文章,说实测是后两者快,于是我也试着做了一个程序运行了一下,却发现这样的结果: 我测试了一个,发现 ...
- box-shadow属性
一.定义和用法 box-shadow属性 向框添加一个或多个阴影. 二.语法 box-shadow: h-shadow v-shadow blur spread color inset; h-shad ...
- Android源码学习(一) 数据集观察者
查看Android源码发现这个,决定记下下来. 1.在android.database这个包下面,存在这样一个抽象类DataSetObserver,里面包括onChanged()和onInvalida ...