第一周 C语言
第一讲
一、转义序列
-
由 \ + 特定字母组成,用于表示无法直接输入的字符。
-
\n表示换行。
printf("hello miuc \n hello may");
运行结果:
hello miuc
hello may
二、占位符
-
使用
%作为标记。 -
%d用于int类型。 -
%f用于float类型。 -
%c用于字符类型。 -
%n.mf和
%n.md格式详解:
-
n:最小栏宽。若数据宽度小于n,则在左侧补空格;若大于n,则按实际宽度显示。 -
m(对于%n.md):显示的最小有效位数。若实际位数少于m,则在左侧补0;超过则正常显示。 -
m(对于%n.mf):小数点后的保留位数。默认为6位。
-
#include <stdio.h>
#include <stdlib.h>
int length = 2, width = 3, high = 4;
int volum;
int main(int argc, char *argv[]) {
volum = length * width * high;
printf("体积=%d", volum);
return 0;
}
运行结果:体积=24
三、读取用户输入
scanf("%d", &length); // 注意变量名前需要加 & (取地址符)
scanf("%d", &width);
scanf("%d", &high);
四、宏定义 #define
#define PI 3.14f // 定义常量PI,值为3.14(单精度浮点数)
五、随堂练习
-
输入圆半径,计算体积。
-
输入两个不同圆的半径,分别计算体积。
-
在2的基础上,将圆周率精度提升至3.14159。
#include <stdio.h>
#include <stdlib.h>
#define PI 3.14 // 宏定义
int r_1, r_2;
float volum_1, volum_2;
int main(void) {
printf("请输入第一个圆的半径:");
scanf("%d", &r_1);
printf("请输入第二个圆的半径:");
scanf("%d", &r_2);
// 注意:使用 4.0f/3.0f 确保浮点数运算
volum_1 = 4.0f / 3.0f * PI * r_1 * r_1 * r_1;
volum_2 = 4.0f / 3.0f * PI * r_2 * r_2 * r_2;
printf("第一个圆的体积为:%f\n第二个圆的体积为:%f ", volum_1, volum_2);
return 0;
}
第二讲
一、布尔值 (_Bool)
-
0代表“假”(false)。 -
任何非0值都代表“真”(true)。
第三讲
一、while 循环中的 i-- 与 --i
-
while(i--): 先判断i是否为真(非0),再执行i--。因此,若初始i=5,会循环5次(i值变化:5,4,3,2,1,0结束)。 -
while(--i): 先将i减1,再判断新值是否为真。因此,若初始i=5,会循环4次(i值变化:4,3,2,1,0结束)。
二、do...while 循环
特点:无论条件是否满足,循环体至少会被执行一次。
其中while(条件),一旦满足括号内条件,将继续循环下去。
// 数字位数判断程序
#include <stdio.h>
#include <stdlib.h>
int num;
int digit_count = 0; // 变量名更清晰
int main(void) {
printf("请输入一个数字:");
scanf("%d", &num);
do {
num /= 10;
digit_count++;
} while (num > 0);
printf("这个数字为%d位\n", digit_count);
return 0;
}
三、continue 语句
continue 用于跳过本次循环中剩余的语句,直接开始下一次循环的判断(而不是结束整个循环)。
第四讲
一、浮点数
-
十进制浮点数:科学记数法,例如
6.324572 * 10^2。 -
二进制浮点数:由符号位、阶码、尾数构成(具体标准如IEEE 754)。
-
精度丢失问题:由于二进制无法精确表示所有十进制小数,应避免直接使用
==或!=比较浮点数。推荐使用基于误差范围的方法:
float a = 0.1f;
float epsilon = 0.0000001f; // 定义一个很小的误差范围
int main(void) {
if ((a - 0.1) < epsilon && (a - 0.1) > -epsilon) {
// 认为 a 约等于 0.1
}
return 0;
}
二、int 类型
-
大小:通常为 4字节(32位系统)。2字节是旧式16位系统的标准,现代编程环境下应为4字节。请参考后面的“错题”部分。
-
范围:4字节时,范围为 -2,147,483,648 到 2,147,483,647。
三、char 类型
-
有符号
char:-
字长:1字节
-
范围:-128 到 127
-
-
无符号
unsigned char:-
字长:1字节
-
范围:0 到 255
-
-
占位符:
%c -
表示方法:用单引号
''包裹,如'a','Z'。
四、define 惯用法
可以使用 #define 为已有的数据类型起一个简短易记的别名,这在嵌入式开发中尤其常见。
#define u8 unsigned char
#define u16 unsigned int
// 之后就可以用 u8 myVar; 来代替 unsigned char myVar;
第五讲
一、字符与字符串
-
字符串:用双引号
" "括起来,如"hello"。本质是以\0结尾的字符数组。 -
字符:用单引号
' '括起来,如'a','b'。 -
声明方式:
char string1[3] = {'a', 'b', 'c'}; // 字符数组,未自动添加 '\0' char string2[] = "abc"; // 字符串,编译器会自动添加 '\0',大小为4 -
占位符:
-
字符串:
%s -
字符:
%c
-
二、指针
-
概念:指针是一个变量,其值为另一个变量的内存地址。
-
关键点:数组名本身就是一个指向数组首元素的常量指针。
#include <stdio.h>
#include <stdlib.h>
int a = 1;
int* p = NULL; // 声明一个指向int类型的指针,并初始化为空
int main(void) {
p = &a; // 将变量a的地址赋值给指针p
*p = 5; // 通过解引用操作符 *,修改p所指向的内存单元的值,即a的值变为5
printf("%d", a); // 输出结果为 5
return 0;
}
第六讲
一、函数传指针(实现交换)
通过传递变量的地址(指针),函数内部可以修改外部变量的值。
#include <stdio.h>
#include <stdlib.h>
int a = 2, b = 3;
void exchange(int* x, int* y) {
int temp = 0;
temp = *x; // 取出x指向的值
*x = *y; // 将y指向的值赋给x指向的位置
*y = temp; // 将临时值赋给y指向的位置
}
int main(void) {
exchange(&a, &b); // 传入a和b的地址
printf("a=%d, b=%d", a, b); // 输出: a=3, b=2
return 0;
}
二、递归操作
函数调用自身的编程技巧。必须有明确的终止条件,否则会无限递归导致栈溢出。
int fact(int n) {
if (n <= 1)
return 1; // 终止条件:0! 和 1! 都等于1
else
return n * fact(n - 1); // 递归调用自身
}
错题整理(附解析)
-
题目:在32位计算机上,int型变量常见的大小是(2)字节,(8)位。
-
正确答案:4 字节,32 位。
-
解析:32位计算机的字长是32位,即4个字节。这是现代C语言标准下最常见的
int大小。你笔记中写的2字节是16位时代的产物。
-
-
题目:在32位电脑上,一个存放 int型变量的数组 a,其中最后一个元素为 int型变量的数组 a,则该数组占用的内存为(36)字节。
-
正确答案:36 字节。
-
解析:数组下标从0开始,最后一个元素是
a[8],说明数组共有9个元素(a[0]到a[8])。每个int占4字节,所以总大小为9 * 4 = 36字节。
-
-
题目:以下变量名合法的是(B)。
-
A.
67numB._32studentC.floatD.32_student -
正确答案:B。
-
解析:C语言变量命名规则:只能由字母、数字和下划线组成,且不能以数字开头,也不能与C语言关键字(如
float,int,if等)重名。
-
-
题目:在C语言中,switch 只能测试整型表达式的值。(F)
-
正确答案:T。
-
解析:
switch语句的表达式必须是整型(如int,char,enum等)或能隐式转换为整型的类型。它不能直接用于判断浮点数或字符串。
-
-
题目:进制转换程序(0-255 → 十六进制 & 二进制)
#include <stdio.h> #include <stdlib.h> int num; int Hex[2]; int Binary[8]; int main(void) { int i; int temp; do { printf("请输入一个十进制数(0-255):"); scanf("%d",&num); if(num>255 || num<0) printf("输入错误!请输入0-255之间的整数\n"); }while(num>255 || num<0);//只要输入小于0 或者 大于255,就继续循环(错误点) temp = num; for(i=0;i<2;i++) { Hex[i] = temp % 16; temp /= 16; } temp = num; for(i=0;i<8;i++) { Binary[i] = temp % 2; temp /= 2; } printf("\n16进制:0x"); for(i=1;i>=0;i--) { if(Hex[i]<10) printf("%d",Hex[i]); else printf("%c",'A'+Hex[i]-10); } printf("\n2进制:"); for(i=7;i>=0;i--) { printf("%d",Binary[i]); if(i==4) printf(" "); } return 0; }-
错误点:
-
do...while的条件写反了:原代码while(num>255 || num<0)是正确的。你的错误可能是最初写成了while(num>=0 && num<=255),这会导致输入正确时反而一直循环。正确的逻辑是:“只要输入不合法(小于0或大于255),就继续循环”。 -
不会用
%c显示字符:在将数字(10-15)转换为对应的十六进制字符(‘A’-‘F’)时,使用了'A' + Hex[i] - 10这个巧妙的表达式来计算字符的ASCII码,然后用%c打印出来。这是一个非常好的技巧,你已经掌握了。
-
-