代码:
- #include<iostream>
- usingnamespacestd;
- classA
- {
- private:
- intx1;
- intx2;
- public:
- A():x2(1),x1(x2++){}
- voidprint()
- {
- cout<<"x1="<<x1<<endl
- <<"x2="<<x2<<endl;
- }
- };
- intmain()
- {
- Aa;
- a.print();
- return0;
- }
疑:x1,x2最终被输出什么值呢?为什么?
解答:上机调试下会发现输出的结果是:x1是一个随机数,x2是1。为什么?因为在初始化列表中在给x1赋值为x2++时,这个x2并未初始化,也就是说x2里面什么东西也没装。也许你会问我不是在前面已经给x2赋值了吗,没错,但是有一个问题你忽略了,那就是初始化列表的赋值顺序是依照x1和x2的声明顺序的顺序来初始化的,也就是说在代码中,程序是先给x1赋值为x2++(此时x2并未初始化),再给x2赋值为1。还有初始化列表里的赋值,是在变量被声明时进行的,所以多使用初始化列表是可以提升程序效率的。
!!代码疑云系列由本人在天天唯C论坛下首发
代码:
- #include<iostream>
- usingnamespacestd;
- voidfoo(intp1,intp2,intp3)
- {
- cout<<"p1="<<p1<<endl
- <<"p2="<<p2<<endl
- <<"p3="<<p3<<endl;
- }
- intmain()
- {
- inti;
- cout<<"firstcall:"<<endl;
- i=0;
- foo(++i,++i,++i);
- cout<<"secondcall:"<<endl;
- i=0;
- foo(++i,i++,i++);
- return0;
- }
疑:两次调用foo函数分别输出了什么,为什么?
解答:按照cedel函数调用的约定,编译器使参数从左到右的入栈。第一次调用为什么p1,p2,p3的值全是3呢,原因在此,在foo被call之前三++i 操作将先被操作也就是连续自增了3次,最终结果i 的值是3,然后是编译器push(i),push(i),push(i)三次入栈,然后call到foo定义处依次出栈并相应地复制给了形参。第二次调用foo时,一开始与第一次一样先是计算三次++操作,但是所不同的是最后两个是i++,i++
刚没说到它们的计算顺序,编译器计算这些的顺序是由右到左的,也就是先i++,再i++,最后是++i,而运算i++是先取值再自增的,编译器会先把i (这时为0)存入寄存器(cpu中的存储器),再加1,然后计算下一个i++ 与前一次一样,所不同的是这次 i 的值是1,因为前面已加1 ,最后++i 。
!!代码疑云系列由本人在天天唯C论坛下首发
代码:
- #include<iostream>
- usingnamespacestd;
- intmain()
- {
- char*str1="string";
- char*str2="string";
- if(str1==str2)
- cout<<"str1issameasstr2";
- }
疑:str1 的值是否等于 str2 而输出字符串“str1 is same as str2”呢,为什么?
解答:是的 “str1 is same as srr2”,也就是说str1与str2指向了相同的内存地址,因为"string"是静态对象,是由编译器分配给他的内存空间,在代码中出现了两次,编译器并不会给他们分别分配空间,因为如果这样将会造成不必要的浪费。
代码:
- #include<iostream>
- usingnamespacestd;
- classA
- {
- };
- classB
- {
- chara;
- intb;
- };
- classC
- {
- voidfoo(){};
- };
- classD
- {
- virtualvoidfoo(){};
- };
- intmain()
- {
- cout<<sizeof(A)<<sizeof(B)<<sizeof(C)<<sizeof(D);
- return0;
- }
疑:结果是什么,为什么呢?
解答:sizeof(A)为1,而不是0,虽然空类没有任何成员变量,但其实体提供取地址操作,所以其内存空间不能为0。sizeof(B)为8,编译器在计算类体或结构体变量的地址时是通过字节对齐的方式进行的,也就是通过加多少偏移量来确认是那个变量。类的偏移量为其最大内存空间的类型的成员变量的长度,其最大内存空间类型成员是int,所以偏移量为4字节,即char a成员需要补上3个字节,才能让编译器准确高效地寻址,再加上int的4字节,sizeof(B)就是8了。sizeof(C)为1,类的成员函数在编译器编译时,其函数地址就已自动存放,所以不必为其分配额外的空间来存放他,所以它的长度跟空类一样为1。sizeof(D)为4,因为类D需要构造一虚函数列表来存放函数指针以实现动态调用,一个指针的长度占用4个字节,所以为4.
代码:
- #include<iostream>
- usingnamespacestd;
- classA
- {
- private:
- intvalue;
- public:
- A()
- {
- value=0;
- }
- voidcoutHello()
- {
- cout<<"hello"<<endl;
- }
- voidcoutValue()
- {
- cout<<value<<endl;
- }
- };
- intmain()
- {
- A*pA=NULL;
- pA->coutHello();
- pA->coutValue();
- return0;
- }
(感谢网友提供的题目)
疑:调用coutHello和coutValue方法有什么问题?
解答:
成员函数的地址在编译器编译时给出的,所以是已知的,根据thiscall约定,类的成员函数在编译时编译器会传入一个this指针,通过this指针指向成员变量,在调用couthello时并未用到this指针所以调用正常,而调用coutvalue时,value需要用到this指针,因为此时this是NULL指针,所以会发生内存报错。
代码:
头文件print_tools.h
- #include<stdio.h>
- voidprintStr(constchar*pStr)
- {
- printf("%s\n",pStr);
- }
- voidprinttInt(constinti)
- {
- printf("%d\n",i);
- }
头文件counter.h
- #include"print_tools.h"
- staticintsg_value;
- voidcounter_init()
- {
- sg_value=0;
- }
- voidcounter_count()
- {
- sg_value++;
- }
- voidcounter_out_result()
- {
- printStr("theresultis:");
- printtInt(sg_value);
- }
main.cpp
- #include"print_tools.h"
- #include"counter.h"
- intmain()
- {
- charch;
- counter_init();
- printStr("pleaseinputsomecharactors:");
- while((ch=getchar())!='$')
- {
- if(ch=='A')
- <spanstyle="white-space:pre"></span>counter_count();
- }
- counter_out_result();
- }
疑:以上代码编译时有何问题吗,是什么导致的呢?
解答:void printStr(const char*)和'void printtInt(int) 函数redefine了,道理很简单,因为在counter.h中已包含了print_tools.h,在main.cpp中又包含了print_tools.h头文件,也就是两次包含了print_toosl.h,所以也就发生了重定义错误,这是初学者常见问题,要避免这个问题,我们必须采取防范措施,就是使用预编译命令,如下作修改:
头文件print_tools.h
- #ifndefPRINT_TOOLS_H//如果未定义PRINT_TOOLS_H
- #definePRINT_TOOLS_H//则定义然后编译以下源代码
- #include<stdio.h>
- voidprintStr(constchar*pStr)
- {
- printf("%s\n",pStr);
- }
- voidprinttInt(constinti)
- {
- printf("%d\n",i);
- }
- #endif//结束//如此改头文件就只被编译器编译一次了,起到了防范重定义错误的作用
头文件counter.h
- #ifndefCOUNTER_H//
- #defineCOUNTER_H//
- #include"print_tools.h"
- staticintsg_value;
- voidcounter_init()
- {
- sg_value=0;
- }
- voidcounter_count()
- {
- sg_value++;
- }
- voidcounter_out_result()
- {
- printStr("theresultis:");
- printtInt(sg_value);
- }
- #endif//
在一个工程项目中头文件众多繁杂,采用这个方法可以很好的避免,所以每当我们定义一个头文件时要养成如此的良好习惯。
代码:
- #include<iostream>
- usingnamespacestd;
- classA
- {
- public:
- A()
- {
- Print();
- }
- virtualvoidPrint()
- {
- cout<<"Aisconstructed.\n";
- }
- };
- classB:publicA
- {
- public:
- B()
- {
- Print();
- }
- virtualvoidPrint()
- {
- cout<<"Bisconstructed.\n";
- }
- };
- intmain()
- {
- A*pA=newB();
- deletepA;
- return0;
- }
(感谢网友提供的题目)
疑:以上代码输出结果是?
输出结果如下:
A is constructed.
B is constructed.
解释:当new B()时,因为B继承了A,所以编译器首先调用A的构造函数,A的构造函数里是调用A类里的Print(),所以首先输出A is constructed ,然后调用的是B的构造函数,此时Print虚函数指针已指向B的void print(),所以输出B is constructed。
分享到:
相关推荐
自《如月疑云》上映以来,这部电影以其别具一格的叙事方式、扣人心弦的悬疑情节以及蕴含其中的幽默元素,成为了不少影迷热烈讨论的话题。它不仅是一部让人捧腹大笑的喜剧片,更是一次思维的盛宴,提供了丰富的推理...
这可能是通过植入恶意代码或者利用系统漏洞实现的。一旦APP获取了音频数据,它可以分析用户的消费习惯,甚至可能在用户谈论特定商品时推送相关广告,这被称为“定向广告”。尽管这听起来像是科幻电影的情节,但在...
绑架疑云是一个涉及到犯罪侦查、社区安全监控、人际交往和心理应对等多个知识点的案例。在这个案例中,我们可以深入探讨以下几个方面的内容: 1. 犯罪侦查知识:案例中刑警李福生在接到孙子失踪的消息后,没有慌乱...
六年级语文纸团疑云PPT教案学习.pptx
上述代码首先将中文字符串按照“编码1”转换成字节,然后再将这些字节按照“编码2”转换回字符串。这种方法适用于没有内置编码选择功能的串口工具,通过程序代码的转换来确保正确的中文显示。 解决串口乱码问题的...
本周电子行业的焦点集中在了三安光电的财务疑云上,这一事件引发了整个LED产业的深思,仿佛整个产业正处在凛冽的寒冬之中。我们来深入探讨一下这个话题。 首先,三安光电作为国内LED行业的领军企业,其财务状况一直...
《IT经理世界》中国联通G网升级疑云.doc
汽车整车行业:特斯拉专题报告-疑云疏散,否极泰来
《如月疑云》是一部融合了推理与喜剧元素的电影,全长108分钟,以其独特的叙事手法和出人意料的情节转折赢得了观众的喜爱。影片最初被介绍为一部悬疑片,可能会让部分观众产生抵触心理,然而,观影后的体验却打破了...
电子行业周报:三安财务疑云发酵,LED产业寒冬凛冽.pdf
随着互联网技术的飞速发展,电商平台的推荐系统变得越来越智能化,能够根据用户的行为和偏好提供个性化服务。然而,用户在享受个性化推荐的便利的同时,也日益关注其个人隐私和数据安全问题。本文通过几个案例,分析...
在PCB设计中,反射是影响信号完整性和系统性能的关键因素。反射通常发生在信号线上的阻抗不连续处,例如连接器、过孔、走线宽度变化或端接不匹配等。这些不连续性会导致信号的能量部分反射回源头,产生信号失真,...
食品饮料行业:消费税疑云消散,继续看好白酒啤酒-1209-中信建投-35页.pdf
线下逆袭疑云:淘品牌纠结的“独立战争” 淘品牌,源自电商平台,特别是淘宝,以其独特的商业模式和快速崛起,一度成为电商领域的亮点。然而,近年来,一些淘品牌开始尝试开设线下实体店,试图打破纯电商模式,实现...
【步步高】2014-2015学年高中物理 2.1-2.2 拨开黑体辐射的疑云 涅槃凤凰再飞翔课件 沪科版选修3-5
违约研究系列专题之三:康而不实,美难掩瑕,康美药业的疑云与启示-0603-招商证券-12页.pdf
苹果公司于2023年9月宣布其新款Apple Watch系列实现了碳中和,这是一个备受瞩目的里程碑,尤其是在全球智能手机市场下滑的背景下。然而,这一声明伴随着一些争议,因为供应链中的部分供应商碳排放量并未显著下降,...
当前,食品饮料行业特别是白酒和啤酒板块,一直受到投资者的密切关注。近期,消费税政策的变化为行业带来了新的...随着消费税政策疑云的消散,食品饮料行业有望继续保持稳定的增长趋势,并为投资者带来持续的投资回报。
小学教案