一.关键字

说明:

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个关键字:inlinerestrict_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 表示空类型(无类型)。通常应用于函数的返回值类型、函数的参数、指针类型。

image-20230810152811098

四.基本数据类型

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 类型,需要在该字面量末尾加上后缀 lL ,编译器会把这个字面量的类型指定为 long 。

long x = 123L; //或者写成 123l

如果希望字面量指定为long long类型,则后缀以llLL结尾。

long long y = 123LL;

如果希望指定为无符号整数 unsigned int ,可以使用后缀 uU

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类型的,需要以Ff作为后缀

如果定义long double类型的,需要以lL作为后缀

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;
}
最后修改:2024 年 03 月 11 日
如果觉得我的文章对你有用,请随意赞赏