前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C/C++教程】关于C/C++那些坑爹的破事儿,你被坑了吗?

【C/C++教程】关于C/C++那些坑爹的破事儿,你被坑了吗?

作者头像
短短的路走走停停
发布2019-05-14 19:14:58
6120
发布2019-05-14 19:14:58
举报
文章被收录于专栏:程序猿声程序猿声
开始之前,突然想到一个笑话。有个小伙子去面试的时候,技术没问题了,但是面试官故意各种刁难。最后在小伙子心灰意冷的时候,面试官蛋蛋一笑。“小伙子,你看你这么多问题都不会。摆明的技术不过关啊,不如先在公司里学习一段时间吧,月薪就给你2000怎样?” 卧槽,感情这tm都是坑我的啊?只能说,老哥,社会啊。所以说,基础知识不过关,被坑是常事呀~~~

那么,今天,就带大家看看C/C++里面究竟有多少不为人知的秘(keng)密(die)吧。可以测试一下,不看答案,自己能get到多少。

1

printf也风骚型

在此之前,先看一段简单得不能再简单的代码:

哎,这还不简单嘛?无非就是自增嘛,

第一个a输出1,第二个++a 输出2,

第三个a++用的原来的值再自增所以输出2。

蛋是!!!

一丝Q死迷???

自增没有错,坑就坑在,函数参数的入栈顺序是

从右往左

从右往左

从右往左

重要的事情说三遍,这就很好解释了。

先是a++,将a=1入栈,再自增。

而后++a,此时将a=3入栈,

最后输出自然是3 3 1。

2

编译器也偷懒型

Talk is cheap。Show me the code.

So,猜猜下面的代码输出结果是?

哎,这么简单的玩意儿,不是小瞧我胖虎嘛?

两个自增,绝逼是两个2啊。

呃,咱们run一下吧。

心里瞬间万头草泥马在奔腾啊

别急!

听老衲慢慢道来

在此之前,先复习一下&&和||运算符,

&&就是两个表达式为真最终结果才为真,

||是两个中只要有一个为真那么结果就为真。

于是乎,关于a++&&++a.

由于a初始为0,a++后自增,先把值拿来用了在让a+1。

所以整个表达式可以看作是0&&2,

但是编译器坑爹啊,他读到0,然后发现,这是一个&&操作。

有一个都是假了那最后结果肯定也是假的,

没必要做后面的运算了。

所以,++a那一句编译器并不会再去理会,

最终的结果是,a只自增了一次。

对于||操作,道理也是一样的。

当他发现||左边的表达式为真(非0)时,

后面的编译器不在理会。这点大家记住。

3

当switch没有了break

switch case语句是一个很神奇的东西,

我也是近来才了解原来他还有这种操作。

在写switch case语句的时候,

我们被要求每一条语句都写上break。

但是实际开发中,

往往会有那么几个人由于疏漏忘了写break子句导致莫名的结果错误。

下面我们来看看没有了break的

switch语句

是有多风骚

嗯,这次就不再用++来玩大家了

运行结果:

之前我一直以为,就算没有break

后面的语句也只会在符合条件的情况下

才会执行。

然而,是我想错了。

上网查了一下,switch语句设计的初衷

就有着一种贯穿的思想

说白了 就是,符合某个case分支以后

如果没有break

那么后面的case 子句无论如何都会执行

所以,你如果只想执行一个条件

别忘了在每个分支后面写上break

4

关于声明和定义,你知多少

下面代码是在C平台上运行的。C++不允许这么干了。

那么,你觉得下面的代码C编译器会报错吗?

答案是不会!

再看:这个会报错吗?

答案,YES!

这就很扎心了,两段代码,位置不一样,还出错了???

嗯,这里就要讲讲声明和定义的区别了。

第一个程序int a是写在全局变量区的,

那么对于全局变量,

声明+赋值=定义

也就是之前无论我们int a多少次

只要没有赋值,

那么编译器就会默认我们这是一条声明。

声明嘛,你想声明多少次都行。

如果都是声明没有赋值,那么编译器就会默认

最后一条声明为定义。

说白了就是,

声明可以有多个,但是定义只能有一个

而第二个程序就不同了,

由于int a 是写在局部变量区域,

对于局部变量来说,无论是否赋值都是定义

所以这里编译器会给出一个重定义的CE。

5

static原来是这样

关于static可以说的实在太多了,但是今天只说一点。

也是各位新手朋友经常犯的。

先看代码:

可以预测一下输出结果嘛

将变量声明为static以后,

该变量会放在全局静态区。

那么这个区域的变量有几个特点

会在程序刚开始运行时就完成初始化,

也是唯一的一次初始化

如果没有初始化,编译器默认初始化为0

于是乎,由于上述程序num只初始化了一次,

所以在后面的9次test()函数的调用中,

static int num = 10

这条语句不会在执行。

因此才会有上面的输出的输出结果

6

printf继续风骚型

关于printf的输出,也是面试官们经常拿来玩的一个埂,通过这个可以看出你对基础知识的把握程度。

先看代码:

输出多少?

看结果:

为什么会出现这个情况呢?

这是因为,printf输出的时候,

并不会去判断变量的类型,

他很听话,只会按照你给的格式控制符去内存中解析数据然后输出

比如整数在内存中是以补码的形式存在的。

(关于源码补码知识不在赘述,读者可自行上网了解)

-1的补码就是32个1。

那么32个1,按照有符号整数来解析就是-1

按照无符号来解析就是上面的结果。等等。

今天就先写到这吧,C/C++还有很多值得大家注意的地方,比如C的宏函数带来的运算级问题,结构体对齐等等,const和指针引发的一系列血案等等。咱们下次有空再聊。

END

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿声 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档