Lecture
计算机程序设计基础 (1) 小班辅导 20221218
刘雪枫 - 无 92
Copyright (C) Timothy Liu 2022-2023
许可证:Creative Commons — 署名-相同方式共享 4.0 国际 — CC BY-SA 4.0
2022.12.18
目录
[TOC]
引言(fei hua)
程设(1)我们应该掌握什么
- 初步了解什么是编程,掌握程序设计的基本思想
- 会使用 C 语言编写简单的程序,了解 C 语言的常见语法
背景知识
C 语言是由著名的 Brian Kernighan 和 Dennis Ritchie 发明的语言,继承于 B 语言。在 1978 年,两位科学家正式发布了第一版 C 语言指导书 The C Programming Language,介绍了 C 语言的语法。这一版 C 语言常被称作“K&R C”或“C78”。K&R C 与我们现在的 C 语言差别还很大。
1983 年,美国标准化组织 ANSI 成立 C 语言委员会,对 C 语言进行标准化,并于 1989 年发布了影响最为深远的第一个标准化的 C 语言版本,常被称作 ANSI C 或 C89;1990 年,国际标准委员会 ISO 对 C 语言进行了标准化,并发布了 C90(与 C89 几乎完全相同)。现在,C 语言由 ISO 的 WG14 工作组负责标准化工作,C 语言历代标准如下:
发布年份 | 称呼 | 备注 |
---|---|---|
史前时期 | K&R C | 最早的版本,C 语言的“古文” |
1989/1990 | C89/C90 | 第一个 C 标准,至今影响仍然广泛(Linux Kernel 于 2022 年从 C89 更新到了 C11) |
1999 | C99 | 增加了 |
2011 | C11 | 增加了大量 |
2018 | C17/C18 | 对 C11 的小补丁 |
2023 | C23 | 即将发布,增加了 |
问:那咱们的程设是哪一个标准呢?
答:咱们的程设是微软(Microsoft)发布的 VS2008“标准”!
当然最接近的标准是 C89
试题讲解
2019~2020 学年秋季学期期末试题(孙甲松老师)
1
数组写成矩阵形式,即为求对角元
- BTW
- 注意初始化与赋值是两个不同的操作,不能混淆
- 注意
int a[10]; a[10] = xxx;
的错误行为
29 27
6
考察逗号表达式的使用。需要知道逗号表达式从左到右依次执行(且存在序列点),以最后一个子表达式的值作为整个逗号表达式的值
- BTW
- 关于函数:形参与实参结合等价于初始化语句;C 语言参数传递全部是传值而没有传引用,C++ 语言才有传引用的语法
24
7
注意 case
后不加 break
会 fall through
- BTW
switch
的设计灵感来源于汇编语言的跳转表,是跳转表的高级语言中的“抽象”。不过不必用跳转表实现,完全取决于具体实现,讨论if
和switch
谁更快没有意义case
本质上只是label
,用于标识语句
1 2 3 4 5
8
考察耐力。
5
9
考察静态存储期。注意(在语法层面上)只在第一次执行到该处时进行初始化。
11 13 15
10
注意宏只是简单的替换
#include
也大致上相当于简单的复制粘贴
23
3
注意 scanf
不会读走空格,gets
会读到且读走回车、但不会读进回车
- BTW
- 注意与
scanf("%[^\n]", s)
区别 gets
已被 C11 删除,建议使用fgets
。但fgets
会读进换行(个人认为这个设计比较蠢 x)
- 注意与
How_how_do_you_do_ _DO_YOU_DO<EOL>
4
观察即可知道是在用参数作为返回值,实际就是递归求斐波那契数列。
13
12
注意整数除法的结果仍然是整数即可,且目前的绝大多数实现中,都是向零取整。
6
13
除了 12 题要注意的点外,注意 %f
保留六位小数
5,6.000000
2
注意:
- 数组作为函数参数时会退化为指针(但需要注意数组和指针是不同的概念,数组不等同于指针)
- 结构体作为参数时复制结构体
10,20,x 50,60,x
11
两个结点互指
-
BTW
-
定义结构体时,也可直接定义变量,结构体本身是一个类型
-
对齐问题
-
默认对齐规则
- 对齐位数为最大的
scalar
类型的大小,但不超过机器字长scalar
:算术类型、枚举类型、指针类型(注:不包括数组、结构体)
- 结构体的大小是对齐位数的正整数倍
- 每个
scalar
成员的地址相对于结构体起始位置的偏移量是min{其大小,机器字长}
的整数倍
- 对齐位数为最大的
-
struct { char c; int32_t x; // int32_t 指四字节大小的整数 int32_t y; }; // 32-bit / 64-bit: 12bytes
-
struct { int32_t x; int32_t y[2]; char c[3]; }; // 32-bit / 64-bit: 16bytes
-
struct { int32_t x; double d; }; // 32-bit: 12bytes // 64-bit: 16bytes
-
-
43
5
考察指针的使用,需要理解指针
18
14
注意数组到指针的退化,二维数组会向指向数组的指针(行指针)退化 。一般地,类型 T
的数组向指向 T
的指针退化。此处 T
为 int[]
- BTW
- k 维数组可以看作 k-1 维数组的数组。因此,一般地,一个 k 维数组会向指向 k-1 维数组的指针退化
16
考察数组转化为指针
- BTW
- 严格来讲,本质上存在未定义行为,可能发生任何意想不到的结果,无法给出确定的输出。但是基于考试,还是可以默认写出结果的
7 10
18
本题回忆有误。原题中 a
的类型为 int[4][3]
,即原题为:
#include <stdio.h>
int f(int(* p)[4], int n)
{
int i;
int m;
m = **p;
for (i = 1; i < n; i++)
if (*(*p + i) > m) m = *(*p + i);
return m;
}
int main()
{
int a[4][3] = { 1,2,3,4,5,6,7,6,5,4,3,2 }, n = 3 * 4;
printf("%d\n", f(a, n));
return 0;
}
需要对数组与指针的关系有一定程度的理解,同 14 题
7
17
注意 '\0'
作为 C 风格的字符串的结束符,会影响字符串长度的判断,但是不影响数组的大小
19
DFKP
15
考察文件读写,想不出来可以画图
1 10 0 0 20 30
本题没有考察 fseek
的使用,也是需要会的
20
题缺失
补充题
补充 1
改编自 2018 年黄永峰老师期末笔试
#include <stdio.h>
int main(void)
{
FILE *fp;
char a[10] = { "tsinghua" }, b[10], *p;
p = b;
fp = fopen("d.dat", "w+");
fwrite(a, sizeof(char), 6, fp);
fseek(fp, sizeof(char) * 3, SEEK_SET);
fgets(p, 5, fp);
fclose(fp);
printf("%c, %c", *(p + 2), b[2]);
return 0;
}
此题存在一些问题。fwrite
应该是在二进制方式下打开而使用的函数,而 fgets
应该是以文本方式下打开使用的函数。在 Windows 系统上这会影响换行符的处理,在 POSIX 系统下无影响。虽然本题没有涉及到换行,但是我们还是应该尽量遵守规则。
抛开二进制方式的问题,需要注意的是,fgets
会读到换行或文件尾或最大字符数,本题读到了文件尾。注意 fgets
会在后面加上 \0
,因此最大读入字符数是传入的参数个数减 1
h, h
补充 2
改编自 2018 年黄永峰老师期末笔试
将程序在 Windows 环境下生成可执行文件 test.exe
,并在 cmd.exe
中运行:
$ test THIS IS OUR FINAL EXAM
#include <stdio.h>
int main(int argc, char* argv[])
{
char** p;
for (p = argv; argc--; p++)
{
printf("%c%s ", **p, *p);
}
putchar('\n');
return 0;
}
考察命令行参数
ttest TTHIS IIS OOUR FFINAL EEXAM
C/C++ 程序的执行过程(选讲)
- 预处理 -> 编译 -> 汇编 -> 链接 -> 执行(程设笔试不会,但是保研面试可能会考一些细节)
- MSVC、GCC、Clang(LLVM)
- cl、gcc、g++、clang
- 链接:静态链接、动态链接与运行时
- 多文件编程
请大家填写反馈问卷(Respect)
反馈问卷略。
祝大家考试顺利!