C语言基础知识

发布时间 2023-12-03 16:18:51作者: 魏图图

C语言的特点

关键字(32个):

auto、break、case、char、const、continue、default、do、
double、else、enum、extern、float、for、goto、if、
int、long、register、return、short、signed、static、sizeof、
struct、switch、typedef、union、unsigned、void、volatile、while

C语言允许直接访问物理地址,能进行位(bit)操作,能实现汇编语言的大部分功能,可以直接对硬件进行操作。因此有人把它称为中级语言。

main 是主函数的函数名,表示这是一个主函数
每一个C源程序都必须有,且只能有一个主函数(main函数)

main 函数的三个参数:

int argc —— 整型变量:用于存放命令行参数的个数
char *argc[]—— 字符串数组:表示命令行中的每一个参数
char *envp[]—— 字符串数组:存放环境变量的数组

面向过程和面向对象设计思想

面向过程:以事件为中心的编程思想,分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候依次调用就可以了

面向对象:以事物为中心的编程思想

数据类型

基本类型:其值不可以再分解为其他类型

整型、字符型、实型(浮点型 —— 单精度,双精度)、枚举类型

指针类型:其值用来表示某个变量在内存储器中的地址

构造类型:根据已定义的一个或多个数据类型用构造的方法来定义,即一个构造类型的值可以分解成若干个 “成员” 或 “元素”。每个成员都是一个基本类型或又是一个构造类型

数组类型、结构体类型、共用体(联合)类型

空类型:在调用函数值时,通常应向调用者返回一个函数值。这个返回的函数值是具有一定数据类型的。有一类函数调用后不需要向调用者返回函数值,这种函数可以定义为空类型,空类型的数据说明符为void

常量与变量

在程序执行过程中,其值不发生改变的量称为常量,其值可变的量称为变量

常量

在程序执行过程中,其值不发生改变的量称为常量

符号常量:用标识符代表一个常量。在C语言中,可以用一个标识符来表示一个常量,称之为符号常量。在使用之前必须先定义,其一般形式为:

#define 标识符 常量

:其中#define也是一条预处理命令(预处理命令都以"*"开头),称为宏定义命令,其功能是把该标识符定义为其后的常量值。一经定义,以后在程序中所有出现该标识符的地方均代之该常量值。

  • 习惯上,符号常量的标识符用大写字母,变量标识符用小写字母,以示区别。

整型常量

  1. 十进制整型常数:无前缀(在程序中是根据前缀来区分各种进制数的),数码值为 0 ~ 9,以下是合法的十进制整型常数

237、-568、65535、1627

  1. 八进制整型常数:八进制整型常数必须以 0 开头(即 0 作为八进制的前缀)。数码取值 0 ~ 7。八进制数通常是无符号数,以下是合法的八进制整型常数

015(十进制为13)、0101(十进制为65)、0177777(十进制为65535)

  1. 十六进制整型常数:十六进制整型常数前缀为 0X 或 0x。其数码取值为 0 ~ 9,A ~ F 或 a ~ f。以下是合法的十六进制整型常数

0X2A(十进制为42)、0XA0(十进制为160)、0XFFFF(十进制为65535)

十进制无符号整型常数的范围为 0 ~ 65535,有符号数为 -32768 ~ +32767。八进制无符号的表示范围为 0 ~ 0177777。十六进制无符号数的表示范围为 0X0 ~ 0XFFFF 或 0x0 ~ 0xFFFF。如果使用的数超过了上述范围,就必须使用长整型数来表示,长整型数是用后缀 ”L“ 或者 ”l“ 来表示的。

实型(浮点型)常量

实型也称为浮点型。实型常量也称为实数或者浮点数。在C语言中,实数只采用十进制,它有两种形式:十进制小数形式,指数形式

  1. 十进制数形式:由数码 0 ~ 9 和小数点组成(必须有小数点),例如(以下均为合法实数):

0.0、25.0、5.789、0.13、5.、-267.8230

  1. 指数形式:由十进制数,加阶码标志"e""E"组成
    一般形式为:aEn(a 为十进制数, n 为十进制整数),以下为合法形式:

2.1E5、3.7E-2、0.5E7、-2.8E-2

注意:标准C允许浮点数使用后缀。后缀为"f""F"即表示该数为浮点数。如 356f 和 356. 是等价的。

字符型常量

字符常量是用单引号括起来的一个字符
例如:
'a','b','=','+','?'等这些都是合法字符常量。

在 C 语言中,字符常量有以下特点:

  1. 字符常量只能用单引号括起来,不能用双引号括起来。
  2. 字符常量只能是单个字符,不能是字符串。
  3. 字符可以是字符集中的任意字符。但数字被定义为字符型之后就不能参与数值运算。如'5'和 5 是不同的。'5'是字符常量,不能参与运算。

