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

目录

1.C语言是什么?

2.C语言的历史

2.1 机器语言

2.2 汇编语言

2.3 高级语言

2.4 C语言的历史

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

3.1 编译和链接

3.2 常见的编译器

3.2 集成开发环境

4.写一个简单的C语言程序

5.main函数

6.printf函数与库函数

6.1 printf函数

6.2 库函数

7.关键字

8.字符和ASCII编码

9.字符串和\0

10.转义字符

11.语句分类

11.1 空语句

11.2 表达式语句

11.3 函数调用语句

11.4 复合语句

11.5 控制语句 

12.注释 

12.1 注释的2种形式 

1.C语言是什么?

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

那么人和计算机怎么交流?使用计算机语言

人们可以使用计算机语言编写程序,给计算机下达指令

C语言就是众多计算机语言中的一种,常见的计算机语言还有:C++、Java、Go、Python

2.C语言的历史

在介绍C语言的历史之前,我们不妨先了解一下机器语言→汇编语言→高级语言这3个阶段。

2.1 机器语言

人们最早使用的计算机语言,并不是C语言,而是机器语言。

机器语言是计算机唯一能直接识别和执行的二进制代码,是最底层的语言。

但是机器语言有个缺点,就是特别复杂,比如1+1用机器语言表示可能是如下这样:

00000001 00000001 00000010 00000001 11111111

这样实在是太冗杂,太难以识记了,于是汇编语言应运而生。

2.2 汇编语言

汇编语言使用了一些助记符如英文单词,来代替机器语言的指令,比如:用ADD表示加法,SUB表示减法。

用汇编语言写的程序,必须通过汇编器转换为机器语言,才能被计算机执行。

汇编语言看起来已经很友好了,但是还是不够好,于是高级语言应运而生。

2.3 高级语言

高级语言更接近人类的自然语言,更容易理解。

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

比如:C语言属于编译型语言,Python属于解释型语言。

编译型语言和解释型语言都需要转换成机器语言才能被计算机执行,只是转换的方式和时机有所不同。

在转换时机方面:

编译型语言是在执行前,一次性编译完,然后再执行,类似于提前把整本书翻译成目标语言,阅读时直接读译本,高效但不灵活。

解释型语言是在执行时,逐行解释,解释一行再执行一行,类似于边读边翻译,阅读时需要翻译官实时翻译,灵活但低效。

在转换方式方面:

编译型语言需要先通过编译器转换为汇编语言,再通过汇编器转换为机器语言,最终才能被执行。

解释型语言则没有汇编这个过程,直接通过解释器或虚拟机执行,可能生成抽象的字节码。

2.4 C语言的历史

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

发明B语言:1969年,贝尔实验室的肯·汤普森和丹尼斯·里奇一起开发了Unix操作系统,Unix是用汇编语言写的,汇编语言不具备可移植性,简单来说,汇编语言是为特定硬件定制的代码,一旦硬件换了,代码就得重写。为了移植到其他计算机,汤普森就在BCPL语言的基础上发明了B语言。

发明C语言:1972年,丹尼斯·里奇和布莱恩·柯林汉又在B语言的基础上重新设计了一种新语言,这种新语言取代了B语言,所以称为C语言。

Unix系统使用C重写:1972年,整个Unix系统都使用C语言重写,此后,C语言开始快速流传,广泛用于各种操作系统和系统软件的开发。

C语言标准化:1988年,美国国家标准协会(ANSI)正式将C语言标准化,明确语法规则、功能特性及实现要求等,标志着C语言开始稳定和规范化。

至今:一直到今天,C语言还是在广泛使用,在计算机语言的排行榜上霸占前三。

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

在初步了解C语言之后,你可能会蹦出一个问题:那么我们用什么软件来写C语言程序呢?

在回答这个问题之前,我们不妨先了解一些必要的概念。

3.1 编译和链接

C语言源代码本质上就是一堆文本,计算机是读不懂这些文本的,必须通过编译器的编译,转换成计算机能够识别的二进制代码,再经过链接器的链接,生成二进制的可执行文件,最终才能够被执行。

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

  1. 源文件以 .c 为后缀
  2. 目标文件以 .obj 为后缀
  3. 可执行文件以 .exe 为后缀
  4. 每个源文件单独经过编译器的处理生成对应的目标文件
  5. 多个目标文件和库文件经过链接器的处理生成对应的可执行程序 

