Written Test in UESTC

简答题

请问用C语言编程实现网络数据结构,应该使用TCP/IP协议还是HTTP协议,为什么?
TCP/IP 协议
  • TCP/IP 是一组工作在传输层和网络层的协议。它提供的是端到端的连接,确保数据可靠传输,保证数据按序到达,数据无误差,没有丢失和重复。适用于需要直接控制数据传输过程,或者对数据准确率要求高的应用,如文件传输、电子邮件、远程登陆等。
HTTP 协议
  • HTTP(超文本传输协议)建立在TCP/IP协议之上,是一个应用层的协议。它是一种无状态的请求-响应协议,通过URL定位网络资源,主要用于网页数据的传输,或者需要与Web服务器交互时,适用于网页浏览、表单提交、文件下载等Web应用。
详细叙述一下一款客户定制的软件应该怎么进行测试,并交付使用
  1. 需求确认和文档化,明确软件需求的每一个细节,包括功能需求、性能需求、用户界面和用户体验要求等,并进行文档化,以作为后续开发和测试的依据。

  2. 根据需求文档,制定测试计划,并搭建适合软件测试的环境。

  3. 执行测试,包括单元测试、集成测试、系统测试、性能测试以及用户测试。

  4. 对测试中发现的缺陷进行跟踪修复以及回归测试。

  5. 客户验收与软件交付,包括软件的最终版本、源代码、使用手册、部署指南等,并根据需要对客户的使用人员进行培训,确保他们能够有效使用软件。

  6. 提供一定期限的技术支持及维护与更新服务。

请简述C语言的隐式类型转换发生的四种情况,并说明每种情况如何转换。并回答float类型数据在转为int类型数据时,发生了什么样的变化
  1. 算术运算过程中,低类型转换为高类型;
  2. 变量赋值过程,表达式的值转换为左边变量的类型;
  3. 参数传递过程中,实参转换为形参的类型;
  4. 函数结果返回时,return表达式转换为接收返回值的变量类型;

float类转换为int类时,会出现小数位截断的现象,并且由于float的表示范围远远大于int类型的范围,若出现超出int类表示范围的转换,结果是不确定的。

从C语言执行效率角度,简述下C语言除了指针、宏函数、位运算还采取了哪些措施提高执行效率
  1. 指针:使C语言拥有类似汇编语言的寻址方式,更有效地实现如直接访问硬件等功能,使程序更高效
  2. 宏函数:预先将函数嵌入到当前程序中,不会产生函数调用,仅仅是占用了空间,而使程序可以高效运行,在频繁调用同一个宏函数时,效果尤其突出;相反,使用函数时,涉及到栈检查以及CPU需要进行压栈和弹出操作来保存和恢复当前的现场;
  3. 操作:可以减少除法和取模的运算,理论上“位运算”可以完成所有的运算和操作,位操作往往通过硬件实现,灵活的位操作可以有效提高程序的运行效率;
  4. 循环:循环嵌套中将较长循环设为内存循环,较短循环设为外置循环,以减少CPU跨切循环层的次数,大大提高程序的运行效率;
  5. 虚拟:让用户可以直接控制进程虚拟地址,为用户提供了高效的内存拷贝函数;变量类型是弱类型,可以进行各种强制转换;
  6. 汇编:可以嵌入汇编语言,让代码效率接近极限;
  7. 系统调用:可以调用系统API,接近底层;
数组越界会造成什么后果

系统出错或者崩溃。越界会对未知的数据进行读取或修改,如果该数据涉及到系统的关键数据,则会导致系统程序遭到修改,因此为了系统安全往往需要对数组下标进行检查。

实参和形参都是数组元素;实参是数组地址,形参是指针;实参和形参都是数组地址;问这三个都是什么传递方式;

值传递;地址传递;地址传递;

变量常量填表
区域 变量或常量名 占用内存 相对地址
常量区 2 2 0
10 2 1
"UESTC" 6 2
"CHENGDU" 8 5
10 2 8
全局区(全局和静态) num 2 0
main函数 str1 10 0
str2 4 5
p 1 7
func函数 m 2 0
n 2 1
for (int i = 0; i < n; i++) S; 用显示结构表示
1
2
3
4
5
6
7
8
9
10
11
12
	int i = 0;

S_for:
if i < n goto S_do; // 条件跳转
goto S_exit; // 强制跳转

S_do:
S;
i = i + 1;
goto S_for; // 强制跳转

S_exit: ;
C语言中,除了关键字,还有哪些单词类型?C的存储类型关键字有哪四个?

标识符、运算符、分隔符、常量、注释符

1
int a = 123; // 对a进行赋值

关键字:auto、extern、register、static

读下面程序,写出输出的结果
1
2
3
4
5
6
#define SepMulti (x) ((x) * (x));
int main() {
int x = 5;
int y = SepMulti(x++); // int y = ((x++) * (x++));
printf("%d %d", x, y); // x = 7, y = 25
}