字符串常量

字符串常量是由一对双引号括起来的字符序列。例如:
"CHINA","C program","$12.5"等都是合法的字符串常量

注意:字符串常量和字符常量是不同的量(char 只占八位),区别如下:

  1. 字符常量由单引号括起来,字符串常量由双引号括起来。
  2. 字符常量只能是单个字符,字符串常量可以是单个或多个字符。
  3. 可以把一个字符常量赋值予一个字符变量,但不能把字符串常量赋予一个字符变量。即:可以char a = 'a'; 不能char a = "a";
  4. 字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字符数加一。增加的一个字节中存放字符"\0"(ASCII码为 0),这是字符串结束的标志。

变量

在程序执行过程中,其值可变的量称为变量

一个变量应该有一个名字,在内存中占据一定的存储单元。变量的定义放在变量使用之前。一般放在函数体的开头部分。要区分变量名和变量值以及变量的地址。

整型变量

整型数据在内存中以二进制形式保存

补充

内存中的二进制存储(一个字节 BYTE = 8位 bit)

数值是以补码表示的

  • 正数的补码和原码相同
  • 负数的补码是对其取反码再加一

整型变量的分类
  1. 基本型:类型说明符为 int ,在内存中占用 4个字节

  2. 短整型:类型说明符为 short int 或 short,所占字节和取值范围与基本型相同

  3. 长整型:类型说明符为 long int 或 long,在内存中占 4 个字节

  4. 无符号型:类型说明符为 unsigned

注意:占多少字节跟系统和编译器规定有关

整型变量的定义

变量定义的一般形式为:
类型说明符 变量名标识符,变量名标识符,...;
例如:

int a,b,c;    //(a,b,c为整型变量)
long x,y;     //(x,y为长整型变量)
unsigned p,q; //(p,q为无符号整型变量)

注意

  • 允许在一个类型说明符后,定义多个相同类型的变量。各个变量名之间用逗号","相隔。类型说明符与变量名之间至少用一个空格间隔。

  • 最后一个变量名之后必须以分号";"结尾。

  • 变量定义必须放在变量使用之间。一般放在函数体的开头部分。

  • 用户定义的合法标识符需满足以下两个要求:

标识符只能由字母,数字和下划线组成。
标识符不能以数字开头

整型数据的溢出
#include <stdio.h>

int main()
{
	short int a,b;
	a = 32767;
	b = a + 1;
	printf("a = %d,b = %d\n",a,b);
	return 0;
}

输出结果:

a = 32767,b = -32768

结果解析:

32767:0111 1111 1111 1111
-32768:1000 0000 0000 0000
(整型数据在内存中以补码方式存储)

实型(浮点型)变量

实型数据一般占四个字节(32位)内存空间。按指数形式存储。实数 3.14159 在内存中的存储形式如下表:

符号 小数部分 指数部分
+ .314159 1
  • 小数部分占的位( bit )数愈多,数的有效数字愈多,精度愈高
  • 指数部分占的位愈多,则能表示的数值范围愈大。
实型(浮点型)变量的分类

实型变量分为:

单精度(float 型)
双精度(double 型)
长双精度(long double 型)

  • 在 C 语言中,单精度型占 4 个字节(32位)内存空间,其数值范围为 3.4E-38 ~ 3.4E+38,只能提供 7 位有效数字。

  • 双精度型占 8 个字节(64位)内存空间,其数值范围为 1.7E-308 ~ 1.7E+308,可提供 16 位有效数字。

实型(浮点型)数据的舍入误差

由于实型变量是由有限的存储单元组成的,因此能提供的有效数字中总是有限的。如下例:

#include <stdio.h>

int main()
{
	float a,b;
	a = 123456.789e5;
	b = a + 20;
	printf("a = %f,b = %f\n",a,b);
	return 0;
}

输出结果:

a = 12345678848.00000000,b = 12345678848.00000000

字符型变量

字符变量用来存储字符常量,即单个字符。

字符变量的类型说明符是char。字符变量类型定义的格式和书写规则都与整型变量相同。例如:
char a,b;

转义字符

转义字符是一种特殊的字符常量。转移字符以反斜线'\'开头,后跟一个或者几个字符。

转义字符具有特定的含义,不同于字符原有的意义,故称为转义字符。例如,在printf函数的格式串中用到的'\n'就是一个转义字符,其意义是”回车换行“。转义字符主要用来表示那些用一般字符不便于表示的控制代码。

