本章学习:C语言的运行机制、常见的库文件、代码框架、标识符的命名规则、C语言关键字、常量学习、输入输出函数、局部变量与全局变量
一、C语言运行机制
整个过程:编写.C文件、编译成.obj的二进制机器指令、结合C语言的库文件链接形成可执行的二进制.exe、最终运行输出结果。
C语言常见的库文件有:
| 头文件 | 常用函数 / 内容 | 高频考点 |
|---|---|---|
<stdio.h> | printf、scanf、fopen、fread、fwrite | 输入输出、文件操作 |
<string.h> | strlen、strcpy、strncpy、memcpy、memset、strcmp | strcpy 与 memcpy 区别、越界风险 |
<stdlib.h> | malloc、calloc、realloc、free、atoi、exit、qsort、bsearch | malloc 底层、内存泄漏 |
<math.h> | sqrt、pow、sin、abs(需链接-lm) | 编译时记得加 -lm |
<ctype.h> | isdigit、isalpha、toupper、tolower | 字符分类 |
<time.h> | time、clock、gettimeofday(POSIX) | 计时、时间戳 |
<assert.h> | assert() | 调试断言 |
<errno.h> | errno、perror、strerror | 错误码处理 |
<stdarg.h> | va_list、va_start、va_end | 可变参数实现 |
<stdint.h> | int8_t、uint16_t、int32_t | 嵌入式必考:定长整型,跨平台 / 跨 MCU 可移植 |
<stdbool.h> | true、false | C99 后可用布尔类型 |
<limits.h> | INT_MAX、CHAR_BIT 等 | 各类型取值范围 |
<stddef.h> | NULL、size_t、ptrdiff_t、offsetof | 常见宏定义 |
<setjmp.h> | setjmp、longjmp | 异常跳转(低层) |
基本的代码框架:
#include<stdio.h> //C语言的编译头文件库 int main() //每一个程序(或工程)可以定义很多函数(后面讲),但有且只有一个main()函数,作为程序执行的入口,空括号(),表示 main 不接受任何参数。 //写在main之前的“int”称为关键字,代表数据类型是整型。它是main()的返回值类型。即在执行main()函数后会得到一个整型值,无返回值可定义void类型 { return 0;//int数据类型下不能省略 }其中:占位符的第一个字符是%,第二个字符表示占位符的类型。printf()的占位符有许多种类,与C语言的数据类型相对应。其中常见的类型输出格式为int(%d)、char(%c)、float(%f)、八进制整数(%o)、十六进制(%x)、String字符串(%s)、科学技术法(%e)等等;
二、C语言的变量命名规则
标识符组成由:字母、数字、下划线_,但是命名规则必须是字母或者下划线_为开头;变量名不能有空格且不能为关键字(下面会讲);
其中长度也有限制:
C89标准规定标识符长度不得超过31个字符。
C99标准规定标识符长度不得超过63个字符。
注:标识符如果超出编译器所支持的标准就会忽略后续的字符长度;
传统的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 |
2.1 变量的的作用:
变量是程序中不可或缺的组成单位,最基本的存储单元;一个变量就是一个存储单元,就会分配存储空间;
变量的定义一般按照以下的格式进行
数据类型变量名;//声明变量的语句必须以分号结尾、
举例:
int length;
char ID;
//基本数据类型【整型、浮点型、字符型】 整型int、短整型short int、长整型long int 浮点型可分为:单精度型float、双精度型double 字符型:单字节char、字符串则用字符数组表示 //构造类型 数组类型、结构体类型struct、共用体类型union、枚举类型enum //空类型 void //指针类型 *三、C语言的常量
常量在程序运行过程中其值不能被修改,是 C 语言中最基础的数据形式之一。按照书写形式和使用方式,常见的常量可以分为以下几类。
3.1 字面常量(直接常量)
直接写在代码中的具体数值或字符,不需要额外定义即可使用。
整型常量:如
100、-25、0。可以写成十进制、八进制(以0开头,如0755)或十六进制(以0x开头,如0xFF)。实型(浮点)常量:如
3.14、-0.5,也支持科学计数法1.2e3(即 1200.0)。默认是double类型,加后缀f表示float,如3.14f。字符常量:用单引号括起来的单个字符,如
'A'、'9'、'\n'。字符常量在内存中存储的是其 ASCII 码值,因此'A'等价于65。字符串常量:用双引号括起来的字符序列,如
"hello"、"C语言"。字符串末尾会自动添加结束符'\0',所以"abc"实际占用 4 个字节。
3.2 转义字符常量
以反斜杠\开头的特殊字符,用于表示无法直接输入的字符。
| 转义字符 | 含义 |
|---|---|
\n | 换行 |
\t | 水平制表符(Tab) |
\\ | 反斜杠本身 |
\' | 单引号 |
\" | 双引号 |
\0 | 空字符(字符串结束标志) |
\ddd | 三位八进制数表示的字符,如\101表示'A' |
\xhh | 十六进制数表示的字符,如\x41表示'A' |
3.3 宏常量(符号常量)
使用#define预处理指令定义的常量,在编译前由预处理器进行文本替换,就是用一个标识符来表示一个常量值。宏名用大写字母表示,以便于与变量区别;
格式:#define符号常量名 常量值
#include <stdio.h> #define PI 3.14159 #define MAX_SIZE 100 int main(void) { double r = 2.0; printf("面积 = %f\n", PI * r * r); printf("最大容量 = %d\n", MAX_SIZE); return 0; }注意:跟#include一样,“#”开头的语句都是“预处理语句”,在编译之 前,预处理器会查找程序中所有的“PI ”,并把它替换成3.14159,这 个过程称为预编译处理。宏常量只是简单的文本替换,没有类型检查,因此建议在定义时加上括号,避免运算优先级问题,例如#define SQUARE(x) ((x) * (x))。
3.4 const 修饰的常量
C99中新的声明方式,这种方式跟定义一个变量是一样的,只需要在变量的数据类型前再加上一个const关键字,这被称为“限定符”。使用const关键字修饰的变量,其值在初始化后不能被修改,具有类型检查,是更推荐的常量定义方式。
格式:const数据类型 常量名=常量值;
#include <stdio.h> int main(void) { const double PI = 3.14159; const int MAX_SIZE = 100; printf("PI = %f\n", PI); printf("MAX_SIZE = %d\n", MAX_SIZE); // PI = 3.14; // 编译错误:const 变量不能被修改 return 0; }const常量与宏常量的区别:
const常量有数据类型,编译器会进行类型检查;宏常量只是文本替换。const常量在调试时可以看到变量名和值;宏常量在预处理后已不存在。const常量占用内存(可能被优化),宏常量不占用内存。
3.5 枚举常量
使用enum关键字定义的一组有名字的整型常量,适合表示一组相关的状态或选项。
#include <stdio.h> enum Weekday { MON = 1, TUE, WED, THU, FRI, SAT, SUN }; int main(void) { enum Weekday today = WED; printf("today = %d\n", today); // 输出 3 return 0; }枚举常量的值默认从 0 开始依次递增,也可以手动指定初始值,后续未指定的成员会在此基础上继续递增。
3.6 常见常量对比
| 常量类型 | 定义方式 | 特点 |
|---|---|---|
字面常量 |
| 直接书写,无需定义 |
宏常量 |
| 预处理替换,无类型检查 |
const 常量 |
| 有类型检查,推荐使用 |
枚举常量 |
| 一组相关的整型常量 |
小结:在实际开发中,对于简单的数值常量优先使用const定义,既能保证类型安全,又便于调试;对于需要表示一组相关状态的场景,使用enum更加清晰;宏常量则多用于条件编译或需要跨文件共享的配置项。
四、C语言的输入输出
所谓输入输出是以计算机主机为主体而言的。输出:从计算外部输出设备(显示器、打印机)输出数据。输入:从输入设备(键盘、鼠标、扫描仪)向计算机输入数据。
C语言本身没有提供专门的输入输出语句,所有的输入输出都是由调用标准库函数中的输入输出函数来实现的。常用的输入输出函数如下所示:
输入函数:scanf() 、 getchar()、gets():
scanf(),是格式输入函数,可接收任意类型的数据。
getchar(),是字符输入函数, 只能接收单个字符。
gets(),是字符串输入函数。
输出函数:printf() 、 putchar()、puts():
printf(),是格式输出函数,可按指定的格式显示任意类型的数据。
putchar(),字符显示函数,只能显示单个字符。
puts(),是字符串输出函数。
4.1 scanf()的使用
scanf()函数的作用:把从键盘上输入的数据根据找到的地址存入内存中,即给变量赋值。
格式为:scanf("格式控制字符串",参数地址列表);
格式控制字符串:约定输入数据的类型和格式,参数的个数必须与变量地址的个数一致。
参数地址列表:以逗号 “, ”分隔的、输入数据变量地址序列。
例如:scanf("%d%d%d",&a,&b,&c);%d表示类型的输出格式、&表示取地址符号
注意:
如果scanf中%d是连着写的,如“%d%d%d”,在输入数据时,数据之间不可以用逗号分隔,只能用空白字符(空格或tab键或者回车键)分隔。即“2(空格)3(tab)4” 或 “2(tab)3(回车)4”等。
如果是“`%d,%d,%d`”,则在输入数据时需要加“,”逗号,如“2,3,4”。
4.2 getchar()、putchar()的使用
getchar():输入字符数据
格式:getchar()
功能:从键盘缓冲区读入一个字符
putchar():输出字符
格式: putchar(ch),其中ch是一个字符变量
功能:从标准输出设备输出一个字符
4.3 gets()与puts()的使用
puts():在C语言中,puts() 是一个用于输出字符串的标准库函数,其原型定义在标准头文件中。puts() 函数的作用是将一个以 null 字符(\0)结尾的字符串打印到标准输出(通常是控制台)上,并自动添加一个换行符。
注意,puts()函数只能用于输出字符串,而不能输出其他类型的数据。如果需要输出其他类型的数据,应使用 printf() 函数。
gets():读取标准输入设备输入的字符串,直到遇到【Enter】键才结束。
补充:也可以用printf()函数输出打印;
样例代码为:
#include<stdio.h> //puts头文件需要 int main() { char str[15]; printf("enter your name:"); gets(str); //输入字符串至数组变量str printf("your name is "); puts(str); //输出字符串 printf("your name is %s\n",str); //输出字符串 return 0; }五、局部变量与全局变量
变量按照声明的位置,可以分为:局部变量 和 全局变量。
局部变量:在函数体内{}定义的变量,也称内部变量。局部变量只能在定义它的函数中使用。
全局变量:在函数之外{},定义的变量称为外部变量,外部变量是全局变量(也称全程变量)。
一个程序中,凡是在全局变量之后定义的函数,都可以使用在其之前定义的全局变量;当局部变量和全局变量同名的时候,局部变量优先使用。
#include <stdio.h> int global = 2026;//全局变量 int main(){ int local = 2026;//局部变量 //下面定义的global会不会报错? int global = 2026;//局部变量 printf("global = %d\n", global); return 0; }总结:
本章初步了解了C语言的运行机制,了解了C语言中变量的命名、输入输出函数。下一章节直接针对性学习C语言的结构,可能减少部分原理性知识;