C语言零基础第1讲:初识C语言

目录

1.C语言是什么?

2.C语言的历史

2.1 机器语言

2.2 汇编语言

2.3 高级语言

2.4 C语言的发展

3.使用什么软件写C语言程序?

3.1 源程序变成可执行程序的过程

3.2 集成开发环境

4.第一个C语言程序

5.main函数

6.库函数

7.关键字

8.ASCIII编码

9.字符串和\0

10.转义字符

11.语句分类

11.1 空语句

11.2 表达式语句

11.3 函数调用语句

11.4 复合语句

11.5 控制语句

12.注释

12.1 注释的2种形式

12.1.1 /*...*/形式

12.1.2 //...的形式

12.2 注释会被替换


正文开始

1.C语言是什么?

人与人交流,使用的是自然语言,如:英语、汉语、日语...

那么人和计算机,使用什么语言交流呢?使用计算机语言

人们可以通过计算机语言写的程序,对计算机下达指令,让计算机完成对应的工作

C语言就是众多计算机语言的一种,其他的还有C++、Java、Go、Python等

2.C语言的历史

2.1 机器语言

机器语言是最早出现的计算机语言,也是计算机唯一能够直接识别和执行的语言,是由0和1组成的二进制数字序列。每一条指令都对应了一个特定的操作,比如:可能使用“10110100”表示“进行加法运算”。你会发现,这种语言难以识记,于是汇编语言应运而生。

2.2 汇编语言

汇编语言用英文单词或其缩写,代替二进制的指令代码,比如:ADD表示相加操作,SUB表示相减操作。但计算机不能直接识别汇编语言,用汇编语言写好的程序,需要通过汇编程序,翻译成机器语言程序,然后交给底层的硬件机器去执行。

汇编语言不具备可移植性。简单来说, 汇编语言的代码是“量身定做”给特定硬件(主要是CPU)的。这台电脑的CPU能看懂的汇编指令,换一台CPU型号或者架构不同的电脑,很可能就看不懂了,因为它们的指令规则不一样。直观的表现就是,硬件变了,代码可能就完全失效,必须重新写。

汇编语言更容易记忆和理解,但是,汇编语言还是不够友好,于是又发展出了高级语言。

而C语言这类高级语言之所以可移植,正是因为它不直接对应硬件指令,而是通过编译器翻译成不同硬件能看懂的汇编/机器码,相当于有个通用翻译官,帮代码适应不同的硬件。

2.3 高级语言

高级语言更加贴近人类自然语言,更容易编写和阅读。

计算机无法直接识别高级语言,需要通过工具将其转换为机器语言,如:汇编程序(汇编器)、编译程序(编译器)和解释程序(解释器)。

故而高级语言可分为编译型语言和解释型语言。

编译型语言包括:C、C++等,通过编译器,将整个程序一次性翻译成机器语言,生成可直接执行的文件。编译器可以直接产生机器语言代码,也可以先产生汇编语言,然后再通过汇编程序将汇编语言代码转换为机器语言代码。

解释型语言包括:Python、JavaScript等,通过解释器,逐行将代码翻译成机器语言并立即执行,即翻译一行就执行一行,不生成独立的可执行文件。

2.4 C语言的发展

C语言最初是作为Unix系统的开发工具而发明的。

  1. 1969年,发明B语言:1969年,贝尔实验室的肯·汤普森和丹尼斯·里奇,一起开发了Unix操作系统。而Unix是用汇编语言写的,不具备可移植性。为了移植到其他计算机上,汤普森就在BCPL的基础上,发明了B语言。
  2. 1972年,发明C语言:丹尼斯·里奇和布莱恩·柯林汉,又在B语言的基础上,重新设计了一种新语言,这种语言取代了B语言,所以称为C语言。
  3. 1973年,Unix系统使用C重写:整个Unix系统都使用C语言重写。此后,这种语言开始快速流传,广泛用于各种操作系统和系统软件的开发。
  4. 1988年,C语言标准化:美国国家标准协会(ANSI)正式将C语言标准化,通过统一语法规则、定义标准库和消除歧义等,让C语言成为一门真正通用的“普通话”,标志着C语言开始稳定和规范化。
  5. 至今:一直到今天,C语言还是在广泛使用,居于计算机语言的前三地位。

3.使用什么软件写C语言程序?

3.1 源程序变成可执行程序的过程

正如前面所说,C语言是一门编译型语言,C语言的源代码是文本内容,文本文件本身无法执行。需要经过编译器的翻译和链接器的链接, 生成二进制的可执行文件,才能够被执行。

