A,局部变量的返回地址

Q:下面的代码有问题吗?如果有,如何修改?

#include

int* inc(int val)

{

int a = val;

a++;

return &a;

}

int main(void)

{

int a = 10;

int *val = inc(a);

printf("\n Incremented value is equal to [%d] \n", *val);

return 0;

}

A:虽然上面的代码有时运行会很好,但是在方法 inc() 中有很严重的隐患。当inc()方法执行后,再次使用局部变量的地址就会造成不可估量的结果。解决之道就是传递变量a的地址给main()。

Answer: Though the above program may run perfectly fine at times but there is a serious loophole in the function ‘inc()’. This function returns the address of a local variable. Since the life time of this local variable is that of the function ‘inc()’ so after inc() is done with its processing, using the address of its local variable can cause undesired results. This can be avoided by passing the address of variable ‘a’ from main() and then inside changes can be made to the value kept at this address.

评:

这个主要是翻译的问题。对照一下原文就会发现,译文不但漏掉了很多内容没有翻译,最严重的是把“by passing the address of variable ‘a’ from main()”给翻译成了“传递变量a的地址给main()”,彻底颠覆了原文的意思。原意是传递main()中变量a的地址,即调用形式为int(&a),而译文的意思依然是代码中那种错误写法的描述。

B,处理 printf() 参数

Q:以下代码输出请问是什么?

#include

int main(void)

{

int a = 10, b = 20, c = 30;

printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2));

return 0;

}

A:输出将是

1 110..40..60

这是因为参数都是从右向左处理的,然后打印出来却是从左向右。

Answer: The output of the above code would be :

110..40..60

This is because the arguments to the function are processed from right to left but are printed from left to right.

评:

这个问题和解答都很狗血!

“参数都是从右向左处理的”是无中生有。C标准规定

The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

也就是说实参的求值次序没做规定(unspecified),编译器可以自己安排计算次序,无论怎样安排都不违背标准。从右向左或从右到左都可以。断言“参数都是从右向左处理”,是这个解答中第一个错误。

前面引用条文中还提到了在实际调用前存在一个序点(sequence point),对于代码中

printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2))

这个函数调用来说,前一个序点就是之前的“;”。

C语言的另一个规定是:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.Furthermore, the prior value shall be read only to determine the value to be stored.

这两句话是什么意思呢?前一句说的是两个相邻序点之间,一个数据对象的值最多可以改变一次。如果改变多次,就是未定义行为。譬如写出下面代码

printf("%d,%d,%d,%d\n", ++i, --i, i++, i--);

就是出于典型的对未定义行为的无知。而津津乐道、煞有介事地讨论这种根本没有意义的代码(i++和++i作为参数时的编译器处理方式分析~) ,就如同谭浩强津津乐道地讨论a+=a-=a*a一样荒唐(参见“牙里长嘴”和“a+=a-=a*a” ),我擦,岂不是滑天下之大稽?只有根本没有技术能力又缺乏自知之明的怨妇,才可能无聊到做这种荒谬无价值的事情。

标准条文中的后面一句有些晦涩,它的意思是数据对象中先前的值只能是用来确定数据对象中后来存储的值,例如:

int i = 1;

i = i + 1 ;

i只改变了一次,且i的原值(1)用来确定i后来存储的值(2)。

如果数据对象的值在两个序点之间只改变一次,且数据对象的原值不是用来确定数据对象后来的值,例如:

int i = 1 , j ;

j = i + (i = 2) ;

则属于未定义行为。因为表达式中第一个i的值不是为了确定i将要存储的值。没人说的清这个i + (i = 2) 这个表达式的值应该是4还是3。

回过头再看问答代码中的

printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2));

b和c都被改变一次,但由于在表达式a+b+c中,b和c的值不是用来确定b和c最终的值,因此这段代码属于没有意义的未定义行为。

因此,这个问答一共错了两处。一处是说“参数都是从右向左处理的”,另一处就是代码行为未定义。

(全文完)

C语言面试问答5

12个滑稽的C语言面试问答——<12个有趣的C语言问答>评析(5) 前文链接:http://www.cnblogs.com/pmer/archive/2013/09/17/3327262. ...

C语言面试问答&lpar;3&rpar;

12个滑稽的C语言面试问答——<12个有趣的C语言问答>评析(3) 前文链接:http://www.cnblogs.com/pmer/p/3322429.html 5,atexit wit ...

《12个有趣的C语言问答》&lpar;4&rpar;

C语言面试问答——<12个有趣的C语言问答>评析(4) 前文链接:http://www.cnblogs.com/pmer/p/3324063.html 8,Making changes i ...

《12个有趣的C语言问答》评析2

<12个有趣的C语言问答>评析(2) 前文链接:http://www.cnblogs.com/pmer/p/3313913.html (没存盘,遭遇过热保护.至少4个问答的评论白写了.默哀 ...

12个有趣的C语言问答(详解)

本文参照博文<12个有趣的C语言问答>,在原文的基础上增加来对应的知识点的详细介绍. 1 gets()方法 Q:下面的代码有一个被隐藏的问题,你能找到它吗? #include

C语言面试基础知识整理

一.预处理 1.什么是预编译?何时需要预编译? (1)预编译又称预处理,是做些代码文本的替换工作,即程序执行前的一些预处理工作.主要处理#开头的指令,如拷贝#include包含的文件代码.替换#def ...