3.2 常见的编译器

上面我们已经提到过,C语言是一门编译型语言,需要依赖编译器,将计算机语言转换成计算机能够执行的机器指令。

常见的C语言编译器有:msvc、clang、gcc等

  • msvc:是 ​Microsoft Visual C++​ 的缩写,是微软公司开发的。

  • clang:主要用于苹果生态开发。

  • gcc:是一款历史悠久的开源编译器套件,尤其适合 Linux/Unix 环境下的系统开发、嵌入式项目以及学术研究。

3.2 集成开发环境

我们再来看一下集成开发环境的概念吧,说白了,所谓集成开发环境,就是你写代码要用的软件。

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

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

  • VS2022:集成了msvc。安装包较大一些,安装简单,无需多余配置,使用起来非常方便。
  • Xcode:集成了clang。是苹果公司推出的集成开发环境。
  • CodeBlock:集成了gcc。这个工具比较小众,需要配置环境,不太推荐。
  • DevC++:集成了gcc。小巧,但是工具过于简单,对于代码风格的养成不好,一些竞赛使用。
  • Clion:默认使用CMake,编译器是可以配置的。工具是收费的,所以暂时不推荐使用。

最后,我们来回答一下,用什么软件来写C语言程序?

推荐安装VS2022的社区版本进行学习,免费,界面清爽,使用方便,工作中常见。 

4.写一个简单的C语言程序

来吧,我们直接上代码:

 运行结果如下:

上图演示了使用VS2022编写的一个简单经典程序,并附带运行结果。

顺便说一下,在VS2022中,运行代码的快捷键是:Ctrl + F5 或 Ctrl + Fn +F5(因为有的电脑,F5的默认功能可能是调低亮度,需要联用Fn才能恢复它原本的功能)

接下来,我们就以上面的代码为例,延伸到其他的概念吧。

5.main函数

每个C语言程序,不管有多少行代码,都是从main函数(也叫主函数)开始执行的,也就是说,main函数是程序的入口。

main 前面的 int 表示,main函数执行结束的时候,会返回一个整型类型的值,所以在main函数的最后写 return 0; 正好前后呼应。

每个程序都必须有一个main函数,因为程序是从main函数开始执行的,如果没有main函数,程序就无从执行了。

每个程序只能有一个main函数,因为如果有多个main函数,程序就不知道到底该从哪个入口开始执行了。

6.printf函数与库函数

6.1 printf函数

上面的代码中,有一行 printf("hello world\n");  使用了printf函数。

printf函数是一个库函数,功能是在屏幕上打印出想要的信息,只要把想打印的一串字符放在双引号中,就可以实现打印功能。

同时,在使用库函数的时候,是需要包含头文件的,比如:printf函数需要包含的就是 stdio.h 这个头文件。具体写法就是:#inclulde <stdio.h>

而 hello world 后面的 \n ,是换行符,作用是在打印完这行内容之后,进行一次换行。

下面的两张图,对比了使用换行符和不使用换行符的情况,可以一目了然地看出换行符\n的作用。