源程序变成可执行程序的过程,具体而言,可分为三步:

  1. 预处理:主要用C语言编译器对各种预处理命令进行处理,包括对头文件的包含、宏定义的扩展和条件编译的选择等,如处理#include、#define等指令,然后生成预处理后的文件。
  2. 编译:直接翻译成计算机能够直接识别的机器语言,或者先翻译成汇编语言,再通过汇编器翻译成机器语言,最终生成目标文件。
  3. 链接:将多个目标文件和库文件组合成可执行文件。

一个工程一般会由多个源文件组成,如下图所示,演示了源程序经过编译器和链接器处理的过程:

注意:

  1. 每个源文件(.c),单独经过编译器的处理,生成对应的目标文件(.obj)
  2. 多个目标文件和库文件,经过链接器的链接,生成对应的可执行程序(.exe)

3.2 集成开发环境

经过上面的介绍,显然,写C语言程序是需要编译器的。

常见的编译器有:msvc、clang、gcc等。

使用什么软件写C语言程序?这个问题其实就是在说,使用什么集成开发环境写C语言程序?

集成开发环境(IDE):就是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。是集成了代码编写功能、分析功能、编译功能、调试功能等,一体化的开发软件服务套。

常见的集成开发环境有:VS2022、XCode、CodeBlocks、DevC++、Clion等。

  1. VS2022:集成了MSVC(安装包较大一些,安装简单,无需多余配置,使用起来非常方便)
  2. Xcode:集成了clang(苹果电脑上的开发工具)
  3. CodeBlocks:集成了gcc(这个工具比较小众,需要配置环境,不太推荐)
  4. DevC++:集成了gcc(小巧,但工具过于简单,对于代码风格的养成不好,一些竞赛使用)
  5. Clion:是默认使用CMake,编译器是可以配置的(工具是收费的,暂时不推荐使用)

整体考虑,推荐大家安装VS2022的社区版进行学习。

优点如下:

  1. VS2022是一个主流的集成开发环境,企业中使用较为普遍。
  2. 包含了:编辑器+编译器+调试器,功能强大。
  3. 直接安装即可使用,基本不用额外配置环境,上手容易。
  4. 默认界面是中文的,初学者友好。

缺点如下:

  • 功能丰富,安装包大,故而占用空间多。

4.第一个C语言程序

#include<stdio.h> int main() { printf("Hello World\n"); return 0; }

上图演示了一段非常经典而简单的代码,并给出运行结果。

在VS2022中,运行代码的快捷键是Ctrl + F5

14英寸的笔记本电脑上的快捷键可能为Ctrl + Fn + F5

5.main函数

main函数也叫主函数,不管程序有多少行代码, 都是从main函数开始执行的。main前面的int表示main函数执行结束的时候返回一个整型类型的值,所以在main函数的最后写return 0;,正好前后呼应。

  1. main函数是程序的入口。
  2. main函数必须有,且仅有一个。
  3. 即使一个项目中有多个.c文件,但是只能有一个main函数。

6.库函数

printf("Hello World\n");

上面的代码使用了printf函数,printf函数是一种库函数,功能是在屏幕上打印出相应的信息。

printf函数的使用方法如下:

%c、%d等是占位符,会被后面的值替换。

\n是换行符,在打印完一条内容后实现换行,那么先后打印的2条内容就不会连在一起了。

我们说,printf函数是一种库函数, 那么,什么是库函数呢?

我们来看一张图:

从上面的图片可以看出,要实现打印功能,实际上需要很多行冗长的代码。如果在一个程序中,你需要多次使用到打印功能,那么每次都要写一长串代码来实现这个功能,这实在是太麻烦太低效了。为了提高效率,C语言标准规定了一个函数,命名为printf函数,人们只需要把想要打印的内容传递给printf函数,仅需一条代码,即可实现打印功能。

同样的,有一些功能,我们是需要经常用到的,于是C语言标准规定了一组函数,这些函数再由不同的编译器厂商根据标准实现,提供给人们使用。这些函数组成了一个函数库,被称为标准库,这些函数被称为库函数。在这个基础上,一些编译器厂商可能会额外扩展,提供部分函数(这些函数,其他编译器不一定支持)。

属于同一个系列的库函数,一般会声明在同一个头文件(.h)中,所以库函数的使用,需要包含对应的头文件

比如,printf函数的使用,就需要包含stdio.h这个头文件,是Standard Input/Output Header的缩写,意为标准输入/输出头文件。如下所示:

