一篇文章看懂c语言代码
怎样学习c语言怎样看懂c语言代码#define指令和注释直观感受#define指令的效果符号_CRT_SECURE_NO_WARNINGS#include"file"int main(){}和return 0;
变量,输入函数scanf和输出函数printf变量输入函数scanf输出函数printf
简单运行代码结语
怎样学习c语言
从我的经历来看,c语言是全国涉及计算机的大学接触计算机的第一门课(有的学校不是,看学校和专业的需求)。
开始学c语言,都是先从简单概念介绍,编译环境的搭建开始,会用就行,用熟后再学内部的东西。编译环境的选择很多,我喜欢用的有三种:
Dev-C++ 5.11(比赛,特别是蓝桥杯用的多)。Microsoft Visual Studio 2019(为啥不用最新的版本,是因为新版本做的封装太过严实,不利于新手学习)。Visual Studio Code,可以装各种插件用于支持各种编程语言和功能。
每种语言都有自己的语法,c语言也不例外。这篇文章的目的是读完就能大概读懂c语言代码想表达什么意思,不过多解释语法。其中大都为自己的经验和见解,如有错误还请指正。
学好一门语言,需要日常积累,写笔记并复习,并且多用来解决生活中的问题。可以根据自己的情况向别人分享自己的笔记。比如博客本身就是一种笔记。
文章的测试环境为windows 11操作系统,用到的开发环境有Dev-C++ 5.11,vs2019和vscode。
怎样看懂c语言代码
c语言的代码大都可以归纳为这种形式:
#define _CRT_SECURE_NO_WARNINGS 1
#include"file"
int main(){
//各种带分号的语句(英文的分号),用于实现各种功能;
/*带{}的代码块,表示一个作用域;*/
return 0;
}
之后一句句解释。
#define指令和注释
define指令用于定义常量和宏。在编写代码时可以用define指令将某个数值或某段代码换成自己想要的符号,编译器在编译时会将符号转换成原来的符号。这个指令不能在末尾加;,如果加了,这个符号也会被替换进去,可能会产生错误。
注释是写给程序员看的,编译器在预编译阶段会将注释删除。
代码中有不需要的代码可以直接删除,也可以注释掉。
代码中有些代码比较难懂,可以加一下注释文字。
注释有两种风格:
C语言风格的注释/*xxxxxx*/
缺陷:不能嵌套注释。
例如,
/*1
/**/2
*/3
1和2进行匹配,使得3暴露在外。
C++风格的注释//xxxxxxxx
一次只能注释一行。
就比如这个c语言代码:
#define Ten 10
int main(){
//注释1
/*注释2*/
int var = Ten;
return 0;
}
编译器会在所有的.c文本中将符号Ten换成10。所以这句代码在编译时就变成了
int main(){
int var = 10;
return 0;
}
直观感受#define指令的效果
注意:如果没有配置gcc的环境变量,之后的操作将无法进行。这里是为了展示指令#define带来的效果,相关指令请参考操作系统有关的指令。这里就不放链接了。
如果电脑中有配置gcc.exe的环境变量,可以按Windows + r,Windows键也就是键盘上有四个方格的键位。 按下之后输入cmd打开windows系统的终端控制台。 点击确定之后即可打开终端控制台。一般颜色不是黑色就是白色,我的电脑做了颜色调整。 将控制台的路径切换到源代码所在的路径: test.c的内容如下:
输入指令gcc test.c -E,表示借助gcc这个编译器,将c语言代码test.c通过"-E"这个操作。就会得到下面的结果。 这个操作是c语言的预处理功能,可以将用户的注释删除,以及将所有符号Ten全部转换成10(因为有预处理指令#define Ten 10)。
10可以写成别的,比如英语单词: 这个单词需要有实际意义才能运行这个代码。
若觉得直接在终端中查看不方便,还可以输入指令gcc test.c -E -o test.i让cmd生成一个test.i的文件,在test.i中即可查看: test.i可以换成别的名字。
符号_CRT_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS这个符号是使vs能正常使用scanf和printf和其他函数。
vs编译器认为这些函数不安全,希望使用vs的程序员用他们提供的函数。比如scanf_s,printf_s。但这种加尾巴_s的函数在vs可以运行,但在别的编译器就不一定给运行(我说不一定是可能存在和vs的编译器的生产厂家有合作的公司,他们的编译器说不定也支持这种格式的函数)。
为了能在vs上正常使用别的编译器也能运行的标准的代码,可以用指令#define来定义这个符号,使vs能正常使用scanf和printf和其他函数。
但定义这个符号需要作为代码文本的第一行语句,否则vs在编译时无法通过。 若#define _CRT_SECURE_NO_WARNINGS 1这个指令不作为代码文本的第一行语句,则无效果。
#include"file"
#include指令可以使另外一个文件被编译。就像它实际出现于#include指令的地方一样。被编译的文件叫头文件。一般约定头文件的拓展名为.h,这里直接展开.txt文件。
如果是用""表示要展开的头文件,在预编译阶段,编译器会先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件。 如果找不到就提示编译错误。
如果是<>,则直接在标准位置查找头文件。标准位置取决于编译器。
比如这个操作:
用gcc将文件test.txt展开。 # 1 "test.txt" 1表示第1个文件展开后的结果。
可以看到,编译器先将头文件展开成了代码的一部分,再参与接下来的编译。
int main(){}和return 0;
main是函数名,这个函数是主函数。每个c程序必须有一个主函数才能运行。除了主函数,程序员可以自行添加别的函数。格式用返回值类型 函数名(参数列表){语句集}即可。
return 0;是返回一个0给调用main函数的后台。同样的,如果在main函数里调用别的函数,main函数内部也可以获得该函数的返回值。比如:
int Ten(){
return 10;
}
int main(){
int ten=Ten();
return 0;
}
ten就得到了函数Ten()的一个返回值。
return最主要的作用还是终止当前函数的进行,并返回调用当前函数的函数。比如这里Ten函数在遇到return语句时,无论return语句后面是否还剩语句,Ten函数都将停止运行,运行进度回到main函数。
当函数类型为void时,函数就不具有返回值,此时用return;可以终止函数的进行。
变量,输入函数scanf和输出函数printf
变量
当我们理解c语言的组成后,便可以尝试用c语言解决问题了。
用c语言解决问题,首先将现实事物抽象为变量。
比如我们需要实现这个问题:给两个数据,求他们的和。
我们给出c语言源文件add.c:
#include
int main(){
int a;//声明变量a
int b=3;//定义变量b
scanf("%d",&a);//从键盘上输入整数,将整数赋值给a
printf("%d",a+b);//输出表达式a+b的值
return 0;
}
声明暂时可以理解为告诉编译器有这么一个变量存在,定义则是告诉编译器准备好一片电脑中的空间(可以称之为内存)用于存放数据3。
声明和定义的区别是声明不消耗内存,但定义会消耗内存用于存储数据。
stdio.h是调用标准的输入、输出函数所需的头文件。这个头文件同样可以用上文的方式展开。不过我想没多少人对这个头文件的内容感兴趣。
输入函数scanf
scanf函数的原型: int scanf ( const char * format, ... );
在这里的scanf的一种运用: scanf("%d",&a);//从键盘上输入整数,将整数赋值给a 是从键盘上按%d的格式获取数据,并将数据赋值给变量a。
从原型上看,这个函数是有返回值的。这个函数如果运行成功,该函数会返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
关于EOF,vs给出的定义是: #define EOF (-1)
在add.c中,scanf的返回值并没有用变量之类的东西去接收。这个返回值怎么处理取决于编译器,至于编译器怎么处理我们就不得而知。也许有别的大佬研究这个东西,但我没读过相关的文章,后面学习之后会写笔记进行总结。
输出函数printf
printf函数的原型: int printf ( const char * format, ... );
这里printf的运用: printf("%d",a+b);//输出表达式a+b的值 是向终端控制台输出运算的结果。
至于为什么输入输出都是在控制台上进行,碍于篇幅有限暂时回答不了,只能留到以后。
注意到printf同样有返回值,在源码中同样不对这个返回值做处理。
简单运行代码
我们最终的目的其实还是让代码运行起来帮助我们解决问题。
一样可以通过控制台运行代码。前提是可通过环境变量调用gcc进行编译。
在控制台中找到代码: 输入指令gcc test.c即可生成可执行程序。gcc生成的可执行程序名是a.exe。后输入的指令,.\表示当前路径,后面输入程序名直接调用程序。
结语
碍于篇幅原因,以后的内容在后续会进行补充。
在c语言的学习过程中可参考的网站: c++工具网站。 MinGW-w64下载,内含gcc编译器。