C语言经典面试题 与 C语言面试宝典

1 预处理 问题1:什么是预编译?何时需要预编译? 答: 预编译又称预处理,是整个编译过程最先做的工作,即程序执行前的一些预处理工作.主要处理#开头的指令.如拷贝#include包含的文件代码.替换# ...

c语言面试宝典(经典,超详细)

c语言面试宝典(经典,超详细) 2018年08月25日 09:32:19 chengxuyuan997 阅读数:7799   摘自:https://blog.csdn.net/chengxuyuan9 ...

10个经典的C语言面试基础算法及代码

c语言滑稽的编程,12个滑稽的C语言面试问答——《12个有趣的C语言问答》评析(5)...相关推荐

  1. 基于C语言的软件,基于C语言的计算机软件编程分析

    摘 要 C语言是在B语言的基础上发展而来,其功能强大,使用便利,是目前计算机软件编程最基础的语言.C语言有着特殊的编程技巧,他的函数库中包含了编程所需的大部分函数,因此不需要程序员再另外定义:C语言中 ...

  2. 在BricxCC中用C++语言为EV3编程

    一.教程 以下教程摘自中文乐高社区(博主:ntwuhui) 网址:http://bbs.cmnxt.com/thread-13374-1-1.html 相关软件: BricxCC(支持EV3) htt ...

  3. c汇编语言实验,C语言与汇编语言编程实验

    1. 掌握在ADT IDE中编写汇编和C语言混合编程程序; 2. 掌握C语言和汇编语言相互调用的过程; 3. 掌握GNU C中内嵌汇编语言的编程方法. C语言与汇编语言编程实验 实验目的 1. 掌握在 ...

  4. 【历史上的今天】12 月 3 日:世界上第一条短信;Fortran 语言之父诞生;百度贴吧上线

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2021 年 12 月 3 日,在 20 年前的今天,电动平衡车(Segway)问世:电动平衡车是一种电力驱动.具 ...

  5. c语言二级编程题库,二级C语言题库-编程题.doc

    二级C语言题库-编程题 第 PAGE \* Arabic \* MERGEFORMAT 27 页第 PAGE \* Arabic \* MERGEFORMAT 27 页 1.请编写函数fun,其功能是 ...

  6. c语言宏定义_掌握C语言,中文编程不是梦

    文/Edward 前面我们在讲节程序编译的时候,编译器做的第一步就是预处理.C语言的预处理,其实是编译器在对整个工程编译之前做的一些文本性质的工作,例如我们经常使用的#include,这就是一个典型的 ...

  7. C++学习笔记:(七)C语言实现面向对象编程

    面试官:C和C++有什么不同? 应聘者:一个是面向过程,一个是面向对象. 这样的答案在我看是不完全正确,因为面向过程编程和面向对象编程是编程思想,C++可以用面向过程的思想编程,同样,C语言也可以用面 ...

  8. linux c语言 信号,linux下基于C语言的信号编程实例

    搜索热词 本文实例讲述了linux下基于C语言的信号编程方法.分享给大家供大家参考.具体如下: #include #include #include #include #include void si ...

  9. C语言多文件编程基本格式

    1.背景: 用一个丢骰子的简单案例熟悉了C语言多文件编程该咋写 2.格式 (1)主函数文件main.c //文件头part1:所有要使用的函数#include ;#include ;#include ...

最新文章

  1. Apriori算法、FP-Growth算法、顺序分析、PrefixSpan算法
  2. 从源码分析DEARGUI之add_text_point
  3. 数据中台、标签、数据资产相关的15个名词解释
  4. yoyo思维题(困难) 组合数学
  5. Eclipse jar包打不进apk
  6. 51单片机实现4位数以内的加减法
  7. Java命令学习系列(三)——Jmap
  8. 弄懂goroutine调度原理
  9. 2014北科计算机原理试题答案,北科_计算机组成原理考题-A卷答案
  10. python mypy类型检查_Python中类型检查的详细介绍
  11. 图解TCPIP-TCP IP
  12. 2.权限管理准备工作:你应该知道的ASP.NET网站最基本的安全措施!
  13. 盘点OLCF的超级计算机
  14. oracle isnull使用索引,isnull()用法总结
  15. 网络编程--探讨一些边界条件
  16. 整合xxl-job-admin动态添加xxl-job定时任务
  17. 联合省选 2021 解题报告
  18. CCTV-TIME特别关注:深圳首届弘扬关公文化促进两岸统一忠义论坛
  19. java log写入txt文件_使用java.util.logging.Logger时如何在文本文件中写日志
  20. 通过继承实现圆柱体面积体积的计算

热门文章

  1. Android 智能手机企业项目
  2. coco语义分割标注json转png
  3. 春风十里不如你——我如果爱你
  4. 博士论文——基于卷积神经网络的人脸识别研究 __张燕红
  5. 更简单的ASP.NET Core多语言(国际化和本地化, 欢迎转载)
  6. java 集成 cas系统 服务端和客户端配置
  7. Python实现归一化和标准化处理
  8. 国际智慧教育展启动第五届校园好方案评选活动
  9. 四川玖益科技:开店的注意事项分析
  10. 查询数据库的隔离级别