网易首页 > 网易号 > 正文 申请入驻

【蓝因子教育】C语言的组成结构(基础完整篇)!

0
分享至

C是一种具有模块化设计的命令式编程语言,具有简约、直观的设计风格,与相对清晰、简单的语言结构。

在谈C的语言结构之前,需要先解释一些基本元素的含义。

一、表达式

表达式是一个或多个变量、常量、函数与运算符按照特定规则的组合,表达式根据特定的优先级与运算符进行计算并返回一个值。

注意:单个变量、常量或函数名也是一个表达式。

以下面表达式为例:

var = fn(1) + 5

其中var、fn、1、5都是表达式,其返回值为自身的值;fn(1)也是一个表达式,返回函数调用的返回值;fn(1) + 5也是一个表达式,返回算术运算的结果;var = fn(1) + 5也是一个表达式,返回赋值号左边的值,此例中此值被丢弃。

特别地,调用返回值为void类型的函数将返回一个void类型的值,但此值无法被使用,只能丢弃。

1、完整表达式

如果一个表达式不是其他表达式的子表达式,则称这个表达式为“完整表达式”。

以下面几个语句为例:

var = 1 + 2;

fn(var + 1);

if (var + 1) ;

✪ 表达式语句中的整个表达式为完整表达式,如上面的var = 1 + 2和fn(var + 1),但第二行的var + 1不属于完整表达式。(函数调用实际上是运算符()对函数指针和参数进行运算)

✪ if、while、switch括号中的表达式以及for括号中的每个分量都是完整表达式,所以第三行的var + 1是完整表达式。

二、副作用

除了返回值以外对程序造成的其他影响称为副作用。比如修改变量的值,执行I/O操作等。

对于如下表达式:

var = 5

表达式的返回值为5,副作用为将5赋值给变量var。

而对于以下表达式:

1 + 2

表达式返回3,没有副作用。

通常说起“副作用”,总是觉得无关紧要或尽量避免,但对于命令式编程语言来说,副作用才是程序执行的主要目的。

比如我们调用printf函数,我们通常并不关心它的返回值,而是需要它把特定的字符输出到屏幕,而标准输出正是这个函数的副作用。

三、语句

语句是C的基本执行单元,语句不返回结果,仅执行副作用。语句可分为简单语句和复合语句。

在C语言中,“;”不是分隔符(for语句中的“;”除外),而是大部分语句的结尾。

申明不属于语句,因为申明通常不产生副作用,即使有时候会产生副作用(如初始化),但仍不将其视为语句,申明也以“;”结尾。

C有5种语句:

✪ 表达式语句

✪ 跳转语句

✪ 选择语句

✪ 循环语句

✪ 标签语句

1、简单语句和复合语句

简单语句指内部不包含其他语句的语句。如表达式语句和跳转语句。最简单的语句是只有一个“;”的空语句。

复合语句的定义与简单语句相反,即其内部有其他语句。

将几个语句用{}括起来就形成了复合语句“块”,最简单的复合语句是空块{}

复合语句可以进行多次复合,比如块可以嵌套,复合语句的子语句可以是其他复合语句。

C语言没有else if关键字,这种语法结构只是将上一个if语句的else部分复合了另一个if语句,将他们写在一起是为了使代码更简洁。

2、表达式语句

表达式语句为一个完整表达式后跟一个分号构成的语句。若表达式为空,就构成了空语句。

表达式语句是最简单也是最常见的语句。以下语句都是表达式语句:

;
1 + 2;
var = 5;
printf("hello, world\n");

3、跳转语句

跳转语句用于改变代码的执行顺序。跳转语句包括continue、break、return、goto语句。

4、选择语句

选择语句是复合语句,其作用是根据特定表达式的值对程序执行进行跳转。如if、if else、switch语句。

5、循环语句

循环语句是复合语句,其作用是根据特定表达式的值让一部分代码反复执行多次,如while、dowhile、for语句。循环语句也可以通过选择语句和跳转语句实现。

6、标签语句

在其他语句前加上标签即是标签语句。标签语句是复合语句,可以在任何语句(包括标签语句)前添加标签。

因为申明不是语句,所以不能在申明前添加标签。对于下面的代码,gcc给出如下错误提示:

lable:

int var = 0;

error: a label can only be part of a statement and a declaration is not a statement

case 标签是一种特殊的标签,其标志是在标签前的case关键字。case标签只能在switch语句中使用,case标签允许且只允许标签名使用整数,并且把标签的作用域限定在当前的switch语句中。

标签是语句的一部分,而不只是个记号,所以块末尾不能是标签。

比如下面语句:

switch (var) {
case 1:
case 2:
case 3:
;
}

最后的分号是不可以省略的,空语句复合case 3标签形成标签语句,然后又复合case 1和case 2,所以这个块内只有一条完整的复合语句。

四、C语言结构

C语言代码文件包括源文件和头文件,源文件可以进行编译和链接,头文件一般通过预处理指令包含到源文件中使用。

