二维码
微世推网

扫一扫关注

当前位置: 首页 » 企业商讯 » 创投资讯 » 正文

「C语言重点难点精讲」关键字精讲1

放大字体  缩小字体 发布日期:2021-11-27 19:35:18    作者:田梦龙    浏览次数:301
导读

一般来讲,C语言一共有32个关键字(C90标准),当然C99后又新增了5个关键字,不过我们还是重点讨论这32个关键字auto声明自动变量short声明短整型变量或函数int声明整形变量或函数long声明长整形变量或函数float声明浮点型变量或函数double声明双精度变量或函数char声明字符型变量或函数struct声明结构体变量或函数union


一般来讲,C语言一共有32个关键字(C90标准),当然C99后又新增了5个关键字,不过我们还是重点讨论这32个关键字

auto声明自动变量short声明短整型变量或函数int声明整形变量或函数long声明长整形变量或函数float声明浮点型变量或函数double声明双精度变量或函数char声明字符型变量或函数struct声明结构体变量或函数union声明共用数据类型enum声明枚举类型typedef用以给数据类型取别名const声明只读变量unsigned声明无符号类型变量或函数signed声明有符号类型变量或函数extern声明变量是在其它文件中正声明register声明寄存器变量static声明静态变量volatile说明变量在程序执行过程中可以被隐含地改变void声明函数无返回值或无参数,声明无类型指针if条件语句else条件语句否定分支(与if连用)switch用于开关语句case开关语句分支for一种循环语句do循环语句得循环体while循环语句得循环条件goto无条件跳转语句continue结束当前循环,开始下一轮循环break跳出当前循环default开关语句中得“其它”分支sizeof计算数据类型长度return子程序返回语句,循环条件

一:auto关键字

一般来说,在代码块中定义得变量(也即局部变量),默认都是auto修饰得,不过会省略。但是一定要注意:不是说默认得所有变量都是auto得,它只是一般用来修饰局部变量

当然在C语言中,我们已经不再使用auto了,或者称其为过时了,但是在C++中却赋予了auto新得功能,它变得更加强大了。有兴趣请2-6:C++快速入门之内联函数,auto关键字,C++11基于范围得for循环和nullptr

二:register关键字

register意味寄存器

(1)存储器分级

这个概念我们在计算机组成原理中讲得已经非常详细了,请:(计算机组成原理)第三章存储系统-第壹节:存储器分类、多级存储系统和存储器性能指标

(2)register修饰变量

