unsigned int a = 0;
a = a - 1; // 不是 -1,而是 4294967295(绕回去了)
printf("%u\n", a);
// 循环变量尤其危险:条件永远成立
for (unsigned int i = 10; i >= 0; i--) // ✗ 死循环!i 永远 >= 0
printf("%u\n", i);
你在 ACM Day 11 学过 C++ 的 struct。C 里它几乎一样,但有两个必须记住的差别。
差别一:定义变量时必须写 struct 关键字(除非用 typedef)
// C++ 写法
struct Point { int x, y; };
Point p; // ✓ C++ 可以直接用 Point// C 里这样写会报错
struct Point { int x, y; };
Point p; // ✗ C 必须写 struct Point p;
struct Point p; // ✓ 但要一直带着 struct 很烦
所以 C 代码里到处都是 typedef —— 给类型起个别名:
typedef struct Point {
int x;
int y;
} Point; // 现在 Point 就是一个类型名了
Point p; // ✓ 和 C++ 一样好写
p.x = 3; p.y = 4;
// 函数声明(放在使用之前,或者放在 .h 里)
int add(int a, int b);
// 函数定义
int add(int a, int b) {
return a + b;
}
// 没有返回值就写 void
void Led_On(void); // (void) 表示"不接收参数",比空括号更严谨
⚠️ C 里不能有同名函数
// C++ 允许(重载)
int max(int a, int b);
double max(double a, double b); // ✗ C 报重复定义// C 的做法:起不同名字
int max_int(int a, int b);
double max_double(double a, double b);
最好的巩固方式:把你已经 AC 过的题,用 C 再写一遍。这样你只需要专注在「输入输出换写法」上,不用分心算法。
P1047 校门外的树入门
就用你之前那题的逻辑(数组标记),只是换成 C 的输入输出。
看参考答案
#include <stdio.h>
int main(void)
{
int arr[10005];
int a, b, i, k, y = 0;
scanf("%d %d", &a, &b);
for (i = 0; i <= a; i++) {
arr[i] = 1; // 0..a 每个位置都种树
}
for (k = 0; k < b; k++) {
int m, n;
scanf("%d %d", &m, &n);
for (i = m; i <= n; i++) {
arr[i] = 0; // 区间内移除
}
}
for (i = 0; i <= a; i++) {
if (arr[i]) y++;
}
printf("%d\n", y);
return 0;
}
对比一下你原来的 C++ 版本,区别只有:#include、scanf 带 &、printf、main(void)。逻辑一个字没变。
P1085 不高兴的津津入门
这题顺便把第 10 讲的「变量必须初始化」用上。
看参考答案
#include <stdio.h>
int main(void)
{
int best = 0; // 目前最大总时长
int day = 0; // 对应的星期几,0 表示不会不高兴
int i;
for (i = 1; i <= 7; i++) {
int a, b, sum;
scanf("%d %d", &a, &b);
sum = a + b;
// 严格大于:并列时保留更早的一天
if (sum > 8 && sum > best) {
best = sum;
day = i;
}
}
printf("%d\n", day);
return 0;
}
自编 位运算热身单片机预备
读入一个 0~255 的整数 v,输出四行:
把最低位(第 0 位)置 1 后的值
把最低位清 0 后的值
把第 3 位翻转后的值
第 5 位是 0 还是 1
输入
40
输出
41
40
32
1
看参考答案
#include <stdio.h>
int main(void)
{
int v;
scanf("%d", &v);
printf("%d\n", v | (1 << 0)); // 置位:最低位变 1
printf("%d\n", v & ~(1 << 0)); // 清零:最低位变 0
printf("%d\n", v ^ (1 << 3)); // 翻转:第 3 位取反
if (v & (1 << 5)) // 读位:第 5 位
printf("1\n");
else
printf("0\n");
return 0;
}