一.关键字
说明:
1、ANSI C、C99和C11,它们之间差别并不大,在大多数情况下,它们都是和谐共处的
2、不需要死记硬背,学到哪里记到哪里即可
**定义:**被C语言赋予了特殊含义,用做专门用途的字符串(或单词)。
**特点:**全部关键字都是小写字母
。
传统的C语言(ANSI C)有32个关键字。如下:
类型 | 具体关键字 |
---|---|
控制语句关键字(12 个) | break, case, continue, default, do, else, for, goto, if, return, switch, while |
数据类型关键字(12 个) | char, enum, double, long, float, int, short, signed, struct, unsigned, union, void |
存储类型关键字(4 个) | auto, extern, register, static |
其他关键字(4 个) | const, sizeof, typedef, volatile |
后续,1999年,C99标准增加了5个关键字:inline
、restrict
、_Bool
、_Complex
和_Imaginary
。
2011年,C11标准又增加了7个关键字:_Alignas
、_Alignof
、_Atomic
、_Static_assert
、_Noreturn
、_Thread_local
和_Generic
。
二.标识符
凡是可以自己取名字的都是标识符
C语言中变量、函数、数组名、结构体等要素命名时使用的字符序列,称为标识符。
1.标识符的命名规则
- 只能由26个英文字母大小写,0-9 或 _ 组成
- 数字不可以开头
- 不可以是关键字,但可以包含关键字
- C99和C11允许使用更长的标识符名,但是编译器只识别前63个字符。(会忽略超出的字符)
- 不允许有空格。
- 严格区分大小写字母。比如:Hello、hello是不同的标识符。
三.变量
1.C语言中的声明格式
数据类型 变量名 = 变量值
2.注意事项
- C语言中每个变量必须先声明,后使用
- 不同的数据类型,占用的空间大小不一样
- 一旦声明,变量的类型就不能在运行时修改
3.变量的分类
变量可以按照数据类型分类,也可以按声明位置分类(全局变量、局部变量)
(1)按照数据类型分类
注意事项
注意1:在C语言中,没有字符串类型,其是使用字符数组表示字符串的。
注意2:这里列举的是C语言的常用类型,后续C语言版本还有新增的类型。
注意3:空类型:void 表示空类型(无类型)。通常应用于函数的返回值类型、函数的参数、指针类型。
四.基本数据类型
1.整型
C语言规定了如下的几类整型:短整型(short)、整型(int)、长整型(long)、更长的整型(long long)
(1) signed和unsigned修饰符
- 使用
signed 修饰
,表示该类型的变量是带符号位的,有正负号,可以表示负值。默认是signed
。 - 使用
unsigned 修饰
,表示该类型的变量是不带符号位的,没有有正负号,只能表示零和正整数。
(2)常见的整型信息
类型 | 修饰符 | 占用空间 | 取值范围 |
---|---|---|---|
short [int] | signed | 2个字节(=16位) | -32768 ~ 32767 (-$2^{15}$ ~ $2^{15}$-1) |
short [int] | unsigned | 2个字节(=16位) | 0 ~ 65535 (0 ~ $2^{16}$-1) |
int | signed | 通常4个字节 | -2147483648 ~ 2147483647 (-$2^{31}$ ~ $2^{31}$-1) |
int | unsigned | 通常4个字节 | 0 ~ 4294967295 (0 ~ $2^{32}$-1) |
long [int] | signed | 4个或8个字节 | 4字节时:-2147483648 ~ 2147483647 (-$2^{31}$ ~ $2^{31}$-1) |
long [int] | unsigned | 4个或8个字节 | 4字节时:-0 ~ 4294967295 (0 ~ $2^{32}$-1) |
long long int是C99新增
的:
类型 | 修饰符 | 占用空间 | 取值范围 |
---|---|---|---|
long long [int] | signed | 8个字节(=64位) | -9223372036854775808~ 9223372036854775807(-$2^{63}$ ~ $2^{63}$-1) |
long long [int] | unsigned | 8个字节(=64位) | 0 ~ 18446744073709551615(0 ~ $2^{64}$-1) |
(3)编译器影响大小
在C语言中,不同的数据类型占用的的大小是与当前计算机的编译器有关的,不同的编译器会导致同一数据类型占用的大小出现区别。
具体情况:
目前主流的是64位编译器,目前刚学只关注64位即可
类型 | 16位编译器 | 32位编译器 | 64位编译器 |
---|---|---|---|
short int | 2字节 | 2字节 | 2字节 |
int | 2字节 | 4字节 | 4字节 |
unsigned int | 2字节 | 4字节 | 4字节 |
long | 4字节 | 4字节 | 8字节 |
unsigned long | 4字节 | 4字节 | 8字节 |
long long | 8字节 | 8字节 | 8字节 |
(4)最常用的整形
最常用的整型类型为: int类型
整数型变量,默认为: int类型
(5)关于后缀
可以通过添加后缀的形式,指定字面量的类型
编译器将一个整数字面量指定为 int 类型,但是如果希望将其指定为 long 类型,需要在该字面量末尾加上后缀 l
或 L
,编译器会把这个字面量的类型指定为 long 。
long x = 123L; //或者写成 123l
如果希望字面量指定为long long类型,则后缀以ll
或LL
结尾。
long long y = 123LL;
如果希望指定为无符号整数 unsigned int ,可以使用后缀 u
或 U
。
unsigned int x = 123U;
L 和 U 可以结合使用,表示 unsigned long 类型。 L 和 U 的大小写和组合顺序无所谓。
u 还可以与其他整数后缀结合,放在前面或后面都可以,比如 10UL 、 10ULL 和 10LLU 都是合法的。
unsigned long int x = 1234UL;
unsigned long long int x = 1234ULL;
2.浮点类型
在C语言中,浮点型变量分为三种:单精度浮点型(float)、双精度浮点型(double)、长双精度浮点型(long double)。
(1)常见浮点型信息
- C语言的第3种浮点类型是long double,以满足比double类型更高的精度要求。
- 浮点型变量不能使用signed或unsigned修饰符
- 最常用的浮点类型为:double 类型,因为精度比float高。
- 浮点型常量,默认为 double 类型。
类型 | 占用空间 | 取值范围 |
---|---|---|
float | 4个字节 (=32位) | $-1.410^{-45}$ ~ $-3.410^{+38}$,$1.410^{-45}$ ~ $3.410^{+38}$ |
double | 8个字节 (=64位) | $-4.910^{-324}$ ~ $-1.710^{+308}$,$4.910^{-324}$ ~ $1.710^{+308}$ |
long double | 12个字节(=96位) | 太大了... |
(2)编译器影响大小
类型 | 16位编译器 | 32位编译器 | 64位编译器 |
---|---|---|---|
float | 4字节 | 4字节 | 4字节 |
double | 8字节 | 8字节 | 8字节 |
(3)关于后缀
如果定义float
类型的,需要以F
或f
作为后缀
如果定义long double类型的,需要以l
或L
作为后缀
3.字符类型
在C语言中,是不存在字符串的。
C语言中,使用 char 关键字来表示字符型,用于存储一个单一字符
。
(1)char的赋值
① 单引号包裹字符
char c = 'A'; //为一个char类型的变量赋值字符'A'
② ASCII赋值
char c = 97;//等同于赋了个"a"
(2)转义字符
字符形式 | 含义 |
---|---|
\n |
换行符(光标移动到下行行首) |
\t |
水平制表符,光标移到下一个Tab位置 |
\' |
单引号字符 ' |
\" |
双引号字符 " |
\\ |
反斜杠字符 ’\’ |
\r |
回车符,光标移到本行开头 |
\0 |
null 字符,代表没有内容。注意,这个值不等于数字0。 |
\b |
退格键,光标回退一个字符,但不删除字符 |
4.布尔类型
1.C语言中没有原生的布尔数据类型,多采用1和0表示真假。
2.后继在C99标准中是有添加类型_Bool
表示布尔值的,即逻辑值true和false,但其依旧是整数类型的"别名",本质就是上面那个
(1)C89标准
直接使用1和0表示真假代码阅读性差,可以借助C语言的宏定义使其更加直观,增加啊阅读性
C语言标准(C89)没有为布尔值单独设置一个类型,所以在判断真假时,使用整数 0 表示假,所有非0表示真。
① 标准写法:
int main(){
int handsome = 1;
if (handsome) {
printf("我好帅!\n");
}
return 0;
}
② 使用宏定义:
// 定义布尔类型的宏
#define BOOL int //可以使用 typedef int BOOL; 替换
#define TRUE 1
#define FALSE 0
int main(){
BOOL handsome = TRUE;
if(handsome){
printf("好帅~");
}
return 0;
}
(2)C99标准
C99 标准添加了类型
_Bool
,表示布尔值,即逻辑值true和false。
① _Bool类型
它不算布尔类型,最多算个别名
但是,这个类型的值其实只是整数类型的别名,还是使用 0 表示false, 1 表示true,其它非0的值都会被存储为1。所以_Bool类型实际上也是一种整数类型。
#include
int main() {
_Bool isFlag = 1;
if (isFlag)
printf("你好毒~~\n");
return 0;
}
② stdbool.h头文件
就是定义了一些名称,使代码看起来更加自然了。
C99还提供了一个头文件 stdbool.h,文件中定义了bool
代表_Bool
,并且定义了 true 代表 1 、 false 代表 0 。只要加载这个头文件,就可以使用 bool 定义布尔值类型,以及 false 和 true 表示真假。
#include
#include
int main() {
bool isFlag = true;
if (isFlag)
printf("你好毒~~\n");
return 0;
}
5.变量间的运算规则
在C语言编程中,经常需要对不同类型的数据进行运算,运算前需要先转换为同一类型,再运算。
(1)隐式类型转换
字节宽度较小
的类型会自动转换为字节宽度较大
的数据类型
(2)强制类型转换
格式:(类型名称)(变量、常量或表达式)
例子:
double x = 12.3;
int y = 10;
int z = (int)x + y; //将变量x的值转换成int后,再与y相加
(3)运算的溢出问题
对于溢出问题编译器是不会进行报错的,使用时要注意
当存放的数值超过当前数据类型可以保存的最大范围时(小于最小值或大于最大值),其所拥有的二进制位不够存储时就会发生异常。
- 大于最大值: 向上溢出(overflow)
- 小于最小值: 向下溢出(underflow)
例子
x 是 unsign char 类型,最大值是255 (二进制 11111111 ),加 1 后就发生了溢出, 256 (二进制 100000000 )的最高位 1 被丢弃,剩下的值就是 0
unsigned char x = 255;
x = x + 1;
printf("%d\n", x); // 0
五.变量
1.C语言中常量的分类
- 字面变量
-
#define
定义的表示符变量 -
const
修饰的常变量 - 枚举变量
2.定义常量的方式
(1)使用#define定义
这种方式是在文件开头用 #define 来定义常量,也叫作“宏定义”。所谓宏定义,就是用一个标识符来表示一个常量值,如果在后面的代码中出现了该标识符,那么编译时就全部替换成指定的常量值。即用宏体替换所有宏名,简称宏替换
。
① 格式
习惯上,宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。
定义格式:#define 符号常量名 常量值
- 符号常量名,称为
宏体
,属于标识符,一般定义时用大写字母表示。 - 常量值,称为
宏名
,可以是数值常量,也可以是字符常量。
② 举例
跟#include一样,“#”开头的语句都是“预处理语句”,在编译之前,预处理器会查找程序中所有的“ZERO”,并把它替换成0,这个过程称为预编译处理。
然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码 (OBJ文件)。
代码:
#include
#define ZERO 0 //#define的标识符常量
int main() {
printf("zero = %d\n", ZERO);
return 0;
}
返回值:
zero = 0
(2)使用const限定符
跟使用 #define定义宏常量相比,const限定符可以声明数据类型,而且会在编译阶段进行安全检查,在运行时才完成替换,更加安全和方便
C99中新的声明方式,这种方式跟定义一个变量是一样的,只需要在变量的数据类型前再加上一个const关键字,这被称为“限定符”。
① 格式
注:const修饰的对象一旦创建就不能改变,所以必须初始化
const 数据类型 常量名 = 常量值;
② 例子
#include
int main(){
//const 修饰的常变量
const float PI = 3.14f;
//PI = 5.14;//是不能直接修改的!
return 0;
}
(3)定义枚举变量
举例:
#include
//使用enum定义枚举类
enum Sex{
//括号中的MALE,FEMALE,SECRET是枚举常量
MALE,
FEMALE,
SECRET
};
int main(){
//枚举常量
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
//注:枚举常量默认是从0开始,依次向下递增1的
return 0;
}
六.输入/输出函数
c语言本身没有提供专门的输入输出语句,所有的输入输出都是由调用标准库函数中的输入输出函数来实现的。
输入函数:scanf() 、 getchar()、gets():
- scanf(),是格式输入函数,可接收
任意类型
的数据。 - getchar(),是
字符
输入函数, 只能接收单个字符
。 - gets(),是
字符串
输入函数。
输出函数:printf() 、 putchar()、puts():
- printf(),是格式输出函数,可按指定的格式显示任意类型的数据。
- putchar(),
字符
显示函数,只能显示单个字符
。 - puts(),是
字符串
输出函数。
1. scanf()的使用
类似于Java中的Scanner,可以接收任意数据。
scanf()函数的作用:把从键盘上输入的数据根据找到的地址存入内存中,即给变量赋值。
(1)格式
格式:scanf("格式控制字符串",参数地址列表);
- 格式控制字符串:约定输入数据的类型和格式,参数的个数必须与变量地址的个数一致。
-
参数地址列表:以逗号 ", "分隔的
输入数据变量地址
序列- 这里要输入变量的地址值
- 使用
&
寻址符,配合变量名即可表示对象在内存中的地址了- 例如
&a
表示对象a在内存中的地址
- 例如
举例:
scanf("%d%d%d",&a,&b,&c)
注意,
- 如果scanf中%d是连着写的,如“
%d%d%d
”,在输入数据时,数据之间不可以用逗号分隔,只能用空白字符(空格或tab键或者回车键)分隔。- 即“
2(空格)3(tab)4
” 或 “2(tab)3(回车)4
”等。
- 即“
- 如果是“
%d,%d,%d
”,则在输入数据时需要加","- 如“
2,3,4
”。
- 如“
举例1:计算圆的面积,其半径由用户指定
#include
int main() {
float radius, area;
printf("请输入半径值: ");
scanf("%f", &radius); //输入半径
area = 3.14 * radius * radius;
printf("area=%f\n", area); //输出圆的面积
return 0;
}
注意:变量名之前要加上&运算符,表示取变量的地址,如“&a,&b”。否则将会出现错误。
举例2:输入一个整数,求其绝对值。
#include
int main() {
int num;
printf("输入一个整数:");
scanf("%d", &num);
int absNum = num;
if(absNum < 0)
absNum = -absNum;
printf("\n 整数:%d--->绝对值为:%d\n", num, absNum);
return 0;
}
举例3:输入多个变量的值,求乘积
#include
int main() {
int a,b,c;
printf("请输入整数a,b:");
scanf("%d%d",&a,&b);
c=a*b;
printf("%d*%d=%d\n",a,b,c);
return 0;
}
2.getchar()与putchar()的使用
getchar():输入字符数据
- 格式:
getchar()
- 功能:从键盘缓冲区读入一个字符
putchar():输出字符
- 格式:
putchar(ch)
,其中ch是一个字符变量 - 功能:从标准输出设备输出一个字符
举例:
#include
int main() {
char c = 0;
putchar('A'); //输出单个字符A
putchar(c); //输出变量c的ASCII对应字符
putchar('\n'); //执行换行效果,屏幕不显示
}
#include
int main() {
char ch;
ch = getchar();
putchar(ch);
return 0;
}
3.gets()与puts()的使用
(1)puts()
puts() 是一个用于输出字符串的标准库函数,其原型定义在
头文件中。
① 作用
**作用:**将一个以 null 字符(\0
)结尾的字符串打印到标准输出(通常是控制台)上,并自动添加一个换行符。
② 代码
int main() {
char str1[]={"China\nBeijing"};
char str2[] = "helloworld";
puts(str1);
puts(str2);
return 0;
}
(2)gets()
① 作用
读取标准输入设备输入的字符串,直到遇到[Enter]键才结束
char str[20]; //定义一个数组
gets(str); //获取输入的字符串,存放到字符数组中
② 例子
int main() {
char str[15];
printf("enter your name:");
gets(str); //输入字符串至数组变量str
printf("your name is ");
puts(str); //输出字符串
return 0;
}
七.局部/全局变量
在C语言中,局部变量和全局变量可以重名,实际使用时按照就近原则调用。
1.概念
(1)局部变量
在函数体内定义
的变量,也称内部变量。局部变量只能在定义它的函数中使用。
(2)全局变量
在函数之外
定义的变量称为外部变量,外部变量是全局变量
(也称全程变量)。
2.示例
当局部变量和全局变量同名的时候,局部变量优先使用。
#include
int global = 2023;//全局变量
int main(){
int local = 2022;//局部变量
int global = 2024;//局部变量
printf("global = %d\n", global);//global = 2024
return 0;
}