C语言复习

Last updated on December 25, 2023 pm

C语言复习

注意:考试内容不涵盖联合体和文件读写
本文件根据课件ppt将过往作业的重要代码加入

一.作业和课件的重要代码案例

string.h库函数部分代码实现及涉及字符串题目

1.strcpy(复制)
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
#include <stdio.h>
#include <string.h>

// 定义一个函数,实现strcpy的功能
char *my_strcpy(char *dest, const char *src) {
// 定义一个指针,指向目标字符串的起始位置
char *p = dest;
// 用一个循环,从源字符串的起始位置开始,依次复制每个字符到目标字符串
while (*src != '\0') {
*p = *src;
p++;
src++;
}
// 在目标字符串的末尾添加一个空字符,表示字符串的结束
*p = '\0';
// 返回目标字符串的指针
return dest;
}

int main() {
// 定义两个字符串,用来测试函数
char str1[20] = "Hello";
char str2[20] = "World";
// 调用函数,将str2复制到str1
my_strcpy(str1, str2);
// 输出结果
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
return 0;
}

2.strcat(连接)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
void _strcat(char *str ,char *str2){
while (*str!='\0')
str++;
while (*str2!='\0')
{
*str = *str2;
str++;
str2++;
}
*str = '\0';
}
int main(int argc, char const *argv[])
{
char str[30] = "Hello world ";
char str2[30] = "I love the world";
_strcat(str,str2);
printf("%s",str);
return 0;
}

3.strlen(长度)
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
#include <stdio.h>
#include <string.h>

// 定义一个函数,实现strlen的功能
int my_strlen(const char *str) {
// 定义一个指针,指向字符串的末尾
const char *end = str;
// 用一个循环,找到空结束字符的位置
while (*end) {
end++;
}
// 返回指针之差,即字符串的长度
return end - str;
}

int main() {
// 定义一个字符串,用来测试函数
char str[] = "Hello World";
// 调用函数,计算字符串的长度
int len = my_strlen(str);
// 输出结果
printf("The length of '%s' is %zu\n", str, len);
return 0;
}

4.strcmp(比较)
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
#include <stdio.h>
#include <string.h>

// 定义一个函数,实现strcmp的功能
int my_strcmp(const char *s1, const char *s2) {
// 用一个循环,从字符串的起始位置开始,依次比较每个字符
while (*s1 && *s2) {
// 如果两个字符不相等,返回它们的差值
if (*s1 != *s2) {
return *s1 - *s2;
}
// 如果两个字符相等,继续比较下一个字符
s1++;
s2++;
}
// 如果循环结束,说明两个字符串有一个已经到达结束,返回它们的差值
return *s1 - *s2;
}

int main() {
// 定义两个字符串,用来测试函数
char str1[] = "Hello";
char str2[] = "World";
// 调用函数,比较两个字符串的大小
int result = my_strcmp(str1, str2);
// 输出结果
printf("The result of comparing '%s' and '%s' is %d\n", str1, str2, result);
return 0;
}

5.strstr(查找)
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
#include <stdio.h>
#include <string.h>

// 定义一个函数,实现strstr的功能
char *my_strstr(const char *haystack, const char *needle) {
// 如果needle为空,返回haystack
if (*needle == '\0') {
return (char *)haystack;
}
// 用一个循环,遍历haystack
while (*haystack != '\0') {
// 如果haystack和needle的第一个字符相同,就比较后面的字符
if (*haystack == *needle) {
// 定义两个指针,分别指向haystack和needle的当前位置
const char *p1 = haystack;
const char *p2 = needle;
// 用一个循环,比较p1和p2指向的字符是否相同
while (*p1 != '\0' && *p2 != '\0' && *p1 == *p2) {
// 如果相同,就继续比较下一个字符
p1++;
p2++;
}
// 如果p2指向了'\0',说明needle已经匹配完毕,返回haystack的当前位置
if (*p2 == '\0') {
return (char *)haystack;
}
}
// 如果haystack和needle的第一个字符不同,就继续遍历haystack
haystack++;
}
// 如果循环结束,说明没有找到needle,返回NULL
return NULL;
}

