在 IDE 里,为什么按一个键,就能编译运行?
./a.out
背后是通过
gcc --help
; man gcc
-E
, -S
, -c
本次课程
#include <>
指令以下代码有什么区别?
#include <stdio.h>
#include "stdio.h"
为什么在没有安装库时会发生错误?
#include <SDL2/SDL2.h>
你可能在书/阅读材料上了解过一些相关的知识
gcc --verbose a.c
以下代码会输出什么?
#include <stdio.h>
int main() {
#if aa == bb
printf("Yes\n");
#else
printf("No\n");
#endif
}
宏展开:通过
#include
→ 粘贴文件aa
, bb
→ 粘贴符号知乎问题:如何搞垮一个 OJ?
#define A "aaaaaaaaaa"
#define TEN(A) A A A A A A A A A A
#define B TEN(A)
#define C TEN(B)
#define D TEN(C)
#define E TEN(D)
#define F TEN(E)
#define G TEN(F)
int main() { puts(G); }
如何躲过 Online Judge 的关键字过滤?
#define SYSTEM sys ## tem
如何毁掉一个身边的同学?
#define true (__LINE__ % 16 != 0)
#define s (((((((((((((((( 0
#define _ * 2)
#define X * 2 + 1)
static unsigned short stopwatch[] = {
s _ _ _ _ _ X X X X X _ _ _ X X _ ,
s _ _ _ X X X X X X X X X _ X X X ,
s _ _ X X X _ _ _ _ _ X X X _ X X ,
s _ X X _ _ _ _ _ _ _ _ _ X X _ _ ,
s X X _ _ _ _ _ _ _ _ _ _ _ X X _ ,
s X X _ X X X X X _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,
s _ X X _ _ _ _ X _ _ _ _ X X _ _ ,
s _ _ X X X _ _ _ _ _ X X X _ _ _ ,
s _ _ _ X X X X X X X X X _ _ _ _ ,
s _ _ _ _ _ X X X X X _ _ _ _ _ _ , };
宏展开:通过
例子:X-macro
#define NAMES(X) \
X(Tom) X(Jerry) X(Tyke) X(Spike)
int main() {
#define PRINT(x) puts("Hello, " #x "!");
NAMES(PRINT)
}
发生在实际编译之前
Pros
Cons
#define L (
int main L ) { puts L "Hello, World" ); }
(先行剧透本学期的主要内容)
一个不带优化的简易 (理想) 编译器
int foo(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
将多个二进制目标代码拼接在一起
extern "C" {
int foo() { return 0; }
}
int bar() { return 0; }
静态:
动态:
两个视角的共同之处:
main
函数开始执行标准规定 C 程序从 main
开始执行
main
?进程执行的第一条指令是什么?)int main(int argc, char *argv[]);
上次课已经演示过
ls -al
(argc = 2, argv = ["ls", "-al", NULL]
)main
, argc
和 argv
一切皆可取地址!
void printptr(void *p) {
printf("p = %p; *p = %016lx\n", p, *(long *)p);
}
int x;
int main(int argc, char *argv[]) {
printptr(main); // 代码
printptr(&main);
printptr(&x); // 数据
printptr(&argc); // 堆栈
printptr(argv);
printptr(&argv);
printptr(argv[0]);
}
例子 (是不是感到学了假的 C 语言)
int main(int argc, char *argv[]) {
int (*f)(int, char *[]) = main;
if (argc != 0) {
char ***a = &argv, *first = argv[0], ch = argv[0][0];
printf("arg = \"%s\"; ch = '%c'\n", first, ch);
assert(***a == ch);
f(argc - 1, argv + 1);
}
}