Skip to content

Commit

Permalink
feat: add lab2
Browse files Browse the repository at this point in the history
feat: add lab2 solution
feat: add week2 note
feat: add week2 lec
Co-authored-by: MayGe <[email protected]>
Co-authored-by: EQ1932 <[email protected]>
  • Loading branch information
E1PsyCongroo committed Oct 14, 2024
1 parent 12a865e commit 3212dce
Show file tree
Hide file tree
Showing 55 changed files with 952 additions and 539 deletions.
Binary file added Labs/Solutions/Lab2-Sol.tar.gz
Binary file not shown.
Binary file added Labs/lab2/Lab2.tar.gz
Binary file not shown.
111 changes: 111 additions & 0 deletions Labs/lab2/lab2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Lab2 C 语言基本语法
## Lab2_1 C 语言基本语法
- 完成lab2_1中的四个.c文件
- 请根据每个ex_中的TODO完成内容。
- 你可以使用 make 自动编译可执行文件
```bash
make # 编译所有可执行文件
make ex1_ptr # 仅编译 ex1_ptr.c
./ex1_ptr # 运行 ex1_ptr
make clean # 删除可执行文件
```

## Lab2_2 字符串和循环
- 本实验使用了参数char *argv[],请在编译后尝试向程序输入命令行参数,如:
```bash
make
./str_and_cyc California Oregon Washington Texas
```
输出内容,如下所示:
```bash
for:
arg 1: California
arg 2: Oregon
arg 3: Washington
arg 4: Texas
state 0: California
state 1: Oregon
state 2: Washington
state 3: Texas
while:
arg 0: ./str_and_cyc
arg 1: California
arg 2: Oregon
arg 3: Washington
arg 4: Texas
state 0: California
state 1: Oregon
state 2: Washington
state 3: Texas
```
- 请对srt_and_cyc.c文件中的for和while循环尝试以下操作并查看结果。
- for循环
- 将i初始化为0看看会发生什么。是否也需要改动argc,不改动的话它能正常工作吗?为什么下标从0开始可以正常工作?
- 将num_states改为错误的值(使它变大),来看看会发生什么。
- RTFM: NULL是什么东西,尝试将它用做states的一个元素,看看它会打印出什么。
- 看看你是否能在打印之前将states的一个元素赋值给argv中的元素,再试试相反的操作。
- while循环
- 使用while循环将argv中的值复制到states。
- 让这个复制循环不会执行失败,即使argv之中有很多元素也不会全部放进states。
- 研究你是否真正复制了这些字符串。答案可能会让你感到意外和困惑。


## 递归(可选,难度较大)

- 经典递归例子

```C
#include <stdio.h>
int fibonacci(int n) {
if (n < 1) {
return -1;
}
if (n == 1 || n == 2) {
return 1;
}
else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
int main(void)
{
int a;
while (scanf("%d", &a) != EOF) {
printf("Fibonacci数列第%d项为:%d\n", a, fibonacci(a));
}
return 0;
}
```
- 理解递归的重要方式
- Base Case:递归主体以一个基本情况开始,通常它是这个条件语句,定义了函数对最简单的输入的行为,并通常被用作递归结束的出口。
- Recursive Calls:在Base Case之后,是一个或多个递归调用。递归调用总是有一个特点:它们简化了原来的问题。
- 数学归纳法理解:
1. 验证递归函数`F(X)`取Base Case时成立.
2. 假设X = n时成立,那么可以推导出在X = n+1时递归函数`F(X)`做出正确的行为。
3. 最后一步总结表述。
- 数独
- 数独(Sudoku)是一种经典的逻辑数字游戏,通常由一个9x9的网格组成,这个网格被进一步划分为9个3x3的小方块。游戏的目标是通过填充数字1到9,使得每一行、每一列和每一个3x3的小方块都包含数字1到9,且数字不能重复。
- 实现一个递归函数`bool solveSudoku(int board[N][N], int row, int col)`判断数独是否可解,有解则填充正确答案。
- 题中数独采用二维数组,需解答填充的数字用0代替如:
0 6 0 0 0 0 0 7 1
7 0 5 4 0 3 0 0 0
0 0 0 6 7 0 3 0 0
0 3 7 2 4 1 8 6 0
0 0 0 0 0 5 1 9 0
1 5 8 7 9 0 2 3 0
6 0 1 0 2 0 0 0 3
0 7 9 0 0 0 5 0 2
0 0 0 0 0 4 7 0 0
提供了`printBoard(int board[N][N])`函数打印数独和`isSafe(int board[N][N], int row, int col, int num)`函数检查数字是否可以放在board[row][col]位置。
- 运行judge.sh检测程序正确性。
- 完成文件`sudoku.c`中的`solveSudoku`函数编写。
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CC := gcc
CFLAGS := -Wall -Werror -Wpedantic -g -std=c11
CFLAGS := -Wall -Wextra -Werror -g -std=c11
TARGET := float hello-world

all: $(TARGET)
Expand Down
70 changes: 70 additions & 0 deletions Lectures/Lecture2/Codes/1-control-flow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* C 语言中的控制流 */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
// 条件分支
// if else
if (argc == 1) {
printf("args = NULL\n");
} else if (argc == 2) {
printf("args = %d\n", argc - 1);
printf("argv:%s\n", argv[1]);
} else {
printf("args = %d\n", argc - 1);
}

printf("\n");

// switch
switch (argc) {
case 1:
printf("args = NULL\n");
break;
case 2:
printf("args = %d\n", argc - 1);
printf("argv:%s\n", argv[1]);
break;
default:
printf("args = %d\n", argc - 1);
break;
}

// 三元表达式
argc == 2 ? printf("yes\n\n") : printf("no\n\n");