int main() {
// 定义两个字符串,用来测试函数
char str1[] = "I love you";
char str2[] = "love";
// 调用函数,查找str2在str1中的位置
char *ret = my_strstr(str1, str2);
// 输出结果
if (ret) {
printf("子串是:%s\n", ret);
} else {
printf("没有找到子串\n");
}
return 0;
}

回文判断
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
#include <string.h>
#include <stdio.h>
int check(char *str,int len){
char *end = str + len-1;
while (str<=end)
{
if (*str!=*end)
{
return 0;
}
str++;
end--;
}
return 1;
}
//递归形式
int check2(char *head,char *tail){
if (head>tail)
{
return 1;
}
if (*head==*tail)
{
return check2(++head, --tail);
}
else{
return 0;
}

}
int main(int argc, char const *argv[])
{
char str[30] = "able was I ere I saw elba";
if (check2(str,str+strlen(str)-1))
{
printf("是");
}
else{
printf("否");
}

return 0;
}


排序算法相关

1.冒泡排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
void bubble_sort(int arr[], int len) {
        int i, j, temp;
        for (i = 0; i < len - 1; i++)
                for (j = 0; j < len - 1 - i; j++)//注意这两处的i和j不大于什么
                        if (arr[j] > arr[j + 1]) {
                                temp = arr[j];
                                arr[j] = arr[j + 1];
                                arr[j + 1] = temp;
                        }
}
int main() {
        int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
        int len = sizeof(arr) / sizeof(arr[0]);
        bubble_sort(arr, len);
        int i;
        for (i = 0; i < len; i++)
                printf("%d ", arr[i]);
        return 0;
}
2.选择排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void swap(int *a,int *b) //交換兩個變數
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void selection_sort(int arr[], int len)
{
    int i,j;

        for (i = 0 ; i < len - 1 ; i++)
    {
                int min = i;
                for (j = i + 1; j < len; j++)     //走訪未排序的元素
                        if (arr[j] < arr[min])    //找到目前最小值
                                min = j;    //紀錄最小值
                swap(&arr[min], &arr[i]);    //做交換
        }
}
2.插入排序
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
#include <stdio.h>
void xuanze(int *arr){
int j,key;
for (int i = 1; i < 10; i++)
{
key = arr[i];
j = i - 1;
while (j>=0 && key<arr[j])
{
arr[j + 1] = arr[j];
j--;
}
arr[j+1] = key;
}

}
int main(int argc, char const *argv[])
{
int arr[10] = {1,5,3,7,4,2,9,6,10,8};
xuanze(arr);
for (int i = 0; i < 10; i++)
{
printf("%d ",arr[i]);
}


return 0;
}


递归相关

1.进制转换实现

本质就是利用如
7%2=3···1
3%2=1···1
1%2=0···1
得出的进制数就是0111

9%2=4···1
4%2=2···0
2%2=1···0
得出的进制数就是1001
最高位是最后一次除法的得数,后面就是从下往上的余数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//十进制转二进制代码实现
#include<stdio.h>
int change(int x){
if(x==0)
return 0;
else
return change(x/2) *10 + x % 2 ;
}
int main( )
{
int x,y;
scanf("%d",&x);
y=change(x);
printf("%10d ",y); //按 10 位宽度输出十进制整数
}
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
//十进制转十六进制代码实现
#include <stdio.h>

// 定义一个函数,将十进制数转换为十六进制数,并输出
#include <stdio.h>