#include <stdio.h>

7.关键字

在C语言中,有一批保留名字的符号,比如:int、if、return等,这些符号被称为保留字或关键字。

在创建变量、函数、结构体等时,需要给变量、函数和结构体等取一个名字,这个名字是不能乱取的。

那么取名字有什么讲究呢?那就是,在创建这些标识符时,不能和关键字重复。

C语言的32个关键字如下:

注:在C99标准中,加入了inline、restrict、_Bool、_Complex、_Imaginary等关键字。

8.ASCII编码

在键盘上,可以敲出各种符号,比如:a、b、@、#等,这些符号被称为字符。

在C语言中,字符是用单引号括起来的,比如:'a'、'b'、'@'、'#'等。

我们知道,在计算机中,所有数据都是以二进制的形式存储的,那么这些字符该如何存储呢?

我们可以给每一个字符编一个独一无二的二进制序列,这就叫做编码。

每个人的编码方式不尽相同,所以为了统一标准,后来美国国家标准学会(ANSI)出台了一个标准ASCII编码,C语言中的字符就遵循了ASCII编码的方式。

ASCII码表如下:

我们不需要记住ASCII码表中的所有数字,使用时查看即可,但最好能掌握几组特殊的数据:

  1. 字符A~Z的ASCII码值:65~90
  2. 字符a~z的ASCII码值:97~122
  3. 对应的大小写字符(如a减A)的ASCII码值的差值为: 32(因为在Z和a之间还存在6个字符:[、\、]、^、_、·)
  4. 数字字符0~9的ASCII码值:48~57
  5. 换行\n的ASCII码值:10
  6. ASCII码值从0~31:这32个字符是不可打印字符,无法打印在屏幕上观察

单个字符的打印,可以用%c来指定格式,可以使用ASCII码值的十进制数进行打印:

可打印字符的展示:

9.字符串和\0

在C语言中,使用双引号括起来的一串字符,就称为字符串,如:"abcdef"

C语言字符串中有一个特殊的知识,就是在字符串的末尾隐藏放着一个\0字符,这个\0字符是字符串的结束标志。

如上图,对于字符串"abcdef" ,我们看到的是6个字符:a,b,c,d,e,f,但是实际上,在末尾还隐藏着一个转义字符\0,\0是字符串结束的标志。我们在使用printf()打印字符串,或使用strlen()计算字符串长度时,遇到\0就自动停止了。

在C语言中,可以把一个字符串放在一个字符数组中,我们利用下面的代码验证一下\0的功能:

我们可以观察到,arr1中存放的是3个字符:a,b,c,所以在末尾没有\0。而arr2中存放的是1个字符串"abc",所以在末尾有\0,作为字符串结束的标志。

运行结果如下:

我们可以看到, arr1在打印了a、b、c后,继续往后打印了一些随机值。这是因为arr1中存放的是3个字符,而不是字符串,所以末尾没有隐藏一个\0作为停止标志。而打印是以%s,即字符串的格式打印的,所以在打印时,从左往右一个个打印,却没有遇到结束标志\0,所以就没有停止打印。

而arr2的打印是正常的,因为arr2是使用字符串常量初始化的,字符串的末尾隐藏了一个\0,并作为停止标志,所以打印可以正常停止。

刚刚说到,arr1中没有\0,故而在打印时出现了问题,如果我们在arr1的最后,单独放一个'\0'字符会怎么样呢?

可以看到,3次打印的结果都一样,都是遇到\0就停止打印了。

10.转义字符

在前面,我们提到了\n、\0。它们都属于转义字符,转义字符顾名思义,就是转变原来意思的字符。

比如:有字符n,放在abcndef中,可以打印出abcndef

如果我们在n的前面加上一个反斜杠\呢?那么就不会打印出n字符了,而是变成了换行

如上所示,这就是转义字符的作用,我们可以简单地理解为,\让n的意思发生了转变,n本来是一个普通的字符,被\转义为换行的意思。