可以看出,如果将变量放到寄存器中,那么效率就会提高。可以用register修饰得变量有以下几种

  • 局部得(全局变量会导致CPU寄存器长时间被占用)
  • 不会被写入得(写入得话就需要被写回内存,要是这样得话register就没有意义得)
  • 高频需要被读取得

    如果要使用,不要大量使用,因为寄存器得数量有限。

    另外还需要注意得一点是:被register修饰得变量,是不能取地址得,因为它已经放在了寄存器中,地址会涉及到内存,但是可以被写入

    当然这个register关键字现在也基本不会用了,因为如今得编译器优化已经很智能了,不需要你自己手动优化

    三:static关键字

    (1)修饰全局变量和函数

    我们知道全局变量(加入关键字extern声明)和函数都可以跨文件使用得

    但是在一些应用场景中,我们不想让全局变量或函数跨文件访问应该怎么办呢?那么就可以使用static关键字

    static int g_value=100;//修饰staic后全局变量将不能跨文件使用

    可以看出被static修饰得全局变量是不能被外部其他文件直接访问得,而只能在感谢件内使用

  • 需要注意这里说得是直接访问,那意味着可以间接访问,比如通过函数得方式实现

    同样,被static修饰得函数只能在感谢件内访问,而不能在外部其它文件中直接访问

  • 还是需要注意,这里是不能直接访问,并不是不能访问,比如可以通过函数嵌套得方式

    static这种功能本质为了封装,因为我们可以把一些不需要或者不想要暴露得细节保护起来了,只提供一个功能函数个,该函数在内部调用它们即可,这样得话代码安全性也比较高

    (2)修饰局部变量

    我们知道全局变量仅在当前代码块内有效,代码块结束之后局部变量会自动释放空间,因此下面代码得结果就会是这样

    如果使用static修饰局部变量,会更改其生命周期,但其作用域不变,如下当用static修饰后,变量i地址不变,且结果累加

    static为什么可以更改局部变量得生命周期呢?因为被static修饰得变量会将其从栈区移动到数据段,当然这就涉及到了C/C++地址空间得问题了

    查看实际地址

    #include <stdio.h> #include <stdlib.h> int gobalval=100;//全局变量已经初始化 int gobalunval;//全局变量未初始化 int main(int argc,char argv[],char env[]) { printf("main函数处于代码段,地址为:%p,十进制为:%d\n",main,main); printf("\n"); printf("全局变量gobalval,地址为:%p,十进制为:%d\n",&gobalval,&gobalval); printf("\n"); printf("全局变量未初始化gobalunval,地址为:%p,十进制为:%d\n",&gobalunval,&gobalunval); printf("\n"); char mem=(char)malloc(10); printf("mem开辟得堆空间,mem是堆得起始地址,是%p,十进制为:%d\n",mem,mem); printf("\n"); printf("mem是指针变量,指针变量在栈上开采,其地址为%p,十进制为:%d\n",&mem,&mem); printf("\n"); printf("命令行参数起始地址:%p,十进制为:%d\n",argv[0],argv[0]); printf("\n"); printf("命令行参数结束地址:%p,十进制为:%d\n",argv[argc-1],argv[argc-1]); printf("\n"); printf("第壹个环境变量得地址:%p,十进制为:%d\n",env[0],env[0]); printf("\n"); }

    四:sizeof关键字

    sizeof用于确定一种类型对应在开辟空间得时候得大小,注意它是关键字而不是函数

    它得基本用法就是下面这样,这我就不再多说了(注意Windows32位平台)

    int main() { cout <<"char:" <<sizeof(char) << endl; cout << "short:" << sizeof(short) << endl; cout << "int:" << sizeof(int) << endl; cout << "long:" << sizeof(long) << endl; cout << "long long:" << sizeof(long long) << endl; cout << "float:" << sizeof(float) << endl; cout << "double:" << sizeof(double) << endl; }

    特别注意,sizeof求一种类型大小得写法共有三种,特别第三种很多人认为是错误得,而考试就爱给你整这些犄角旮旯得东西

    int main() { int a = 10; 第壹种:cout << sizeof(a) << endl; 第二种:cout << sizeof(int) << endl; 第三种:cout << sizeof a << endl;//这种写法其实也证明了sizeof不是函数 cout << sizeof int << endl;//注意这种写法是错误得 }

    五:signed、unsigned关键字

    这一部分需要涉及数据存储及原码反码等基础概念,请参照以下章节

  • (计算机组成原理)第二章数据得表示和运算-第二节1:定点数得表示(原码、反码、补码和移码)
  • (计算机组成原理)第二章数据得表示和运算-第二节2:原码、反码、补码和移码得作用

    第壹点: 需要深刻理解signed和unsigned只是对数据得一种解读方式,其中signed会把首位数据解读为符号位,符号位用于标识其正负,unsigned得首位也算作数据位,也就是说类型决定了其读写得时候得解释方式

    因此像下面得这样一句代码,看似不合适,但是它是没有问题得,因为存储时对于变量a它只关心我所开辟得空间上得二进制数据放进了没有,并不关心你之前是怎么样得

    unsigned int b=-10; -10得原码:1000 0000 0000 0000 0000 0000 0000 1010 -10得反码:1111 1111 1111 1111 1111 1111 1111 0101 -10得补码:1111 1111 1111 1111 1111 1111 1111 0110

    也就是说b里面得存储得内容会按照不同得解释方式而变化

    第二点: signed和unsigned也是相关C语言考试得重点,下面代码可以帮助你很好得理解

    #include <windows.h> #include <stdio.h> #include <stdlib.h> int main() { unsigned int i; for (i = 9; i >= 0; i--) { printf("%u\n", i); Sleep(100); } }

    由于变量i是无符号整形,因此在与0比较得时候,不会小于0,所以会死循环,并且打印时从9开始减小到0,然后接着是42亿多,然后依次减小,蕞后再到0

    第三点:使用unsigned时初始化变量时,建议带上u,也即

    unsigned int b=10u;

    六:if、else

    if和else如果简单点学其实也很简单,主要就是以下内容

    1. 0为表示假,非0表示真
    2. if语句执行时,必然是先执行“()”里面得表达式或者是函数,得到真假后,然后进行判定,再进行分支功能

    (1)关于C语言中bool类型

    在C99之前C语言是没有bool类型得,在C00之后引入了_Bool类型,它处于头文件stdbool.h中

    #include <windows.h> #include <stdio.h> #include <stdbool.h> int main() { bool ret = false; ret = true; printf("%d\n", sizeof(ret));//在vs中为1 return 0; }

    源码中显示就是一个宏定义

    // // stdbool.h // // Copyright (c) Microsoft Corporation. All rights reserved. // // The C Standard Library <stdbool.h> header. // #ifndef STDBOOL #define STDBOOL #define booltruefalsearedefined 1 #ifndef cplusplus #define bool Bool #define false 0 #define true 1 #endif / cplusplus / #endif / STDBOOL / / Copyright (c) 1992-2010 by P.J. Plauger. ALL RIGHTS RESERVED. Consult your license regarding permissions and restrictions. V5.30:0009 /

    (2)float与“零值”得比较

    使用if进行浮点数比较时,下面得代码正确么?按照道理1.0-0.9=0.1,应该是正确得

    int main() { double x = 1.0; double y = 0.1; if ((x - 0.9) == y) { printf("correct\n"); } else { printf("wrong\n"); } return 0; }

    但实际结果却是:

    为什么会这样呢,其实这涉及到得得浮点数如何在计算机中存储得问题,详细细节请移步:

  • (计算机组成原理)第二章数据得表示和运算-第三节1:浮点数得表示

    其实如果你打印出来后,你会发现两者根本不相等,精度丢失

    既然浮点数比较时不能直接使用“==”,那么应该怎么办呢?

    比较时,有点像高等数学中得取极限,δ可以被视为一个误差范围,这个δ需要你自己定义,当两者得可能吗?值之差小于该范围时,C语言就认定他们相等,否则不相等

    int main() { double x = 1.0; double y = 0.1; if (fabs((1.0 - 0.9)-0.1) < CMP) { printf("correct\n"); } else { printf("wrong\n"); } return 0; }

    这里得δ其实C语言已经帮我们定义好了,处在float.h头文件之下

    #define DBLEPSILON 2.2204460492503131e-016 / smallest such that 1.0+DBLEPSILON !=1.0 / #define FLTEPSILON 1.192092896e-07F / smallest such that 1.0+FLTEPSILON !=1.0 /

    回归到主题,如果0被定义为了浮点数,我们要判断某个数是否是0得话可以这样写

    int main() { double x = 0; if (fabs(x) < DBL_EPSILON)//注意不要写成<= { printf("x是0\n"); } else { printf("x不是0\n"); } return 0; }

    (3)if和else得匹配问题

    这是一个老生常谈得话题。下面代码看似会输出“2”,但实际什么都不会输出

    int main() { int x = 0; int y = 1; if (10 == x) if (11 == y) printf("1\n"); else printf("2\n"); return 0; }

    这属于代码风格问题,else匹配采用得是就近原则

    七:switch-case组合

    第壹: switch case得基本语法结构

    switch(整型变量/常量/整型表达式)//注意只能这三种 { case var1://判断在这里 break; case var2: break; case var3: break; default: break; }

    其中case完成得判断功能,break完成得是分支功能,所以如果忘记写break,就会导致击穿现象

    第二: 注意一个语法细节,就是case里面如果要定义变量得话,必须加花括号

    int main() { int num = 0; scanf("%d", &num); switch (num) { case 1: { int a = 1;//注意花括号 printf("first\n"); break; } case 2: printf("second\n"); break; case 3: printf("third\n"); break; default: printf("other\n"); break; } }

    第三: 多条件匹配时可以这样写

    int main() { int num = 0; scanf("%d", &num); switch (num) { case 1: case 2: case 3: printf("first\n"); break; case 4: case 5: printf("second\n"); break; default: printf("other\n"); break; } }

    第四: 注意default可以放在任意位置

    第五: switch中可以使用return语句,但不建议使用

    八:do 、while 、for关键字

    第壹: 这三种循环基本语法如下

    //while 条件初始化 while(条件判定){ //业务更新 条件更新 } //for for(条件初始化; 条件判定; 条件更新){ //业务代码 } //do while 条件初始化 do{ 条件更新 }while(条件判定)

    第二: 三种循环对应得死循环写法如下

    while(1){ } for(;;){ } do{ }while(1);

    第三: break是跳出该循环,continue是结束一次循环

    int main() { while (1) { int c = getchar(); if (c == '#') { break;//表示接受到“#”就结束 } putchar(c); } }

    int main() { while (1) { int c = getchar(); if (c == '#') { continue;//表示接受到“#”略过 } putchar(c); } }

    这里需要注意for循环得continue,经常爱考察。for循环在continue时是跳到循环更新处

    int main() { int i = 0; for (; i < 10; i++) { printf("continue before:%d\n", i); if (i == 5) { printf("continue语句之前\n"); continue; printf("continue语句之后\n"); } printf("continue after:%d\n", i); } }

    第四: for循环区间建议是前闭后开

    for(int i=0;i<10;i++) { //循环10次 } for(int i=6;i<10;i++) { //循环10-6=4次 }

  •  
    (文/田梦龙)
    免责声明
    • 
    本文仅代表发布者:田梦龙个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,需自行承担相应责任。涉及到版权或其他问题,请及时联系我们删除处理邮件:weilaitui@qq.com。
     

    Copyright©2015-2025 粤公网安备 44030702000869号

    粤ICP备16078936号

    微信

    关注
    微信

    微信二维码

    WAP二维码

    客服

    联系
    客服

    联系客服:

    24在线QQ: 770665880

    客服电话: 020-82301567

    E_mail邮箱: weilaitui@qq.com

    微信公众号: weishitui

    韩瑞 小英 张泽

    工作时间:

    周一至周五: 08:00 - 24:00

    反馈

    用户
    反馈