char digits[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void toBase16(int num){
int r;
r = num % 16;
num = num / 16;
// Think about it: printf before calling toBase16() OR calling toBase16() before printf()?
if(num != 0)
toBase16(num);
printf("%c", digits[r]);
}

int main(void) {
int number;
printf("Please enter a number to convert:\n");
scanf("%d", &number);
printf("Corresponding 16-based number is: \n");
toBase16(number);
return 0;
}


2.递归相关算法实现
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
//递归实现二分法查找
#include <stdio.h>
int erfeng(int *arr,int target,int left,int right){
int mid = (left + right) / 2;
if (left>right)
{
return -1;
}

if (target>arr[mid])
{
left =mid;
return erfeng(arr,target,left+1,right);
}
else if (target < arr[mid])
{
right = mid;
return erfeng(arr,target,left,right-1);
}
else{
return mid;
}

}
int main(int argc, char const *argv[])
{
int arr[11] = {1,4,8,9,12,14,22,30,39,55,57};
int target;
int loc;
int left = 0, right = 11;
scanf("%d",&target);
//target = 13;
loc=erfeng(arr,target,left,right);
printf("%d",loc);
return 0;
}
1
快速排序因为不考这里略过
3.其他递归函数案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//编写计算组合数C(n,m)的函数。主函数中输入n和m的值(n>m),调用函数输出输出组合数n!/(m!(n-m)!)。
#include <stido.h>
int calculate(int n,int m);
int main(){
int n,m;
printf("Please type two numbers\n");
scanf("%d %d",&n,&m);
printf("C(n,m)=%d",calculate(n,m));
return 0;
}
int factorial(int a){
if(a==1||a==0){
return 1;
}
else{
return a*factorial(a-1);
}
}
int calculate(int n,int m){
return factorial(n) / (factorial(m)*factorial(n-m));
}

1
阶乘这里就不写了,上面那个组合数的题本质就是用了阶乘

素数相关

1.筛法
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
#include <stdio.h>

// 定义一个函数,用筛法求n以内的素数,并输出
void sieve(int n) {
// 定义一个数组,用来存储每个数是否为素数,0表示是,1表示否
int is_prime[n + 1];
// 初始化数组,假设所有数都是素数
for (int i = 0; i <= n; i++) {
is_prime[i] = 0;
}
// 从2开始,依次判断每个数是否为素数
for (int i = 2; i <= n; i++) {
// 如果i是素数,就把它的倍数都标记为非素数
/*注:也可以遍历,把is_prime[j]%is_prime
[i]==0的数标记为非负数,题目可能以这种形
式来表示筛法*/
if (is_prime[i] == 0) {
for (int j = i * 2; j <= n; j += i) {
is_prime[j] = 1;
}
}
}
// 输出素数
printf("筛法求出%d以内的素数为:\n", n);
for (int i = 2; i <= n; i++) {
if (is_prime[i] == 0) {
printf("%d ", i);
}
}
printf("\n");
}

int main() {
// 定义一个变量,用来存储要求的范围
int limit;
// 输入一个正整数
printf("请输入一个正整数:");
scanf("%d", &limit);
// 调用函数,求limit以内的素数
sieve(limit);
return 0;
}

2.求最大公约数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//辗转相除法求最大公约数
#include<stdio.h>
int gcd(int a, int b) {
int t;
while(b!=0) {
t=a%b;
a=b;
b=t;
}
return a;
}
int main() {
int a,b;
scanf("%d%d",&a,&b);
printf("gcd=%d\n",gcd(a,b));
return 0;
}
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
//更相减损术求最大公约数
#include <stdio.h>

// 定义一个函数,用更相减损术求两个数的最大公约数
int gcd(int a, int b) {
// 如果两个数相等,直接返回其中一个数
if (a == b) {
return a;
}
// 如果两个数不相等,用较大的数减去较小的数,然后递归调用函数
if (a > b) {
return gcd(a - b, b);
} else {
return gcd(a, b - a);
}
}

int main() {
// 定义两个变量,用来存储要求最大公约数的两个数
int a, b;
// 输入两个数
printf("请输入两个数:\n");
scanf("%d %d", &a, &b);
// 输出最大公约数
printf("它们的最大公约数是:%d\n", gcd(a, b));
return 0;
}


C语言复习
https://txpoki.github.io/2023/12/19/C语言复习/
Author
John Doe
Posted on
December 19, 2023
Updated on
December 25, 2023
Licensed under