printf("hello world\n); 所打印的信息,是字符串类型,用双引号括起来。

其实printf函数还可以打印其他类型的信息,如下图所示:

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

6.2 库函数

我们刚刚说,printf函数是一个库函数。

那么,也许你会问,什么是库函数呢?

我们以printf函数为例,看看它的部分简化版底层实现代码:

我们不用关心上面的代码是什么意思,我们只需要知道一点,要实现打印功能,原来要写这么多行代码!

如果我们在一个程序中,需要多次使用到打印功能,那么岂不是要重复地写很多遍这样的长代码吗?这实在是太麻烦和低效了。于是C语言标准规定了一个函数,命名为printf函数。这样,以后人们想要实现打印功能,只需要一行简单的 printf("......"); 就可以搞定了。

推而广之,如果我们在一个程序中,需要多次使用到某种功能,可能要重复写同一段很长的代码。所以C语言标准规定了一组函数,这些函数再由不同的编译器厂商根据标准进行实现,提供给大家使用。这些函数组成了一个函数库,被称为标准库,里面的函数被称为库函数。在这个基础上,一些编译器厂商可能会额外扩展,提供部分其他函数,对于这些函数,其他的编译器不一定支持。

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

7.关键字

在写代码的过程中,我们常常需要创建变量或者创建函数等,既然要创建变量,那么肯定要取一个变量名吧?创建函数,也需要取一个函数名吧?

那么,这些名字是随便我们取的吗?其实,有些名字我们是不能取的,这些不能取的名字,就称为关键字保留字,比如前面提到的 int 和 return 等。

总结一下:我们自己在创建标识符的时候,是不能和关键字重复的。

那么你可能要问了,关键字都有哪些呀?

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

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

8.字符和ASCII编码

在键盘上,可以敲出各种字符,比如: h 、 j 、 @ 、 # 等,这些符号都被称为字符。C语言中,字符是用单引号括起来的,如:'h','j','@'。

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

不难想到,我们可以给每个字符编一个二进制序列,这就叫做编码。每个字符都唯一对应一个二进制序列,这样就可以解决存储的问题了。

为了统一编码规则,不造成混乱,后来美国国家标准学会(ANSI)出台了一个标准ASCII编码,C语言中的字符就遵循了ASCII编码的方式。

上面的ASCII码表,我们看每个字符对应的十进制数字就好了。

我们不需要记住所有的内容,使用时查看就可以了,但我们也可以记住几组特殊的数据:

  • 字符A~Z的ASCII码值,从65~90
  • 字符a~z的ASCII码值,从97~122
  • 对应的大小写字符,ASCII码值的差值为32,即小写字符 - 大写字符 = 32
  • 数字字符0~9的ASCII码值,从48~57
  • 换行符 \n 的ASCII码值,为10
  • 在这些字符中,ASCII码值从0~31的32个字符是不可打印的,无法打印在屏幕上观察

前面我们提到过,单个字符的打印可以用%c来指定格式,而且可以用ASCII码值来打印对应的字符:

另外,有些字符是不可打印的,这里可以展示一下可打印的字符:

9.字符串和\0

在前面,已经提到过字符串了,使用双引号括起来的一串字符就被称为字符串,如:"hello world" 就是一个字符串。

前面也提到过,字符串的打印格式可以用%s来指定,也可以直接打印,如下:

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

如上图,对于字符串"abcdef",我们实际上只看到了6个字符:a,b,c,d,e,f

但是实际上,在末尾还隐藏了一个转义字符:\0

刚刚说到,\0是字符串结束的标志,所以,在使用printf()打印字符串或者strlen()计算字符串长度的时候,遇到\0就自动停止了。

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

我们再来看一下运行结果:

我们可以看到,arr1数组在打印的时候,打印了abc,后面还有一些随机值,这就是因为arr1在末尾,没有\0字符作为结束标志,于是在打印的时候没有停止。

而arr2的打印就是完全正常的,因为arr2数组中放入的是字符串常量,默认自带\0字符,打印可以正常停止。

如果我们在arr1数组的末尾再放一个 '\0' ,会如何呢?

如上图,三次打印的结果都一样了。

我们在arr1数组的末尾加了一个'\0',所以打印可以正常停止,不会往后出现随机值。

我们在arr3数组中,abc的后面加了一个'\0',所以在此处打印就停止了,def并不会被打印。

10.转义字符

在前面,我们提到了 \n 和 \0 等字符,它们都是转义字符。

所谓转义字符,顾名思义:就是转变原来意思的字符。

比如:n本来是一个字母,但是加上斜杠之后,就转变成了换行的意思。

还是用代码演示一下吧:

由上图可见,双引号中所放的内容是abc\ndef,但\n并没有被打印出来,而是被转换为换行。

像这样的转义字符,C语言中还有很多,我们不妨来看看:

  1.  \' :用于表示单引号。
  2.  \" :用于表示字符串内部的双引号。
  3.  \\ :用于表示一个反斜杠,防止它被解释为一个转义序列符。
  4.  \a :警报,发出警报声或出现闪烁,或者两者同时发生。
  5.  \b :退格键,光标回退一个字符,但不删除字符,如果后续有新的字符输出,新字符就会把原位置的字符覆盖掉。比如打印abc\bd,打印结果是abd。这个过程是,首先输出字符'a','b','c',此时光标位于'c'的后面。遇到\b之后,光标回退到'b'和'c'之间,接着输出'd','d'便覆盖了原来的'c'。也就是说,没有删掉原来的字符,只是把原来的字符覆盖掉了。
  6.  \n :换行符,前面已演示过。
  7.  \r :回车符,光标移到当前行的起始位置,也就是最左侧,但不删除原有内容,后续要是有新字符输出,新字符就会把原位置的字符覆盖掉。比如打印abc\rdef,打印结果是def。这个过程是,首先输出abc,遇到\r,光标移到这一行的开头,也就是a的前面,然后再输出def,而def把原来位置上的abc覆盖了。
  8.  \t :水平制表符,光标移到下一个水平制表位,通常是8。比如打印AAA\tAAA,打印结果是AAA(5个空格)AAA。这个过程是,先输出AAA,然后遇到\t,发现AAA后面离8还差5个位置,于是补充5个空格,光标跳转到下一个水平制表位的最左侧。
  9.  \v :垂直制表符,光标移到下一个垂直制表位,也就是移到下一行的相同列位置。
  10.  \ddd :字符的8进制表示形式。其中d为1个8进制数字,可以是\d,\dd,\ddd。比如:\110,八进制的110表示的是字符H"。
  11.  \xdd :字符的16进制表示形式。其中dd为2个16进制数字。比如:\x4a表示字符'J',\x36表示字符'0'。
  12.  \0 :null字符,表示没有内容。\0其实就是\ddd这类转义字符的一种, 用于字符串的结束标志,其ASCII码值是0。

下面来个关于有关转义字符的小题目吧:

思考一下,运行结果会是什么呢?答案如下:

11.语句分类

显然, C语言的代码,是由一条条的语句构成的,这些语句可以分为五类:

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

11.1 空语句

空语句是一个仅由分号组成的语句,它不执行任何操作。

空语句看似简单,但在特定场景下有重要用途。

空语句出现的场景一般是:在语法上,这里需要一条语句,但这个语句不需要做任何事。

下面给出两种简单的应用场景:

11.2 表达式语句

表达式语句就是,一个表达式后面跟一个分号。

那么啥是表达式呢?其实表达式也分为挺多种的,比如:赋值语句、函数调用语句、自增/自减语句、逗号表达式语句、空表达式语句等等。

11.3 函数调用语句

函数调用语句就是调用函数的语句,后面也需要跟上一个分号。

调用函数,可以是调用库函数,也可以是调用自定义函数。

下面是调用库函数的示例:

下面是调用自定义函数的示例:

11.4 复合语句

复合语句也就代码块,简而言之,就是由被花括号{}括起来的一块代码。

在一对花括号内部,会形成独立的作用域。在花括号内部声明的变量,具有局部作用域,在该花括号之外,无法访问这个变量。

11.5 控制语句 

控制语句用于控制程序的执行流程,以实现各种结构(C语言支持3种结构:顺序结构、选择结构、循环结构)。

控制语句可分为以下3类,共9种:

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

这些语句,后续再进行一一介绍。

12.注释 

注释是对代码的说明,编译器会自动忽略注释,所以注释对代码本身不会产生影响。

写了注释,可以帮助我们更好地理解代码,当然也不能过度写注释,写不必要的注释。

12.1 注释的2种形式

12.1.1 /**/的形式

第一种方法是,把注释内容放在 /*...*/ 之间,内部可以分行。

在使用这种注释的时候,要注意不要忘记写结束的符号 */ ,我们来看一个反面例子:

我们来看一下运行结果吧:

12.1.2 //的形式

第二种写法,是把注释内容放在双斜杠//的后面,从双斜杠开始,一直到这一行的行尾,都属于注释内容。

这种注释方法只能是单行的,可以放在行首,也可以放在一句代码的结尾。

最后,不管是/*/的注释方法,还是//的注释方法,都不能放在双引号里面,否则会成为字符串的一部分,解释为普通符号,失去注释的作用:

12.2 注释会被替换

编译时,注释会被替换成一个空格。

比如:Hello/*这里是注释*/World 会被替换成Hello World,而不是HelloWorld。


好啦,这一篇博客完结了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值