源文件由预处理指令、申明、类型定义、函数定义和注释组成。

预处理指令和注释可以出现在源文件的任何位置而不影响其功能,而申明和类型定义的位置决定了其作用域。

申明有时会伴随定义,定义一定会包含申明。

函数定义由返回值类型、函数名、参数列表和语句块组成。语句只能出现在函数定义内部。

C源文件必须有且只能有一个main函数,C89规定,main函数的返回值必须为int类型,如果程序正常终止,应返回0。

标准的main函数应写为 int main(void); 或 int main(int argc, char const *argv[]); 。

五、序列点

C语言通过序列点控制副作用的执行。在该点处之前的求值的所有的副作用已经发生,在它之后的求值的所有副作用仍未开始。

序列点的存在一定程度上保证了程序按照预期执行,但仍存在一些未定义的行为。

C中的序列点很少,因为C追求效率,更少的序列点可以给编译器更多优化的空间。

注意:C中有很多符号同时承担多种功能,在不同语境下扮演不同的身份。

C的序列点包括:

1、&& 与 || 运算符

&&||运算符会先对左边的表达式求值并执行副作用。

&& 运算符来说,只有当左边表达式的值为1时才对右边的表达式求值并执行副作用。

这是对程序的一种优化,因为根据“与”逻辑,如果左边表达式的值为0,则总表达式的值定为0,无需对右边表达式进行计算。根据这一特性,可以写出更加符合人类逻辑的代码。

if (var != 0 && 3 == 100 / var) {}

如果没有此序列点,则可能会出现0做除数的错误。

|| 运算符同理,只有当左边表达式的值为0时才对右边的表达式求值并执行副作用。

2、逗号运算符

“,”在C语言中有很多用途,在某些地方它是分隔符,在某些地方它是运算符。比如以下表达式:

var = 1, var = 2

这里的“,”不是分隔符,而是运算符。此逗号运算符的两边是两个赋值表达式,逗号表达式先对左边的表达式求值并执行副作用,此时var的值被修改为1,之后对右边的表达式求值并执行副作用,var的值被修改为2,最后,逗号表达式返回右边表达式的值,即2。

逗号表达式的特性可以使两个表达式像两个表达式语句那样执行,适合用在需要用表达式代替语句块的地方,如for语句的括号内。

3、三元运算符 ? : 中的 ?

?前的表达式求值并执行副作用后,才判断返回其后哪个表达式的值。并且,如果确定返回某个表达式的值,则不会对另一个表达式求值或执行副作用。

? :表达式的这个特性使其行为与if else表现一致。

4、完整表达式的末尾

完整表达式的末尾也是一个序列点,这保证了表达式语句的副作用按照其书写顺序执行。

同时,根据前面对完整表达式的定义,if、while、switch括号中的表达式以及for括号中的每个分量都是完整表达式,这些表达式的副作用也都会在语句其他部分开始前执行。

5、函数调用与返回

函数调用时参数列表中的逗号不是表达式,而是分隔符。

参数列表的求值顺序是未定义的,比如fn(a++, b--),a++和b--的求值顺序是未知的,取决于编译器。

此处的序列点表现为在进入函数前,所有表达式的副作用都已经完成;函数返回时,返回值已经拷贝到调用处。

6、初始化末尾

因为初始化是申明的一部分,不属于语句或表达式,所以不能套用表达式的说法,但其表现是类似的。

如下申明:

int var = 5;

在分号前已经完成副作用,即把var初始化为5。

7、初始化列表中的逗号分隔符

初始化列表中的逗号是分隔符而不是运算符。

初始化列表中的表达式按照从左到右的顺序求值并执行副作用。

如下代码:

int var = 0;
int array[] = { var++, var++, var++ };

8、申明中的逗号分隔符

申明中的逗号是分隔符而不是运算符。

如下代码:

int a = 0;
int b = a++, c = a++;

b、c分别被初始化为0、1。

而且,在逗号前的变量已经申明完成,逗号后的则不然。

如下代码:

int a = 0, b = a; //Correct
int c = d, d = 0; //Error

在申明b前,a已经申明并初始化完成,所以可以用a初始化b。而在申明c时还没有申明d,所以初始化会报错。

因为缺少序列点,C会产生很多未定义的行为。最典型的例子是:

int var = 0;
var = var++;

根据优先级,表达式var = var++的值是确定的,然而赋值和自增副作用的执行顺序是未定义的,所以var的值是未知的。如果用gcc编译这段代码,var的值为0,比较符合预期;但在VC++中,var的值为1。

所以我们应避免在表达式中同时使用某一变量和它的自增表达式。



特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
勇士99-102快船!可怕的不是丢西部第一,库里赛后表态该引起重视

勇士99-102快船!可怕的不是丢西部第一,库里赛后表态该引起重视

鱼崖大话篮球
2024-11-19 17:12:02
讽刺至极,有时候真的很无助 !

讽刺至极,有时候真的很无助 !

娱乐圈见解说
2024-11-19 19:52:49
余承东首秀华为 Mate 70 Pro+ 真机外观,“金丝银锦”配色亮相