// 循环结构
int i = 10;
while (i != 0) {
printf("%d ", i);
i--;
}
printf("\n");

do {
printf("%d ", i);
i++;
} while (i < 10);
printf("\n");

for (i = 0; i < 10; i++) {
printf("%d ", i);
}
printf("\n\n");

// 跳转控制语句
/**
* @statement break; 跳出循环或者是跳出switch语句
* @statement continue; 跳过下面的步骤重新开始下一次循环
*/
printf("goto语句示范:\n");
int go = 0;
lable:
printf("%d ", go);
if (go < 3) {
go++;
goto lable;
}
printf("\n");
return EXIT_SUCCESS;
}
22 changes: 22 additions & 0 deletions Lectures/Lecture2/Codes/2-function.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <stdio.h>
#include <stdlib.h>

// 函数声明
int fact(int);

int main(void) {
printf("%d", fact(5));
return EXIT_SUCCESS;
}

// 函数定义
int fact(int n) {
if (n <= 1) {
return 1;
}
int sum = 1, i;
for (i = 1; i <= n; i++) {
sum *= i;
}
return sum;
}
20 changes: 20 additions & 0 deletions Lectures/Lecture2/Codes/3-array.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <stdio.h>
#include <stdlib.h>

int main(void) {
// 定义
unsigned char temp[10] = {0x11, 0x15, 0x22};

// 数组的地址
printf("temp address: %p\n", temp);

// 更改
temp[3] = 0xa8;

// 使用
for (size_t i = 0; i < 10; i++) {
printf("%02x ", temp[i]);
}
printf("\n");
return EXIT_SUCCESS;
}
14 changes: 14 additions & 0 deletions Lectures/Lecture2/Codes/4-string.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 字符串以'\0'结尾 */

int main(void) {
char str1[] = "I Can Eat Glass";
char str2[20] = "I Can Eat Glass";

printf("str1:%s\nsize:%lu\nstr2:%s\nsize:%lu\n", str1, strlen(str1), str2,
strlen(str2));
return EXIT_SUCCESS;
}
31 changes: 31 additions & 0 deletions Lectures/Lecture2/Codes/5-string-advance.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* string.h标准库的几个常用函数 */

int main(void) {
char str1[] = "I Can Eat Glass";
char str2[] = "Neko Bytes";

printf("str1:%s\nsize:%lu\nstr2:%s\nsize:%lu\n", str1, strlen(str1), str2,
strlen(str2));

// 字符串比较
int h = strcmp(str1, str2);
if (h != 0) {
if (h > 0) {
printf("str1更大\n");
} else {
printf("str2更大\n");
}
} else {
printf("str1和str2一样大\n");
}

// 字符串赋值
strcpy(str1, "I love windows\n");
printf("str1:%s", str1);

return EXIT_SUCCESS;
}
9 changes: 9 additions & 0 deletions Lectures/Lecture2/Codes/6-macro.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <stdio.h>

#define MAX 1000

int main(void) {
printf("MAX: %d", MAX);

return 0;
}
13 changes: 13 additions & 0 deletions Lectures/Lecture2/Codes/7-variable.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <stdio.h>

int main(void) {
unsigned int a;
int b;
float c;
printf("a,b,c各元素的值\n");
printf("%u %d %f\n", a, b, c);
printf("a,b,c各元素的地址\n");
printf("%p %p %p\n", &a, &b, &c);

return 0;
}
11 changes: 11 additions & 0 deletions Lectures/Lecture2/Codes/8-nested-array.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <stdio.h>

int main(void) {
int matrix[2][2] = {{1, 2}, {3, 4}};
printf("%p %p %p %p\n", &matrix[0][0], &matrix[0][1], &matrix[1][0],
&matrix[1][1]);
printf("sizeof matrix: %zu\n", sizeof matrix);
printf("sizeof matrix[0]: %zu\n", sizeof matrix[0]);
printf("sizeof matrix[1]: %zu\n", sizeof matrix[1]);
return 0;
}
23 changes: 23 additions & 0 deletions Lectures/Lecture2/Codes/9-pointer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <stdio.h>

void swap1(int x, int y) {
int t = x;
x = y;
y = t;
}

void swap2(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}

int main(void) {
int a = 1, b = 2;
printf("a = %d, b = %d\n", a, b);
swap1(a, b);
printf("a = %d, b = %d after swap1\n", a, b);
swap2(&a, &b);
printf("a = %d, b = %d after swap2\n", a, b);
return 0;
}
14 changes: 14 additions & 0 deletions Lectures/Lecture2/Codes/B-pointer-clac.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <stdio.h>

int main(void) {
int array[10] = {0};
printf("array = %p\n", array);
int *p1 = array, *p2 = array;
printf("p1 = %p, p2 = %p\n", p1, p2);
p1 = p1 + 1;
printf("p1 = %p, p2 = %p\n", p1, p2);
p2 = p2 + 9;
printf("p1 = %p, p2 = %p\n", p1, p2);
printf("p2 - p1 = %u\n", (unsigned int)(p2 - p1));
return 0;
}
7 changes: 7 additions & 0 deletions Lectures/Lecture2/Codes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
在本目录下打开终端,输入:

```bash
make
```

`./build`目录下生成对应的可执行文件
17 changes: 17 additions & 0 deletions Lectures/Lecture2/Codes/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
BUILD_DIR = ./build
CC := gcc
CFLAGS := -Wall -Wextra -g -std=c11
SRCS := $(wildcard *.c)
TARGETS := $(SRCS:%.c=$(BUILD_DIR)/%)

all: $(TARGETS)

$(BUILD_DIR)/%: %.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -o $@ $<

clean:
-rm -rf $(BUILD_DIR)

.PHONY: clean all

Loading

0 comments on commit 3212dce

Please sign in to comment.