前言
本章主要讲解了C语言的发展史和一些语法规则、分支语句和循环语句,博主是个小白本章如有错误欢迎大佬在评论区留言指出。
什么是C语言?
C语言简介
C语言是一门面向过程的计算机编程语言,与C++、C#、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言描述问题比汇编语言迅速、工作量小、可读性好、易于调试、修改和移植,而代码质量与汇编语言相当。C语言一般只比汇编语言代码生成的目标程序效率低10%-20%。因此,C语言可以编写系统软件。
当前阶段,在编程领域中,C语言的运用非常之多,它兼顾了高级语言和汇编语言的优点,相较于其它编程语言具有较大优势。计算机系统设计以及应用程序编写是C语言应用的两大领域。同时,C语言的普适较强,在许多计算机操作系统中都能够得到适用,且效率显著。
C语言拥有经过了漫长发展历史的完整的理论体系,在编程语言中具有举足轻重的地位。
发展史
C语言诞生于美国的贝尔实验室,由丹尼斯·里奇(Dennis MacAlistair Ritchie)以肯·汤普森(Kenneth Lane Thompson)设计的B语言为基础发展而来,在它的主体设计完成后,汤普森和里奇用它完全重写了UNIX,且随着UNIX的发展,c语言也得到了不断的完善。为了利于C语言的全面推广,许多专家学者和硬件厂商联合组成了C语言标准委员会,并在之后的1989年,诞生了第一个完备的C标准,简称“C89”,也就是“[ANSI C](https://baike.baidu.com/item/ANSI C/7657277)”,截至2020年,最新的C语言标准为2018年6月发布的“C18”。
C语言之所以命名为C,是因为C语言源自[Ken Thompson](https://baike.baidu.com/item/Ken Thompson)发明的B语言,而B语言则源自BCPL语言。
1967年,剑桥大学的Martin Richards对CPL语言进行了简化,于是产生了BCPL(Basic Combined Programming Language)语言。
20世纪60年代,美国AT&T公司贝尔实验室(AT&T Bell Laboratories)的研究员肯·汤普森(Kenneth Lane Thompson)闲来无事,手痒难耐,想玩一个他自己编的,模拟在太阳系航行的电子游戏——Space Travel。他背着老板,找到了台空闲的小型计算机——PDP-7。但这台电脑没有操作系统,而游戏必须使用操作系统的一些功能,于是他着手为PDP-7开发操作系统。后来,这个操作系统被命名为——UNICS(Uniplexed Information and Computing Service)。
1969年,美国贝尔实验室的Ken Thompson,以BCPL语言为基础,设计出很简单且很接近硬件的B语言(取BCPL的首字母),并且用B语言写了初版UNIX操作系统(叫UNICS)。
1971年,同样酷爱Space Travel的丹尼斯·里奇为了能早点儿玩上游戏,加入了汤普森的开发项目,合作开发UNIX。他的主要工作是改造B语言,使其更成熟。
1972年,美国贝尔实验室的丹尼斯·里奇在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言。
1973年初,C语言的主体完成。汤普森和里奇迫不及待地开始用它完全重写了UNIX。此时,编程的乐趣使他们已经完全忘记了那个“Space Travel”,一门心思地投入到了UNIX和C语言的开发中。随着UNIX的发展,C语言自身也在不断地完善。直到2020年,各种版本的UNIX内核和周边工具仍然使用C语言作为最主要的开发语言,其中还有不少继承汤普逊和里奇之手的代码。
在开发中,他们还考虑把UNIX移植到其他类型的计算机上使用。C语言强大的移植性(Portability)在此显现。机器语言和汇编语言都不具有移植性,为x86开发的程序,不可能在Alpha、SPARC和ARM等机器上运行。而C语言程序则可以使用在任意架构的处理器上,只要那种架构的处理器具有对应的C语言编译器和库,然后将C源代码编译、连接成目标二进制文件之后即可在哪种架构的处理器运行。
1977年,丹尼斯·里奇发表了不依赖于具体机器系统的C语言编译文本《可移植的C语言编译程序》。
C语言继续发展,在1982年,很多有识之士和美国国家标准协会(ANSI)为了使C语言健康地发展下去,决定成立C标准委员会,建立C语言的标准。委员会由硬件厂商、编译器及其他软件工具生产商、软件设计师、顾问、学术界人士、C语言作者和应用程序员组成。1989年,ANSI发布了第一个完整的C语言标准——ANSI X3.159-1989,简称“C89”,不过人们也习惯称其为“ANSI C”。C89在1990年被国际标准化组织(International Standard Organization,ISO)一字不改地采纳,ISO官方给予的名称为:ISO/IEC 9899,所以ISO/IEC9899:1990也通常被简称为“C90”。1999年,在做了一些必要的修正和完善后,ISO发布了新的C语言标准,命名为ISO/IEC 9899:1999,简称“C99”。
在2011年12月8日,ISO又正式发布了新的标准,称为ISO/IEC9899:2011,简称为“C11”。
语言特点
主要特点
C语言是一种结构化语言,它有着清晰的层次,可按照模块的方式对程序进行编写,十分有利于程序的调试,且c语言的处理和表现能力都非常的强大,依靠非常全面的运算符和多样的数据类型,可以轻易完成各种数据结构的构建,通过指针类型更可对内存直接寻址以及对硬件进行直接操作,因此既能够用于开发系统程序,也可用于开发应用软件。通过对C语言进行研究分析,总结出其主要特点如下:
-
简洁的语言
C语言包含的各种控制语句仅有9种,关键字也只有32个,程序的编写要求不严格且以小写字母为主,对许多不必要的部分进行了精简。实际上,语句构成与硬件有关联的较少,且C语言本身不提供与硬件相关的输入输出、文件管理等功能,如需此类功能,需要通过配合编译系统所支持的各类库进行编程,故c语言拥有非常简洁的编译系统。
-
具有结构化的控制语句
C语言是一种结构化的语言,提供的控制语句具有结构化特征,如for语句、if…else语句和switch语句等。可以用于实现函数的逻辑控制,方便面向过程的程序设计。
-
丰富的数据类型
C语言包含的数据类型广泛,不仅包含有传统的字符型、整型、浮点型、数组类型等数据类型,还具有其他编程语言所不具备的数据类型,其中以指针类型数据使用最为灵活,可以通过编程对各种数据结构进行计算。
-
丰富的运算符
C语言包含34个运算符,它将赋值、括号等均视作运算符来操作,使C程序的表达式类型和运算符类型均非常丰富。
-
可对物理地址进行直接操作
C语言允许对硬件内存地址进行直接读写,以此可以实现汇编语言的主要功能,并可直接操作硬件。C语言不但具备高级语言所具有的良好特性,又包含了许多低级语言的优势,故在系统软件编程领域有着广泛的应用。
-
代码具有较好的可移植性
C语言是面向过程的编程语言,用户只需要关注所被解决问题的本身,而不需要花费过多的精力去了解相关硬件,且针对不同的硬件环境,在用C语言实现相同功能时的代码基本一致,不需或仅需进行少量改动便可完成移植,这就意味着,对于一台计算机编写的C程序可以在另一台计算机上轻松地运行,从而极大的减少了程序移植的工作强度。
-
可生成高质量、目标代码执行效率高的程序
与其他高级语言相比,C语言可以生成高质量和高效率的目标代码,故通常应用于对代码质量和执行效率要求较高的嵌入式系统程序的编写。
特有特点
C语言是普适性最强的一种计算机程序编辑语言,它不仅可以发挥出高级编程语言的功用,还具有汇编语言的优点,因此相对于其它编程语言,它具有自己独特的特点。具体体现为以下三个方面:
其一,广泛性。C语言的运算范围的大小直接决定了其优劣性。C语言中包含了34种运算符,因此运算范围要超出许多其它语言,此外其运算结果的表达形式也十分丰富。此外,C语言包含了字符型、指针型等多种数据结构形式,因此,更为庞大的数据结构运算它也可以应付。
其二,简洁性。9类控制语句和32个关键字是C语言所具有的基础特性,使得其在计算机应用程序编写中具有广泛的适用性,不仅可以适用广大编程人员的操作,提高其工作效率,同时还能够支持高级编程,避免了语言切换的繁琐。
其三,结构完善。C语言是一种结构化语言,它可以通过组建模块单位的形式实现模块化的应用程序,在系统描述方面具有显著优势,同时这一特性也使得它能够适应多种不同的编程要求,且执行效率高。
缺点
- C语言的缺点主要表现为数据的封装性弱,这一点使得C在数据的安全性上有很大缺陷,这也是C和C++的一大区别。
- C语言的语法限制不太严格,对变量的类型约束不严格,影响程序的安全性,对数组下标越界不作检查等。从应用的角度,C语言比其他高级语言较难掌握。也就是说,对用C语言的人,要求对程序设计更熟练一些。
变量与常量
变量
什么是变量?
变量是一个抽象概念,你可以理解成变量是一个装物品的盒子。
作用域
描述一个变量的有效范围
生命周期
描述一个变量的生命
全局变量
-
生命周期
整个项目的生命周期(ps:程序结束了,全局变量才死亡)
-
作用域
在整个项目内都有效
局部变量
-
生命周期
进作用域是它生命周期的开始,出作用域是它生命周期的结束。
-
作用域
当前范围内有效(ps:指的是在“{}”内就是它的作用域一旦出了“{}”就会失效)
总结: 能被修改的盒子就是变量,变量的作用域跟生命周期挂钩,出了作用域生命周期也就结束了,在”{}“内定义的变量称为局部变量,在”{}“外定义的变量称为全局变量。
全局变量与局部变量的区别:作用域不同,生命周期不同。
常量
什么是常量?
常量是一个抽象概念,你可以理解成封闭的通明盒子,只能看到里面的东西无法对里面的东西进行更换。
字面常量
字面常量就是123
这样直接显示打出来的内容就是字面常量。
cosnt修饰的常量
const
修饰的常量本质是一个变量,但是它的属性被const
修饰了,具有了常量的无法被修改属性。(ps:简单理解就是一个盒子可以打开里面的东西可以更换,而cosnt
相当于钉子你用这个钉子把盒子开口钉住了,无法取出更换了。)
#define定义的标识符常量
#define
定义的标识符常量,本质是一个字面常量,你看起来使用不像是常量,但是它的底层原理是交换标识符。
枚举常量
枚举常量是一种一个一个列举出了的事物或者其它东西,但是本质都是字面常量。
内置类型
什么是内置类型?
C语言本身自带的类型就是内置类型,这些类型都是关键字。
字符型家族
-
默认有符号
类型前面默认+
signed
,手动显示+signed
效果一样。char //字符型
-
无符号
在类型前面+
unsigned
变成无符号字符型
整形家族
-
默认有符号
类型前面默认+
signed
,手动显示+signed
效果一样。short //短整形 int //整形 long //长整形 long long //更长的整形
-
无符号
在类型前面+
unsigned
变成无符号整形
浮点型家族
-
默认有符号
类型前面默认+
signed
,手动显示+signed
效果一样。float //单精度浮点型 double //双精度浮点型
-
无符号
在类型前面+
unsigned
变成无符号浮点型
无符号类型与有符号类型的区别
无符号类型和有符号类型的唯一区别:
- 无符号只有正数,没有负数,而没有负数可以表示更大的值。
- 有符号有正负数之分,而这样无法表示更大的数。
自定义类型
数组
什么是数组?
数组就是多个相同类型的元素在一起就成了一个组。
数组的创建
数组: 数组类型 数组名[元素个数]
例子:
int arr[3];
注意: c99前的标准元素个数必须是字面常量,c99及之后才支持变量定义元素个数。
结构体
什么是结构体?
结构体是一种描述现实中的复杂对象,C语言内置的类型无法满足这种复杂对象的描述,所以C语言提供了一种自定义类型规则,你可以定义出任意类型,这个类型一般用于描述复杂场景。
例如: 描述一个学生,用C语言的类型是无法满足的,只能用C语言内置类型组合出一个新的类型,这种类型我们称之为结构体。
结构体的创建
结构体语法: struct 新类型名
{…};
例子:
struct students //自定义的学生类型
{
short ID;
short age;
char[20] name;
};
ASCII码表
ASCII码表是用来给计算机换算成相应值的,因为计算机是用电驱动的,电信号只能表示0和1不能表示其它的,而我们这些英文和中文本质都是一个值,不过是经过ASCII码表换过的值。
注释
什么是注释
注释的意思是让编译器无视被注释的内容,被注释的内容是给人看的,机器不需要理解。
注释风格
C语言注释风格
/*sdgag
dfaf
fasdf*/
-
优点
支持大面积注释
-
缺点
不支持嵌套注释
C++注释风格
//dfsafsf
//asdfasf
//daf
- 优点
支持嵌套注释 - 缺点
不支持大面积注释
🎈分支语句
什么是分支语句?
相当于现实生活中的选择,我今天选择喝奶茶呢?还不是不喝奶茶呢?而计算机的选择也是如此,如果你想喝奶茶就打1,那么计算机会给你买一杯奶茶,如果不想喝就什么都不做。
💨分支语句关键字
if和else
用法:
if (表达式)
{
//...
}
else
{
//...
}
else if多分支
用法:
if (表达式1)
{
//...
}
else if (表达式2)
{
//...
}
else if (表达式3)
{
//...
}
//else if...
else
{
//...
}
嵌套if和多分支
if
语句支持任何形式的嵌套
用法:
if (表达式1)
{
if (表达式2)
{
//...
}
}
switch关键字
switch
和if
一样不过唯一的区别就是,它会从匹配到的位置一直往下执行,直到语句执行完毕。
default关键字
default
和else
一样的作用,都是在你啥都不选的时候的默认选项。
case关键字
case
相当于else if
的作用用于多分支选择。
break关键字
break
用于跳出不想执行的场景,因为switch
一旦匹配到会从匹配到的位置一直往下执行,有时候并不需要全部执行就会使用到break
。
switch使用方式
switch (表达式)
{
case 常量1:
//...
break;
case 常量2:
//...
break;
//case 常量3...
default:
//...
break;
}
注意: case
后面必须是常量否则会报error。
总结: 分支语句的使用具体根据场景使用不同场景使用不同分支语句关键字,所有分支语句都支持嵌套。
✨循环语句
什么是循环语句?
和if
语句一样,不过唯一的区别是,需不需要做而不是选择一次,直到不满足条件才停止。
while关键字
while
语句你可以理解成一个if
不过它和if
的区别是while
一直重复执行直到符合某种条件才停止,if
只会执行一次。
用法:
while (表达式)
{
//...
}
for关键字
它和while
一样不过唯一的区别是用法,不过有一点优点是比while
好的,满足条件的方法一定会增加永远不会漏写,而while
当里面的内容过多可能会造成漏写满足条件的方法导致死循环。
用法:
for (表达式1; 表达式2; 表达式3)
{
//...
}
do while关键字
它和前面两个的循环不太一样,它是不管任何条件先执行一次后判断是否需要继续执行。
用法:
do
{
//..
} while (表达式)
🧨🧨🧨求个一键三连!!!