在C语言中,像这样的转义字符还有很多,具体如下:

  1. \?:在书写连续多个问号时使用,防止它们被解析成三字母词,在新的编译器上没法验证了
  2. \' :用于表示字符常量 ',如下图:
  3. \" :用于表示一个字符串内部的双引号,如下图:
  4. \\ :用于表示一个反斜杠,防止它被解释为一个转移序列符,如下图:
  5. \a :警报,这会使终端发出警报声或出现闪烁,或两者同时发生。
  6. \b :退格键,光标回退一个字符,但不删除字符。如下图,依次打印出a、b、c,此时光标在c的后面,接下来遇到了\b,于是光标回退到b的后面,然后继续打印d,而d覆盖了原来的c,于是变成了abd,继续往后打印,最终打印出abdef。
  7. \f :换页符,光标移到下一页。在现代系统上,这已经反映不出来了,行为改成类似于\v
  8. \n:换行符
  9. \r :回车符,光标移到同一行的开头。如下图,依次打印出a、b、c,此时光标在c的后面,接下来遇到\r,光标移到这一行的开头,也就是a的前面,然后继续打印d、e、f,而d、e、f覆盖了原来的a、b、c,所以最终打印出def。
  10. \t :水平制表符,光标移到下一个水平制表位,一个水平制表位一般默认是8个字符。如果\t的前面有x个字符,那么就会算上前面的字符个数,往后面补充(8-x)个空格,构成一个水平制表位。如下图:水平制表符的对齐效果如下:
  11. \v :垂直制表符,光标移到下一个垂直制表位,通常是下一行的同一列,它会按垂直方向来对齐内容。如下图:
  12. \ddd:字符的8进制表示形式,d表示1个八进制数字。如下图:
  13. \xdd:字符的16进制表示形式,d表示1个十六进制数字。如下图:
  14. \0 :null字符,代表没有内容,\0就是\ddd这类转义字符的一种,用于字符串的结束标志,其ASCII码值是0。

11.语句分类

C语言中的语句可以分为以下5类:

  1. 空语句
  2. 表达式语句
  3. 函数调用语句
  4. 复合语句
  5. 控制语句

11.1 空语句

在C语言中,空语句是仅由一个分号组成的语句,它不执行任何操作。如下图:

空语句虽然看似无用,但在特定场景下有其独特的应用价值。空语句出现的位置一般是:这里需要一条语句,但是这个语句不需要做任何事。如下图:

简化后如下:

11.2 表达式语句

表达式语句就是在表达式的后面加上一个分号,通过分号将表达式转换为可执行的语句。常见于变量赋值、函数调用、自增自减等操作。

11.3 函数调用语句

函数调用的时候,也会加上分号,就是函数调用语句。

函数的调用,可以分为库函数的调用和自定义函数的调用,如下图:

11.4 复合语句

复合语句其实就是代码块,是由一对花括号 { } 括起来的内容。

花括号包裹任意数量的语句(哪怕只有1条、甚至0条),都叫复合语句。

如下图,for循环的循环体,花括号括起来的内容,就是复合语句。

11.5 控制语句

控制语句用于控制程序的执行流程,以实现程序的顺序结构、选择结构和循环结构,它们由特定的语句定义符组成。

C语言有9种控制语句,可以分为以下3类:

  1. 条件判断语句(分支语句):if语句、switch语句
  2. 循环执行语句:do while语句、while语句、for语句
  3. 转向语句:break语句、goto语句、continue语句、return语句

12.注释

注释是对代码的说明,编译器会忽略注释。也就是说,注释对实际代码没有任何影响。

注释是给自己看的,也是给别人看的。好的注释可以帮助我们更好地理解代码,但也不要过度注释,不要写不必要的注释。

12.1 注释的2种形式

C语言的注释有2种方法。

12.1.1 /*...*/形式

第一种方式是,将注释放在/*和*/之间,内部可以分行。如下图:

要注意,注释是不能放在printf里面的,还是会被打印出来,起不到注释的效果:

它可以插在行内,比如放在函数的参数列表里面,对参数进行说明:

这种注释方式,一定不能忘记写结束符号*/,如下图:

在上图中,原意为在第1行和第4行,各有一个注释,但是注释1忘了写结束符号*/,导致注释一直往后延续,直到找到注释2的结束符号*/,才结束注释,于是第二三四行的内容全被注释了,我们可以看一下运行结果:

同时,这种注释方式也不支持嵌套注释,/*开始注释后,遇到第一个*/就认为注释结束了,如下图:

12.1.2 //...的形式

第二种方式是,将注释放在双斜杠//的后面,从//到行尾都属于注释。这种注释方法只能是单行的,可以放在行首,也可以放在一行语句的结尾。这是C99标准新增的语法。

同样的,这种注释方式也不能放在双引号里面,否则还是会被打印出来,如下图:

12.2 注释会被替换

在编译时,注释会被替换为一个空格,比如:abc/*这里是注释*/def,会被替换为abc def,而不是abcdef。


完结