FEATURED · 精选文章

C语言语句、语句分类及注释

发布时间 / 2026/8/14 6:17:09
来源 / 创域科博编辑部
栏目 / 资讯中心
C语言语句、语句分类及注释 文章目录一、语句和语句分类二、注释注释是什么为什么写注释1. /**/的形式2. //的形式3. 注释会被替换三、随机数的生成1. rand函数2. srand函数3. time函数4. 设置随机数的范围四、C99中的变长数组五、问题表达式解析表达式1表达式2表达式3表达式4表达式5六、位段补充一、语句和语句分类C语言的代码是由一条一条的语句构成的C语言中的语句可为以下五类空语句表达式语句函数调用语句复合语句控制语句(1) 空语句空语句是最简单的语句一个分号就是一条语句即空语句。#includestdio.hintmain(){;//空语句return0;}空语句一般出现的地方是这里需要一条语句但是这条语句不需要做任何事就可以写一个空语句。(2) 表达式语句表达式语句就是在表达式的后边加上分号。如下所示#includestdio.hintmain(){inta20;intb0;ba5;//表达式语句return0;}(3) 函数调用语句函数调用的时候也会加上分号就是函数调用语句。#includestdio.hintAdd(intx,inty){returnxy;}intmain(){printf(hehe\n);//函数调用语句intretAdd(2,3);//函数调用语句return0;}(4) 复合语句成对括号中的代码就构成一个代码块也被称为复合语句。#includestdio.hvoidprint(intarr[],intsz)//函数的大括号中的代码也构成复合语句{inti0;for(i0;isz;i){printf(%d ,arr[i]);}}intmain(){inti0;intarr[10]{0};for(i0;i10;i)//for循环的循环体的大括号中的就是复合语句{arr[i]10-i;printf(%d\n,arr[i]);}return0;}(5) 控制语句控制语句用于控制程序的执行流程以实现程序的各种结构方式(C语言支持三种结构顺序结构、选择结构、循环结构)它们由特定的语句定义符组成C语言有九种控制语句。可分成以下三类:1.条件判断语句也叫分支语句if语句、switch语句;2.循环执行语句do while语句、while语句、for语句;3.转向语句break语句、goto语句、continue语句、return语句。二、注释注释是什么为什么写注释●注释是对代码的说明编译器会忽略注释也就是说注释对实际代码没有影响。●注释是给程序员自己或者其他程序员看的。●好的注释可以帮我们更好的理解代码但是也不要过度注释不要写没必要的注释。●当然不写注释可能会让后期阅读代码的人抓狂。写注释一定程度上反应了程序员的素质建议大家写必要的注释在未来找工作的时候写代码时留下必要的注释也会给面试官留下更好的印象。C 语言的注释有两种表示方法。1. /**/的形式第一种写法是将注释放在/*…*/之间内部可以分行。⚾形式1/* 注释 */形式2/*这是一行注释*/这种注释可以插在一行内部。int fopen(char* s/* file name */, int mode);上面示例中/*file name*/用来对函数参数进行说明跟在它后面的代码依然会有效执行。这种注释一定不能忘记写结束符号*/否则很容易导致错误。例如上面示例的原意是第五行和第七行代码的尾部有两个注释。但是第一行注释忘记写结束符号*/导致注释一延续到第三行才结束。/**/ 这种注释不支持嵌套注释从/*开始注释后遇到第一个 */ 就认为注释结束了。2. //的形式第二种写法是将注释放在双斜杠//后面从双斜杠到行尾都属于注释。这种注释只能是单行可以放在行首也可以放在一行语句的结尾。这是C99标准新增的语法。形式1//这是一行注释形式2int x 1; //这也是注释不管是哪一种注释都不能放在双引号里面。放在双引号里面的注释符号会成为字符串的一部分会被解析成普通符号失去注释作用。#includestdio.hintmain(){printf(//hello /* world */ );return0;}程序运行结果上面示例中双引号里面的注释符号都会被视为普通字符没有注释作用。3. 注释会被替换编译时, 注释会被替换成一个空格, 所以 min/*这里是注释*/Value 会变成 min Value ,而不是minValue。三、随机数的生成1. rand函数C语言提供了一个函数叫rand这个函数可以生成随机数函数原型如下intrand(void);rand函数会返回一个伪随机数这个随机数的范围是在0~RAND_MAX之间这个RAND_MAX的大小是依赖编译器实现的但是在大部分编译器上是32767。rand函数的使用需要包含一个头文件是stdlib.h测试一下rand函数这里多调用几次产生5个随机数#includestdio.h#includestdlib.hintmain(){printf(%d\n,rand());printf(%d\n,rand());printf(%d\n,rand());printf(%d\n,rand());printf(%d\n,rand());return0;}程序运行结果我们先运行一次看看结果然后再运行一次多运行次呢?可以看到虽然一次运行中产生的5个随机数是相对随机的但是下一次运行程序生成的结果和上一次一模一样这就说明有问题。如果深入了解一下就不难发现其实rand函数生成的随机数是伪随机的伪随机数不是真正的随机数是通过某种算法生成的随机数。真正的随机数的是无法预测下一个值是多少的。而rand函数是对一个叫“种子”的基准值进行运算生成的随机数。之所以前面每次运行程序产生的随机数序列是一样的就是因为rand函数生成随机数的默认种子是1。如果要生成不同的随机数就要让种子是变化的。2. srand函数C语言中又提供了一个函数叫srand是用来初始化随机数的生成器srand的原型如下voidsrand(unsigned int seed);程序中在调用 rand 函数之前先调用 srand 函数通过 srand 函数的参数seed来设置rand函数生成随机数时候的种子只要种子在变化每次生成的随机数序列也就变化起来了。也就是说给srand的种子如果是随机的那rand就能生成随机数在生成随机数的时候又需要一个随机数(种子)这咋办呢看下面3. time函数在程序中我们一般使用程序运行的时间作为种子因为时间是时刻在变化的。在C语言中有一个函数叫 time就可以获得这个时间time函数原型如下time_ttime (time_t* timer);time 函数会返回当前的日历时间其实返回的是1970年1月1日0时0分0秒到现在程序运行时间之间的差值单位是秒。返回的类型是time_ttime_t类型本质上就是32位或者64位的整型类型。time函数的参数 timer 如果是非NULL指针的话函数也会将这个返回的差值放在timer指向的内存中带回去。如果 timer 是NULL就只返回这个时间的差值。time函数返回的这个时间差也被叫做时间戳。time函数的使用需要包含头文件time.h如果只是让time函数返回时间戳我们就可以这样写time(NULL); //调用time函数返回时间戳这里没有接收返回值那就可以让生成随机数的代码改写成如下#includestdio.h#includestdlib.h#includetime.hintmain(){//使用time函数的返回值设置种⼦//因为srand的参数是unsigned int类型我们将time函数的返回值强制类型转换srand((unsignedint)time(NULL));printf(%d\n,rand());printf(%d\n,rand());printf(%d\n,rand());printf(%d\n,rand());printf(%d\n,rand());return0;}程序运行结果(注截图只是当时程序运行的结果你的运行结果不一定和这个一样)srand函数是不需要频繁调用的在一次运行的程序中调用一次就够了。4. 设置随机数的范围如果我们要生成0~99之间的随机数方法如下rand() % 100; //余数的范围是0~99如果要生成1~100之间的随机数方法如下rand()%1001; //%100得到的余数是在0~99之间(包括0和99),0~99的数字1,范围就是1~100如果要生成100~200的随机数方法如下100 rand()%(200-1001); //余数的范围是0~100加100后就是100~200所以如果要生成a~b的随机数方法如下a rand()%(b-a1)四、C99中的变长数组在C99标准之前C语言在创建数组的时候数组大小的指定只能使用常量、常量表达式或者如果我们初始化数组的话可以省略数组大小。int arr1[10];int arr2[35];int arr3[ ] {1,2,3,4,5};省略数组大小这种情况虽然[ ]中没指定元素个数但是编译器会根据你后面初始化元素的多少来确定数组的大小。这样的语法限制让我们创建数组就不够灵活有时数组大了浪费空间有时数组小了又不够用。C99中给了一个变长数组(variable-length array简称VLA)的新特性允许我们可以使用变量指定数组的大小。int n ab;int arr[n];上面示例中数组 arr 就是变长数组因为它的长度取决于变量n的值编译器没法事先确定只有运行时才能知道 n 是多少。变长数组的根本特征就是数组长度只有运行时才能确定所以变长数组不能初始化。它的好处是程序员不必在开发时随意为数组指定一个估计的长度程序可以在运行时为数组分配精确的长度。有一个比较迷惑的点变长数组的意思是数组的大小是可以使用变量来指定的在程序运行的时候根据变量的大小来指定数组的元素个数而不是说数组的大小是可变的。数组的大小一旦确定就不能再变化了。遗憾的是在VS2022上虽然支持大部分C99的语法但没有支持C99中的变长数组语法没法测试但可以在gcc编译器上测试下面的代码#includestdio.hintmain(){intn0;scanf(%d,n);//根据输入的数值确定数组的大小intarr[n];inti0;for(i0;in;i){scanf(%d,arr[i]);}for(i0;in;i){printf(%d ,arr[i]);}return0;}五、问题表达式解析表达式1我们都知道通过运算符优先级可以知道一个表达式优先级高的部分要比优先级低的先执行。但不能知道有相同优先级的几个部分会不会同时执行还是有先后顺序比如//表达式的求值部分由操作符的优先级决定。//表达式1a*b c*d e*f表达式1在计算的时候由于*比的优先级高只能保证*的计算比的早但是优先级并不能决定第三个 * 比第一个 早执行。所以表达式的计算机顺序就可能是1 a*b2 c*d3 a*b c*d4 e*f5 a*b c*d e*f或者1 a*b2 c*d3 e*f4 a*b c*d5 a*b c*d e*f表达式2//表达式2c --c;同上操作符的优先级只能决定自减 – 的运算在 运算的前面但是我们并没有办法得知 操作符的左操作数的获取(使用)在右操作数之前还是之后求值所以结果是不可预测的是有歧义的。表达式3#includestdio.h//表达式3intmain(){inti10;ii-----i*(i-3)*ii;printf(i %d\n,i);return0;}表达式3在不同编译器中的测试结果(非法表达式程序的结果)上面的表达式在VS2022中的运行结果为表达式4#includestdio.hintfun(){staticintcount1;returncount;}intmain(){intanswer;answerfun()-fun()*fun();printf(%d\n,answer);//输出多少return0;}程序运行结果虽然在大多数的编译器上求得的结果都是相同的。但是上述代码 answer fun() - fun() * fun(); 中我们只能通过操作符的优先级得知先算乘法再算减法。但三个fun函数的调用先后顺序却无法通过操作符的优先级确定不一定就是按从左到右的顺序调用。表达式5#includestdio.hintmain(){inti1;intret(i)(i)(i);printf(%d\n,ret);printf(%d\n,i);return0;}VS2022的运行结果但如果你在gcc中运行上面的代码得到的结果就和上面VS的结果有差异。看看同样的代码产生了不同的结果这是为什么? 简单看一下汇编代码就可以分析清楚这段代码中的第一个 在执行的时候第三个是否执行这个是不确定的因为依靠操作符的优先级和结合性是无法决定第一个和第三个前置 的先后顺序的。总结即使有了操作符的优先级和结合性我们写出的表达式依然有可能不能通过操作符的属性唯一确定表达式的计算路径那这个表达式就是存在潜在风险的建议大家不要写出特别复杂的表达式。六、位段补充在位段中位段的成员必须是int、unsigned int或者signed int(包括char类型, char也属于整型家族)。上面的意思是如果使用位段那这个结构体中的成员一般是同类型的。比如structS{int_a:2;int_b:5;int_c:10;int_d:30;};structS{char_a:3;char_b:4;char_c:5;char_d:4;};特别是位段成员如果出现在表达式中则会进行整型提升自动转换为int类型或者unsigned int类型。在C语言中位段是用来节省内存空间的。内存分配是遵循以下规则的1.成员大小限制位段中的成员大小不能超过机器定义的类型大小。例如int类型在大多数平台上是32位因此位段中的成员大小(bit位数)不能超过32位。2.内存对齐位段的内存对齐是基于其中成员的最大类型来确定的。如果一个位段中包含多个成员且这些成员的类型大小不同则内存对齐将基于最大的成员类型。3.内存分配位段通常不直接分配内存而是作为结构体的一部分。结构体在内存中的分配遵循常规的内存分配规则即通过 malloc 函数分配内存并由程序员使用free函数释放内存。位段中是可以有不同的类型成员的但如果位段的成员有不同类型的话那位段大小的计算就比较复杂。建议位段成员都以相同类型出现。(只要是整型家族即可)
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