余承东首秀华为 Mate 70 Pro+ 真机外观,“金丝银锦”配色亮相

IT之家
2024-11-19 18:18:10
原来真有孩子大了不避嫌的家庭啊!网友:何止炸裂简直就是炸裂

原来真有孩子大了不避嫌的家庭啊!网友:何止炸裂简直就是炸裂

美好客栈大掌柜
2024-11-15 00:20:03
看了范丞丞,再看王安宇,真是没对比就没伤害 ,正午“口碑”保住

看了范丞丞,再看王安宇,真是没对比就没伤害 ,正午“口碑”保住

圈里的甜橙子
2024-11-19 18:20:13
国足1-3日本!不是林良铭!不是谢文能!中国队10号全场评分最高

国足1-3日本!不是林良铭!不是谢文能!中国队10号全场评分最高

詹妹侃体育
2024-11-19 23:29:15
上课给爱说话的学生戴“小蜜蜂” 当事老师发视频称已离职

上课给爱说话的学生戴“小蜜蜂” 当事老师发视频称已离职

闪电新闻
2024-11-18 12:28:59
外交部:坚决反对个别西方国家干涉中国内政

外交部:坚决反对个别西方国家干涉中国内政

财联社
2024-11-19 15:38:35
官方通报良品铺子被举报问题不成立 公司:将提起诉讼

官方通报良品铺子被举报问题不成立 公司:将提起诉讼

中新经纬
2024-11-19 08:35:20
留给蒙古的时间不多了,中俄管道完工,全程未经过蒙古境内

留给蒙古的时间不多了,中俄管道完工,全程未经过蒙古境内

智凌纵横
2024-11-19 19:48:28
为啥现在老鼠越来越少,他们都跑哪儿去了呢?看完你就知道了。

为啥现在老鼠越来越少,他们都跑哪儿去了呢?看完你就知道了。

粤语音乐喷泉
2024-11-19 14:03:01
港片第一性感美人,168cm身材黄金腰臀比,退圈后相夫教子很幸福

港片第一性感美人,168cm身材黄金腰臀比,退圈后相夫教子很幸福

探寻者
2024-11-19 16:48:47
华为Mate70已到店 现货供应无溢价数量有限先到先得

华为Mate70已到店 现货供应无溢价数量有限先到先得

PConline太平洋科技
2024-11-19 11:13:08
成都网民:交通信号灯设置不科学是造堵的重要原因

成都网民:交通信号灯设置不科学是造堵的重要原因

古装影视解说阿凶
2024-11-19 21:33:18
从《三生三世十里桃花》到《永夜星河》,他越来越糊,差点没认出

从《三生三世十里桃花》到《永夜星河》,他越来越糊,差点没认出

娱乐的小灶
2024-11-19 16:32:25
金鸡奖这一夜,不尊重刘德华礼节的陈凯歌,不再被网友宽容了

金鸡奖这一夜,不尊重刘德华礼节的陈凯歌,不再被网友宽容了

喵喵娱乐团
2024-11-18 17:07:15
最牛券商大妖股,跌崩了?

最牛券商大妖股,跌崩了?

财经锐眼
2024-11-19 17:46:31
李娜:网球不是我喜欢的项目;希望现在的球员能为自己打网球

李娜:网球不是我喜欢的项目;希望现在的球员能为自己打网球

懂球帝
2024-11-19 15:32:15
荷兰博主北京转机时逛故宫迷路,称在韩国玩三周不如在中国玩两天

荷兰博主北京转机时逛故宫迷路,称在韩国玩三周不如在中国玩两天

简读视觉
2024-11-18 21:43:28
欧洲不要中国要!中俄能源管道已完工,4亿人将用上俄罗斯天然气

欧洲不要中国要!中俄能源管道已完工,4亿人将用上俄罗斯天然气

现代春秋
2024-11-18 21:47:15
2024-11-20 00:24:49
原画在线课堂vv
原画在线课堂vv
一家有温度的原画教育机构
1123文章数 1关注度
往期回顾 全部

科技要闻

小鹏Q3营收破百亿,交付4.7万辆,亏18.1亿

头条要闻

国足1比3不敌日本 征战18强赛的最大顽疾被对手再利用

头条要闻

国足1比3不敌日本 征战18强赛的最大顽疾被对手再利用

体育要闻

15胜0负的骑士,真的在模仿勇士

娱乐要闻

金鸡奖颁奖,流量至上,都在座位表上体现了

财经要闻

专家称我国还缺1亿套保障房

汽车要闻

后排够大 智能化提升 全新探岳L是你的菜么?

态度原创

本地
房产
艺术
时尚
公开课

本地新闻

重庆记忆|山城特色“过山车”上天入地穿花海

房产要闻

重磅!海南取消限购第8城来了!楼市限购,还剩10城

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

50岁贝嫂:生孩子不会变老,穷和不自律才会

公开课

一块玻璃,如何改变人类世界?

无障碍浏览 进入关怀版