常用的转义字符及其含义
转义字符 意义
\n 回车换行
\t 横向跳到下一制表位置
\b 退格
\f 换页
\r 回车
\v 纵向跳到下一制表位置
\\ 反斜线符"\"
\' 单引号
\" 双引号
\a 鸣铃声
\ddd 1~3位八进制所代表的字符
\xhh 1~2位十六进制所代表的字符
\0 空字符
字符数据在内存中的存储形式及使用方法

每个字符变量被分配一个字节的内存空间,因此只能存放一个字符。字符值是以 ASCII 码的形式存放在变量的内存单元之中的。例如:对字符变量 a , b 赋值

#include <stdio.h>

int main()
{
	//大写字母A~F的ASCII码是从65~90
	//小写字母a~f的ASCII码是从97~122
	//数字0~9的ASCII码是48~57
	char a,b;
	a = 'x';
	b = '7';
	printf("%d %d",a,b);   //打印 a 和 b 字符数据对应的 ASCII 码
	return 0;
}

输出结果:

120 55

数值型数据之间的运算

数据类型转换

变量的数据类型是可以转换的。转换的方法有两种,一种是自动转换,一种是强制转换

自动类型转换

自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。自动转换遵循以下规则:

  1. 若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

  2. 转换按数据长度增加的方向进行,以保证精度不降低。如 int 型和 long 型运算时,先把 int 型转成 long 型再进行运算。

  3. 所有的浮点型运算都是以双精度进行的,即使仅含有 float 单精度运算的表达式,也要先转为 double 型,再作运算。

  4. char 型和 short 型参与运算时,必须先转为 int 型。

  5. 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。

下图是自动转换的规则:

强制类型转换

强制类型转换是通过类型转换运算来实现的。
其一般形式为:
(类型说明符)(表达式)
其功能是把表达式的运算结果强制转换成类型说明符所表达的类型。例如:
(float)a //把 a 转换为实型
(int)(x+y) //把 x+y 的结果转换为整型

注意

  1. 类型说明符和表达式都必须括号(单个变量可以不加括号),如果把(int)(x+y)写成(int)x+y,则是把 x 转为 int 型再与 y 相加。
  2. 无论是强制转换还是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型。

算术运算符和算术表达式

基本的算术运算符

  • 加法运算符"+":加法运算符为双目运算符,即应有两个量参与加法运算。如 a + b、4 + 8 等。自左向右结合
  • 减法运算符"-":减法运算符为双目运算符。但"-"也可以作负值运算符,此时为单目运算,如 -x、-5 等自右向左结合
  • 乘法运算符"*":双目运算,自左向右结合
  • 除法运算符"/":双目运算,自左向右结合。参与运算量均为整型时,结果也为整型,舍去小数。如果运算量中有一个是实型,则结果为双精度实型。
  • 取模运算符"%":双目运算,自左向右结合参与运算量必须均为整型

运算符优先级和结合性

! ( 逻辑非 ) > 算术运算符 > 关系运算符 > && ( 逻辑与 ) > || ( 逻辑或 ) > 赋值运算符 > 逗号运算符

(详情见以下)
![C语言运算符优先级和结合性一览表]

自增、自减运算符

自加、自减运算符均为单目运算符,自右向左结合,可以有以下几种形式:

++ i;:i 自增 1 后再参与其他运算。
-- i;:i 自减 1 后再参与其他运算。
i ++;:i 参与运算后,i 的值再自增 1。
i --;:i 参与运算后,i 的值再自减 1。

赋值运算符和赋值表达式

赋值运算符

简单赋值运算符和表达式:简单赋值运算符记为"=",由"="连接的式子称为赋值表达式。其一般形式为:
变量 = 表达式
例如:

x = a + b;
w = sin(a) + sin(b);
y = i + j;

赋值表达式的功能是计算表达式的值再赋予左边的变量,即自右向左结合

如果赋值运算符两边的数据类型不相同,系统将自动进行类型转换,即把赋值号右边的类型换成左边的类型。具体规定如下:

  1. 实型赋予整型,舍去小数部分。

  2. 整型赋予实型,数值不变,但以浮点形式存放,即增加小数部分(小数部分的值为 0)

  3. 字符型赋予整型,由于字符型为一个字节,而整型为四个字节,故将字符的ASCII码值放到整型量的第八位,中,高八位均为 0,只把低八位赋予字符量。

复合的赋值运算符

在赋值符"="之前加上其他双目运算符可构成复合赋值符。如"+="、"-="、"*="、"/="、"%="、"<<="、">>="、"&="、"^="、"!="

逗号运算符和逗号表达式

在 C 语言中逗号","也是一种运算符,称为逗号运算符。其功能是吧两个表达式连接起来组成一个表达式,称为逗号表达式。其一般形式为:
表达式1,表达式2

其求值过程是分别求两个表达式的值,并以表达式2的值作为整个逗号表达式的值。