程序题

  1. Count
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* getStr() {
size_t buf_size = 0;
char* str = malloc(buf_size * sizeof(char)); // 动态分配空间
getline(&str, &buf_size, stdin);
int len = strlen(str);
if (len > 0 && str[len - 1] == '\n') str[len - 1] = '\0'; // 设置结束位置
return str;
}

int main() {
printf("输入字符串a: ");
char* a = getStr();
printf("输入字符串b: ");
char* b = getStr();

int lenA = strlen(a), lenB = strlen(b), count = 0;
for (int i = 0; i < lenA; i++) {
for (int j = 0; j < lenB && a[i] == b[j]; j++) {
if (j == lenB - 1) count += 1;
else i++;
}
}

printf("\"%s\"在\"%s\"中出现了%d次\n", b, a, count);
}
  1. Read File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INITIAL_CAPACITY 10

typedef struct wordCount {
char word[20];
int val;
} WordCount;

int main() {
int len = 0;
int capacity = INITIAL_CAPACITY;
WordCount* wordset = malloc(capacity * sizeof(WordCount)); // 动态分配单词集空间

FILE* fp;
char buffer[20];
if ((fp = fopen("./text.txt", "r")) == NULL) {
printf("不存在该文件\n");
exit(1);
}

while (fscanf(fp, "%19s", buffer) == 1) { // 最多读取长度为19的单词
int flag = 1;
for (int i = 0; i < len; i++) {
if (strcmp(wordset[i].word, buffer) == 0) {
wordset[i].val += 1;
flag = 0;
break;
}
}
if (flag) {
if (len >= INITIAL_CAPACITY) {
capacity *= 2;
wordset = realloc(wordset, capacity * sizeof(WordCount));
if (wordset == NULL) {
printf("单词集内存分配失败");
exit(2);
}
}
strcpy(wordset[len].word, buffer);
wordset[len].val = 1;
len += 1;
}
}

for (int i = 0; i < len; i++) printf("%s: %d\n", wordset[i].word, wordset[i].val);

fclose(fp);
free(wordset);
return 0;
}
  1. Student Management
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 100

typedef struct student {
char name[20];
long number;
int score;
} Student;

void bubbleSort(Student* studentset, int m) {
int flag = 0; // 作为全部元素已正序的标志
for (int i = 0; flag == 0; i++) {
flag = 1;
for (int j = 0; j < m - i - 1; j++) {
if (studentset[j].score > studentset[j + 1].score) {
Student tmp = studentset[j];
studentset[j] = studentset[j + 1];
studentset[j + 1] = tmp;
flag = 0; // 仍有乱序的元素
}
}
}
}

void binarySearch(Student* studentset, int low, int high, int target) {
int flag = 0; // 查找成功标志
int mid = (low + high) / 2;
if (low <= high) {
if (studentset[mid].score == target) flag = 1;
else if (studentset[mid].score > target) binarySearch(studentset, low, mid - 1, target);
else binarySearch(studentset, mid + 1, high, target);
}

if (flag == 1) {
printf("以下学生符合要求(姓名(学号): 分数):\n");
// 打印目标位置的左右元素中符合条件的学生信息
for (int i = mid; studentset[i].score == target; i++) printf("%s(%ld): %d\n", studentset[i].name, studentset[i].number, studentset[i].score);
for (int i = mid - 1; studentset[i].score == target; i--) printf("%s(%ld): %d\n", studentset[i].name, studentset[i].number, studentset[i].score);
}
}

int main() {
int m, n;
printf("学生信息数量: ");
scanf("%d", &m);

if (m > MAXSIZE) {
printf("超出最大收录范围\n");
exit(1);
}
Student studentset[MAXSIZE];
printf("请逐行输入%d条学生信息(姓名 学号 分数):\n", m);

for (int i = 0; i < m; i++) {
int err = scanf("%s %ld %d", studentset[i].name, &studentset[i].number, &studentset[i].score);
if (err != 3) {
printf("输入格式错误\n");
exit(1);
}
}

bubbleSort(studentset, m);

printf("请输入要查找的目标分数: ");
scanf("%d", &n);
binarySearch(studentset, 0, m - 1, n);

return 0;
}
  1. Toy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <stdlib.h>

typedef struct linkNode {
int val;
struct linkNode* next;
} LinkNode;

int main () {
int m;
scanf("%d", &m);
int* turns = malloc(m * sizeof(int));

for (int i = 0; i < m; i++) scanf("%d", &turns[i]);

LinkNode *p = malloc(sizeof(LinkNode));
p->next = NULL;
LinkNode *pre = p;

for (int i = 0; i < 10; i++) {
LinkNode* node = malloc(sizeof(LinkNode));
node->val = i + 1;
pre->next = node;
pre = node;
}
pre->next = NULL;

for (int i = 0; i < m; i++) {
int loc = 0;
LinkNode* node = p;
while (node->next->val != turns[i]) node = node->next;
LinkNode* tmp = node->next;
node->next = node->next->next;
tmp->next = p->next;
p->next = tmp;
}

LinkNode* node = p;
for (int i = 0; i < 10; i++) {
node = node->next;
printf("%d ", node->val);
}
printf("\n");

return 0;
}