一、普通变量初始化(int、char、double、short、long long)
变量:存储单个数据的内存单元。可以比喻成单独的小盒子,一个盒子只能存放一份数据。 共 3 种书写形式:
- 初始化(定义同时赋值)
int a = 10; char ch = 'A'; double num = 3.14;通俗理解:一边造盒子,一边直接把数据放进盒子。这是严格意义上的初始化。
- 先定义,后赋值(不属于初始化)
int b; // 变量定义,开辟内存空间 b = 20; // 赋值操作,修改变量存储的值通俗理解:先做出空盒子,后续代码再把数据放进去,这个动作叫赋值,不是初始化。
- 定义变量后,通过标准输入赋值
int num; scanf("%d", &num); char ch; scanf("%c", &ch); double d; scanf("%lf", &d);说明:语法层面属于赋值。课堂练习中常用来给变量设置初始数据,但不属于初始化,选择题注意区分。 通俗理解:盒子提前做好,由键盘输入内容存入盒子。
单个字符 char 的三种写法
- 定义时初始化
char ch = 'M';- 先定义,后赋值
char ch; ch = 'X';- 标准输入赋值
char ch; scanf("%c", &ch);二、字符串(字符数组)的四种初始化方式
概念:C 语言字符串是以
\0(字符串结束符)结尾的字符序列。 使用字符串处理函数,必须引入头文件:#include <string.h>
- 字符串字面量初始化(最常用)
char str[100] = "student";说明:使用双引号包裹字符串,编译器自动在末尾追加
\0。 通俗理解:双引号写文字,电脑自动在文字末尾加上结束标记。
- 逐字符列表初始化,手动添加结束符
char str[8] = {'a','b','c','d','\0'};说明:逐个列出字符,必须手动写入
\0作为字符串结束标记。
- 循环逐个字符读取,手动添加
\0(原理演示代码,工程不推荐)
char str[100]; int i = 0; while (1) { scanf("%c", &str[i]); if (str[i] == '\n') break; i++; } str[i] = '\0';通俗理解:一个字一个字从键盘读入,按下回车停止,最后手动补上字符串结束标记。 注意:
scanf("%c")会读取换行符,容易出现读取异常。
- 使用
strcpy字符串复制函数完成初始化
char str[100]; char temp[] = "hello world"; strcpy(str, temp);说明:将源字符串
temp的内容复制到目标字符数组str。
第二部分:数组
一、引入数组的原因
如果需要存储多份同类型数据,不使用数组就要单独定义多个独立变量。 例:存储 100 名学生成绩,需要定义 100 个不同名称的 int 变量。
缺点:
- 变量数量多,代码冗余;
- 批量计算、遍历数据需要重复编写大量代码;
- 无法统一批量输入、批量输出。
数组定义:一组相同数据类型的连续内存单元,共用同一个数组名,依靠下标(索引)区分每一个元素。
通俗理解:一整排连续、同类型的小盒子,共用一个名字,靠编号区分每个盒子。 优势:只需一行代码定义,配合循环,完成批量输入、遍历、计算,精简代码。
数组分为两类:一维数组、二维数组
提示:不带
\0的普通字符数组仅作了解;做题、写代码优先使用带\0的字符串数组,否则会出现乱码。
二、一维数组
1. 一维数组定义语法
数据类型 数组名[元素个数];示例:
int arr[10]; // 存放10个整型元素 double brr[5]; // 存放5个双精度浮点型元素 char str[20]; // 字符数组,用于存储字符串两条核心规则:
[]内一般写常量表达式;C99 标准支持变长数组 VLA(变量作为长度),应试场景不使用。- 数组下标从 0 开始。
int arr[10]有效下标范围:0~9;访问arr[10]属于数组越界,会造成未定义行为(乱码、程序崩溃)。
通俗理解:10 个盒子,编号 0 到 9,不存在编号 10 的盒子,强行访问会出错。
2. 一维数组的三种初始化方式(int、double 通用)
① 定义数组时,初始化列表赋值
int arr[3] = {1,2,3}; double brr[4] = {1.1,2.2,3.3,4.4}; // 省略数组长度:编译器自动统计元素个数 int arr[] = {10,20,30};补充:初始化列表提供元素数量少于数组总长度时,剩余元素自动初始化为 0。 示例:
int arr[5]={1,2};,数组元素:1,2,0,0,0
② 数组定义完成后,循环逐个元素赋值
int arr[5]; for(int i=0;i<5;i++) { arr[i] = i+1; }③ 数组定义后,循环读取标准输入(考试高频写法)
int arr[5]; for(int i=0;i<5;i++) { scanf("%d", &arr[i]); }3. 计算一维数组元素个数(常用公式)
⚠️ 限制:仅能在数组定义所在函数内使用。数组作为函数形参时,数组名退化为指针,该公式失效。
int len = sizeof(数组名) / sizeof(数组名[0]);解释:sizeof(数组名):整个数组占用的总字节数sizeof(数组名[0]):数组单个元素占用字节数 两者相除,得到数组元素总个数。
4. 遍历输出一维数组全部元素
int arr[5] = {1,2,3,4,5}; int len = sizeof(arr)/sizeof(arr[0]); for(int i=0;i<len;i++) { printf("%d ", arr[i]); }5. 一维数组常见考点
数组元素求和、求平均值、查找最值(最大值 / 最小值)、顺序查找、统计元素出现次数;后续学习冒泡排序、选择排序、插入排序。
三、普通字符数组(了解即可,不推荐直接使用)
char arr[5]={'a','b','c','d','e'};特点:没有\0结束符,不是 C 语言字符串。 缺陷:
- 不能直接使用
%s格式输出; - 无法使用
strlen、strcpy等字符串库函数; - 使用
%s输出会出现乱码。
建议:代码中统一使用带
\0的字符串。
四、字符串(字符数组)输入输出
前提:字符数组作为字符串使用时,数组容量 ≥ 有效字符个数 + 1,预留位置存放\0。
scanf("%s",数组名);
读取连续非空白字符,遇到空格、回车停止;数组名本身是地址,前面不加取地址符
&
fgets(字符数组,最大读取字符数,stdin);
可以读取包含空格的整行字符串
printf("%s",字符数组);
输出字符串,读到
\0停止输出
五、二维数组
概念:二维数组可以理解为数组的数组,逻辑上呈现表格形态,由行、列两个下标定位元素。 通俗理解:多行多列的盒子表格。
1. 二维数组定义语法
数据类型 数组名[行数][列数];示例:int arr[2][3];,2 行 3 列,一共 6 个整型元素。 行下标:0、1;列下标:0、1、2。
规则:初始化时行数可以省略,列数不能省略。
2. 二维数组初始化
① 定义时初始化
int arr[2][3] = {{1,2,3},{4,5,6}}; // 平铺简写写法 int arr[2][3] = {1,2,3,4,5,6};② 双层循环,标准输入逐个赋值
int arr[2][3]; int row = sizeof(arr)/sizeof(arr[0]); // 获取总行数 for(int i=0;i<row;i++) { int col = sizeof(arr[i])/sizeof(arr[i][0]); // 获取当前行的列数 for(int j=0;j<col;j++) { scanf("%d", &arr[i][j]); } }3. 遍历打印二维数组
外层循环遍历行,内层循环遍历当前行的每一列;一行打印结束后换行。
int row = sizeof(arr)/sizeof(arr[0]); for(int i=0;i<row;i++) { int col = sizeof(arr[i])/sizeof(arr[i][0]); for(int j=0;j<col;j++) { printf("%d ", arr[i][j]); } printf("\n"); }六、数组高频易错点
- 数组下标从 0 开始;访问超出范围的下标属于数组越界,产生未定义行为。
- 定义数组时方括号内一般使用常量;C99 变长数组应试不采用。
- 不能直接用
b=a完成数组整体赋值,编译报错;整数数组使用循环拷贝,字符串使用strcpy。 - 局部数组不初始化,元素为随机垃圾值;全局数组默认全部元素初始化为 0。
scanf输入:普通变量需要加&;字符数组名代表首地址,不需要加 &。- 字符串比较不能直接使用
==,数组名比较的是内存地址;字符串比较必须使用strcmp。 strlen只适用于 C 语言字符串,统计有效可见字符数量,不包含末尾\0。
七、字符串库函数(头文件:#include <string.h>)
strlen(字符串):获取字符串有效字符长度,不计入\0strcpy(目标字符数组,源字符串):字符串复制,把源字符串拷贝到目标数组strcat(目标字符数组,追加字符串):字符串拼接,将后一段字符串追加到目标数组末尾strcmp(字符串1,字符串2):字符串比较- 返回值 = 0:两个字符串完全相等
- 返回值 < 0:字符串 1 小于字符串 2
- 返回值 > 0:字符串 1 大于字符串 2
- 标准判等写法:
if(strcmp(s1,s2)==0)