C语言基础(2023/11/27~12/12)
D1.Linux终端指令和基本使用
第一天上课,线上上课
作业:
- 整理思维导图
- 课上练习重新写一遍
- 思维导图晚上十一点前发在群里
D2.vim,gcc和数据类型
第二天线上,有点难跟上
作业:
-
整理思维导图,复习课上内容
-
课上的宏定义练习再做一遍
-
计算下面宏定义的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 1、求NUM的结果 #define N 8 #define M N+3*N #define NUM M*N+N/5+M*7
8+3*8*8+8/5+8+3*8*7 8+192+1+8+168 = 377
2、求以下程序的输出结果 #include #define ADD(a,b) a+b int main() { printf("%d\n",ADD(3,9)); return 0; }
|
-
背会7种基本数据类型
-
作业完成十点前截图发群里(所有)
D3.原反补码和运算符
回看课程笔记感觉今天讲的挺重要的……
作业:
-
signed char c = 129; %d输出的结果(所有低于4Byte的数据,在运算时都补成4Byte的有符号数,高位补符号位)
c = 255,%d输出的结果
c = 213,%d输出的结果
-
使用宏定义完成+、-、*、/和%功能,
要求:/可以实现两数整除
如:10/4 结果为2.5
1 2 3 4 5 6 7 8 9
| #include <stdio.h> #define DIV(a,b) a/b int main(int argc, const char *argv[]) { int num1 = 10,num2 = 4; printf("%f\n",DIV((float)num1,num2)); return 0; }
|
-
整理思维导图
-
整理课上scanf吸收垃圾字符的代码
-
理解getchar获取和putchar输出的逻辑
-
有问题及时问
-
作业十一点前截图发到群里
D4.语法结构-if,switch case
哎,好多事情要忙
作业:
-
整理思维导图
-
有unsigned int a; 给第7个bit位置1,给第9个bit位置0,给第21个bit位取反
1 2 3
| a|=(0x1<<7) a&=~(0x1<<9) a^=(0x1<<21)
|
-
.将data中的第7:4置1,保持其他位不变
-
终端输入一个字符,判断是大写字母、小写字母、数字字符还是其他字符;如果是大写字母转成小写字母,如果是小写字母转换成大写字母,如果是数字字符,转换成对应的整形,如果是其他字符转换成#
-
复习课上练习和代码(运算符优先级,逻辑运算部分的练习多看看)
-
晚上十一点前交作业
D.5循环结构
嗯,今天状态不错不但听进去了,还跟着写练习,快夸我好棒!第一周的学习告一段落,给我的感受是还行:-)
作业:
-
整理思维导图
-
终端输入行数,打印金字塔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <stdio.h>
void main(){ printf("请输入行数:"); int l=0; scanf("%d",&l); int ll=l,i=0; while(l>0){ while(i<=2*ll-l){ if(i>=l){ printf("⏹️"); }else{ printf(" "); } i++; } printf("\n"); i=0; l--; } }
|
-
打印倒九九乘法表
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdio.h> void main(){ int i=1,j=1; while(i<=9){ while(j<=9){ printf("%dx%d=%d ",j,i,i*j); j++; } j=i+1; printf("\n"); i++; } }
|
-
思考两数交换的方法
-
整理课上的所有代码
-
百钱买百鸡问题:我国古代数学家张丘建在《算经》一书中曾提出过著名的 “百钱买百鸡” 问题,该问题叙述如下:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <stdio.h>
void main(){ int cock=0,hen=0,small=0; while(cock<=100){ while(hen<=100){ while(small<=100){ if((cock*15+hen*9+small)==300 && (cock+hen+small)==100){ printf("🐓=%d,🐔=%d,🐥=%d\n",cock,hen,small); } small+=3; } small=0; hen++; } hen=0; cock++; } }
|
-
打印字母图形
-
周日十一点前交作业
D6.for循环,冒泡排序
作业:
1.思维导图
2.输入一个数,计算是否是完数
完数:除本身约数和等于本身
eg:6: 1 2 3 6
1+2+3==6
3.循环输入n个元素存到数组,计算数组中素数的个数
4.循环输入数组,实现冒泡降序排序,循环输出
5.循环输入数组,计算第二大值
int arr[]={12,33,24,33,13};
第二大值计算24
D7.字符数组+二维数组
D8.函数
1.输入一个字符串,计算空格的个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int main(int argc, const char *argv[]){ char arr[20]; gets(arr);
size_t count=0;
for (int i = 0; arr[i]!='\0' ; i++){ if(arr[i]==' '){ count++; } }
printf("空格的个数是:%ld\n",count);
return 0; }
|
2.输入一个字符串,计算单词的个数
eg: “good good study”(空格的格式可能是多个)
单词的个数是3,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <stdio.h>
int main(int argc, const char *argv[]){ char arr[20]; gets(arr);
size_t count=0;
int i =0;
while(arr[i]!='\0'){
if(arr[i]!=' ' && (arr[i+1]==' '||arr[i+1]=='\0')){ count++; }
i++; }
printf("单词的个数是:%ld\n",count);
return 0; }
|
3.矩阵相乘:前提条件A矩阵的列数需要和B矩阵的行数相同
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>
int main(int argc, const char *argv[]){ int line1=0,cow1=0; printf("line1 cow1:"); scanf("%d %d",&line1,&cow1); int line2=0,cow2=0; printf("line2 cow2:"); scanf("%d %d",&line2,&cow2);
if(cow1!=line2){ printf("error!\n"); return 0; }
int a[line1][cow1],b[line2][cow2],ans[20][20]={0};
printf("a:\n"); for (int i = 0; i < line1 ; i++){ for (int j = 0; j < cow1; j++){ scanf("%d",&a[i][j]); } }
printf("b:\n"); for (int i = 0; i < line2 ; i++){ for (int j = 0; j < cow2; j++){ scanf("%d",&b[i][j]); } }
for (int i = 0; i < line1 ; i++){ for (int j = 0; j < cow2; j++){ for (int k = 0; k <line1; k++){ ans[i][j]+=a[i][k]*b[k][j]; }
printf("%d ",ans[i][j]); } puts(" "); }
return 0; }
|
4.定义有参无返函数实现杨慧三角
参数:二维数组,行,列
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>
void YanhuiTri(int n){ int arr[n][n]; for (int i = 0; i < n; i++){ for (int j = 0; j <= i; j++){ if(j==0||i==j){ arr[i][j]=1; }else{ arr[i][j]=arr[i-1][j]+arr[i-1][j-1]; }
printf("%-3d",arr[i][j]);
} puts(" "); } }
int main(int argc, const char *argv[]){ int a; scanf("%d",&a);
YanhuiTri(a); return 0; }
|
5.定义有参无返函数实现二维数组转置?
参数:二维数组,行,列
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> #include <string.h> #include <stdlib.h> void Rev(int line,int row,int a[line][row]); int main(int argc, const char *argv[]){ int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int line=sizeof(a)/sizeof(a[0]); int row=sizeof(a[0])/sizeof(a[0][0]); Rev(line,row,a); return 0; }
void Rev(int line,int row,int a[line][row]){ int b[row][line]; for(int i=0;i<line;i++){ for(int j=0;j<row;j++){ b[j][i]=a[i][j]; } }
for(int i=0;i<row;i++){ for(int j=0;j<line;j++){ printf("%-3d",b[i][j]); } puts(""); } }
|
6.输入一个字符串实现单词的逆置
eg:“good good study”
输出:“study good good”
7.输入n个字符串每个字符串20字节,并实现输出
D9.指针
C语言高级(2023/12/12~12/18)
数据结构(2023/12/18~12/23)
IO进程线程(2023/12/29~2024/10/2)
D1.IO基础
作业:
1> 使用fgets统计一个文件的行号
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 main(int argc, const char *argv[]){ FILE *fp=NULL; if(argc!=2){ puts("输入有误"); puts("eg:/a.out test.txt"); return -1; } if((fp=fopen(argv[1],"r"))==NULL){ perror("fopen error:"); return -1; }
int line=0;
char buff[128]; while(NULL!=fgets(buff,sizeof(buff),fp)){ line++; }
printf("此文件有%d行\n",line); fclose(fp); return 0; }
|
2> 使用fgets、fputs完成两个文件的拷贝
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
|
#include <stdio.h>
int main(int argc, const char *argv[]){ if(argc!=3){ puts("输入有误!"); return -1; } FILE* fp=NULL; FILE*fp_cp=NULL; if((fp=fopen(argv[1],"r"))==NULL){ perror("打开1文件出错:"); return -1; }
if((fp_cp=fopen(argv[2],"w"))==NULL){ perror("打开2文件出错:"); return -1; }
char buff[1024]; while(fgets(buff,sizeof(buff),fp)!=NULL){ fputs(buff,fp_cp); }
puts("拷贝成功!"); fclose(fp); fclose(fp_cp); return 0; }
|
3> 向文件中输出当前的系统时间
1 2 3 4 5 6 7 8 9 10
| 1、16:42:50 2、16:42:51 3、16:42:52 。。。 ctrl + C ./a.out 6、17:10:03 7、17:10:04 8、17:10:05 。。。
|
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 <time.h> #include <unistd.h>
time_t sys_time = 0; char time_buff[128] = ""; struct tm *t; int line = 1;
int get_time() { time(&sys_time); t = localtime(&sys_time); sprintf(time_buff, "%4d[%4d/%02d/%02d-%02d:%02d:%02d]\n", line, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
return t->tm_sec; }
int main(int argc, const char *argv[]) {
FILE *fp = NULL; int last_sec = -1;
if ((fp = fopen("./time.txt", "r")) == NULL) { perror("打开文件失败:"); }
char buff[128]; while (NULL != fgets(buff, sizeof(buff), fp)) { line++; }
while (1) { if ((fp = fopen("./time.txt", "a")) == NULL) { perror("打开文件失败:"); return -1; } sleep(1);
if (last_sec != get_time()) { last_sec = t->tm_sec; fputs(time_buff, fp); line++; } printf("%d\n", line); fclose(fp); }
return 0; }
|
D2.IO基础
作业
1> 使用fread、fwrite完成两个文件的拷贝
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
|
#include <stdio.h>
int main(int argc, const char *argv[]) { if(argc!=3) { puts("输入错误!"); return -1; } FILE* fp=NULL; FILE* fp_cp=NULL;
if((fp=fopen(argv[1],"r"))==NULL) { perror("fopen error:"); return -1; }
if((fp_cp=fopen(argv[2],"w"))==NULL) { perror("fopen error:"); return -1; }
char buff;
while (1) { fread(&buff,1,sizeof(buff),fp); fwrite(&buff,1,sizeof(buff),fp_cp); if(feof(fp)) { break; } }
fclose(fp); fclose(fp_cp);
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 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#include <stdio.h> #include <stdlib.h> #include <string.h>
enum Operate { REGISTER, LOGIN, EXIT }; char *op_msg[] = {"注册", "登录", "退出"};
enum Operate menu;
int do_register() { FILE *wfp =NULL; char username_reg[20]; char pwd_reg[20];
printf("请输入账号:"); fgets(username_reg,sizeof(username_reg),stdin); printf("请输入密码:"); fgets(pwd_reg,sizeof(pwd_reg),stdin);
username_reg[strlen(username_reg)-1]='\0'; pwd_reg[strlen(pwd_reg)-1]='\0';
if((wfp=fopen("./user.txt","a+"))==NULL) { perror("open user.txt error:"); return -1; }
fprintf(wfp,"%s %s\n",username_reg,pwd_reg); fclose(wfp); printf("注册成功!\n");
return 0; }
int do_login() { FILE *wfp =NULL; char input_username[20]; char input_pwd[20];
char username_reg[20]; char pwd_reg[20];
printf("请输入账号:"); fgets(input_username,sizeof(input_username),stdin); printf("请输入密码:"); fgets(input_pwd,sizeof(input_pwd),stdin);
input_username[strlen(input_username)-1]='\0'; input_pwd[strlen(input_pwd)-1]='\0';
if((wfp=fopen("./user.txt","r"))==NULL) { perror("open user.txt error:"); return -1; }
while(1) { int res = fscanf(wfp,"%s %s",username_reg,pwd_reg); if (res<0) { printf("没有这个用户\n"); fclose(wfp); return 1; }
if(strcmp(username_reg,input_username)==0 && strcmp(pwd_reg,input_pwd)==0){ printf("登录成功!\n"); fclose(wfp); return 0; } }
}
int main(int argc, const char *argv[]) { while (1) { for (int i = 0; i <= EXIT; i++) { printf("【%d】:%s\t", i, op_msg[i]); if ((i + 1) % 2 == 0) { puts(""); } } puts(""); printf("请输入要执行的操作:"); scanf("%d", &menu); while (getchar() != '\n'); switch (menu) { case REGISTER: do_register(); break; case LOGIN: do_login(); break; case EXIT: exit(EXIT_SUCCESS); default: printf("输入序号有误,请重新输入:"); } printf("按任意键清屏\n"); while (getchar() != '\n'); system("clear"); }
return 0; }
|
3> 完成图像文件信息的读写操作
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
|
#include <stdio.h>
int main(int argc, const char *argv[]){ FILE *fp=NULL; if(NULL==(fp=fopen("./output.bmp","r+"))) { perror("fopen error:"); return -1; }
fseek(fp, 0x02, SEEK_SET); unsigned int size; fread(&size, sizeof(size), 1, fp); printf("size = %d\n", size);
unsigned int x,y; fseek(fp, 0x12, SEEK_SET); fread(&x, sizeof(size), 1, fp); fread(&y, sizeof(size), 1, fp); printf("x = %d\ny = %d\n", x,y);
fseek(fp, 54, SEEK_SET);
unsigned char color[3] = {255, 0, 0};
for(int i=0; i<800; i++) { for(int j=0; j<33; j++) { fwrite(color, sizeof(color), 1, fp); } } fclose(fp); return 0; }
|
面试题目
1.标准I0与文件IO的区别
标准IO依赖的是标准库,有缓冲区,效率高;文件IO依赖于系统调用,效率较低
2.什么是IO
input和output,IO就是程序对外部设备完成信息的交换过程
3.什么是文件指针?
指向文件的指针变量,可以通过这个变量来完成对文件的各种操作
4.简述一下系统调用
系统调用是用户空间程序与内核空间交互的一种方式,允许用户程序执行一些只有操作系统内核能够执行的特权操作。
5.如何判断一个单向链表中有环
遍历整个链表,判断某个结点是否被访问多次
D3.IO基础
作业
- 使用标准io完成两个文件的拷贝
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>
int main(int argc, const char *argv[]){ if(argc!=3){ puts("输入有误!"); return -1; } FILE* fp=NULL; FILE*fp_cp=NULL; if((fp=fopen(argv[1],"r"))==NULL){ perror("打开1文件出错:"); return -1; }
if((fp_cp=fopen(argv[2],"w"))==NULL){ perror("打开2文件出错:"); return -1; }
char buff[1024]; while(fgets(buff,sizeof(buff),fp)!=NULL){ fputs(buff,fp_cp); }
puts("拷贝成功!"); fclose(fp); fclose(fp_cp); return 0; }
|
- 使用文件IO完成两个文件的拷贝
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
| #include <stdio.h> #include <fcntl.h> #include <unistd.h>
int main(int argc, const char *argv[]) { if(argc!=3) { puts("输入有误"); return -1; } int fd=-1,fd_cp=-1; fd=open(argv[1],O_RDONLY); if(fd==-1) { perror("打开文件1失败:"); return -1; } fd_cp=open(argv[2],O_WRONLY | O_CREAT | O_TRUNC,0664); if(fd_cp==-1) { perror("打开文件2失败:"); return -1; }
char buff[4096]; int res; while((res=read(fd,buff,sizeof(buff)))>0) { write(fd_cp,buff,res); } close(fd); close(fd_cp); }
|
- 将stat函数实现一遍
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
| #include<myhead.h> int main(int argc, const char *argv[]) { struct stat sb; stat(argv[1], &sb); switch(sb.st_mode&S_IFMT) { case S_IFSOCK: { printf("这是套接字文件\t"); } break; case S_IFLNK: { printf("这是链接文件\t"); } break; case S_IFREG: { printf("这是普通文件\t"); } break; case S_IFBLK: { printf("这是块设备文件\t"); } break; case S_IFDIR: { printf("这是目录文件\t"); } break; case S_IFCHR: { printf("这是字符设备文件\t"); } break; case S_IFIFO: { printf("这是管道文件\t"); } break; } printf("%#o\t%ld\t%ld\n", sb.st_mode&0777, sb.st_size, sb.st_ino); 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 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 72 73 74 75 76 77 78 79 80 81 82
| #include<myhead.h> int main(int argc, const char *argv[]) { if(argc != 2) { printf("input error\n"); printf("usage:./a.out name\n"); return -1; } DIR *dp = NULL; if((dp = opendir(argv[1])) == NULL) { perror("opendir error"); return -1; } struct dirent *sdp = NULL; while((sdp = readdir(dp)) != NULL) { printf("inode:%10ld, size:%10d, %10s, ",\ sdp->d_ino, sdp->d_reclen, sdp->d_name); switch(sdp->d_type) { case DT_BLK: { printf("b\n"); } break; case DT_CHR: { printf("c\n"); } break; case DT_DIR: { printf("d\n"); } break; case DT_FIFO: { printf("p\n"); } break; case DT_LNK: { printf("l\n"); } break; case DT_REG: { printf("-\n"); } break; case DT_SOCK: { printf("s\n"); } break; } } closedir(dp); return 0; }
|
D4.进程线程基础
作业
1> 创建出三个进程完成两个文件之间拷贝工作,子进程1拷贝前一半内容,子进程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 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h>
int main(int argc, const char *argv[]) { if (argc != 3) { puts("输入有误!"); return -1; } FILE *fp = 0; FILE *fp_cp = 0; if ((fp = fopen(argv[1], "r")) == NULL) { perror("fopen:"); return -1; }
if ((fp_cp = fopen(argv[2], "w")) == NULL) { perror("fopen:"); return -1; }
fseek(fp, 0, SEEK_END); long file_size = ftell(fp); long half_size = file_size / 2; rewind(fp);
pid_t pid1 = fork(); if (pid1 == 0) { char buff; while (ftell(fp) < half_size) { int res = fread(&buff, 1, sizeof(buff), fp); fwrite(&buff, 1, res, fp_cp); }
exit(EXIT_SUCCESS); } else if (pid1 == -1) { perror("fork error"); return -1; }
pid_t pid2 = fork(); if (pid2 == 0) { sleep(1); char buff; fseek(fp, half_size, SEEK_SET); fseek(fp_cp, half_size, SEEK_SET); while (!feof(fp)) { int res = fread(&buff, 1, sizeof(buff), fp); fwrite(&buff, 1, res, fp_cp); } exit(EXIT_SUCCESS); } else if (pid1 == -1) { perror("fork error"); return -1; }
wait(NULL); wait(NULL);
fclose(fp); fclose(fp_cp);
return 0; }
|
D5.进程线程通信
作业:
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 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
|
#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <pthread.h> #include <string.h>
pthread_mutex_t mutex;
void* task(void *arg) { while (1) { pthread_mutex_lock(&mutex);
printf("子线程");
pthread_mutex_unlock(&mutex); }
}
int main(int argc, const char *argv[]) { pthread_t tid;
pthread_mutex_init(&mutex, NULL);
if(pthread_create(&tid,NULL,task,NULL)!=0) { perror("tid create error\n"); return -1; }
while (1) { pthread_mutex_lock(&mutex);
printf("主线程\n");
pthread_mutex_unlock(&mutex); }
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 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
|
#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <pthread.h> #include <string.h> #include <semaphore.h>
sem_t sem;
void* task1(void* arg) { while(1) { sem_post(&sem); printf("post了sem\n"); sleep(2); } pthread_exit(NULL); }
void* task2(void* arg) { while(1) { sem_wait(&sem); printf("收到了\n");
}
pthread_exit(NULL); }
int main(int argc, const char *argv[]) { pthread_t tid1,tid2;
sem_init(&sem,0,0);
if((pthread_create(&tid1,NULL,task1,NULL))!=0) { perror("thread creat error"); return -1; } if((pthread_create(&tid2,NULL,task2,NULL))!=0) { perror("thread creat error"); return -1; }
pthread_join(tid1,NULL); pthread_join(tid2,NULL);
return 0; }
|
3> 使用三个线程完成两个文件的拷贝,线程1完成拷贝前一半,线程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 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <pthread.h> #include <string.h> #include <semaphore.h>
sem_t sem; int len,half_hen; const char *srcFile,*destFile;
int file_len(const char *file) { FILE* fp=NULL; if((fp=(fopen(file,"r")))==NULL) { perror("open fire error"); return -1; } fseek(fp,0,SEEK_END); return ftell(fp); }
int copy_file(const char *srcFile, const char *destFile, int begin, int end) { FILE* srcfp=NULL; FILE* destfp=NULL; if ((srcfp=(fopen(srcFile, "r"))) == NULL) { perror("open srcFile error"); return -1; } if ((destfp=(fopen(destFile, "w"))) == NULL) { perror("open destFile error"); return -1; }
fseek(destfp,begin,SEEK_SET); fseek(srcfp,begin,SEEK_SET); char buff; while(ftell(srcfp)<end) { int res=fread(&buff,1,sizeof(buff),srcfp); fwrite(&buff,1,res,destfp); } fclose(srcfp); fclose(destfp); return 0; }
void *task1(void *arg) { copy_file(srcFile,destFile,0,half_hen); pthread_exit(NULL); }
void *task2(void *arg) { copy_file(srcFile,destFile,half_hen,len); pthread_exit(NULL);
}
int main(int argc, const char *argv[]) { if(argc!=3) { printf("输入有误!\n"); return -1; }
srcFile=argv[1]; destFile=argv[2];
len=file_len(argv[1]); half_hen=len/2; pthread_t tid1, tid2; if ((pthread_create(&tid1, NULL, task1, NULL)) != 0) { perror("thread creat error"); return -1; } if ((pthread_create(&tid2, NULL, task2, NULL)) != 0) { perror("thread creat error"); return -1; }
pthread_join(tid1, NULL); pthread_join(tid2, NULL);
return 0; }
|
4> 使用三个线程完成:线程1输出字符’A’,线程2输出字符’B’,线程3输出字符’C’,要求输出结果为:ABCABCABCABCABC…
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <pthread.h> #include <string.h> #include <semaphore.h>
sem_t sem1,sem2,sem3;
void* task1(void *arg) { while (1) { sem_wait(&sem2); printf("B"); fflush(stdout); sem_post(&sem3); } }
void* task2(void *arg) { while (1) { sem_wait(&sem3); printf("C"); fflush(stdout); sem_post(&sem1); } }
int main(int argc, const char *argv[]) { sem_init(&sem1,0,1); sem_init(&sem2,0,0); sem_init(&sem2,0,0); pthread_t tid1, tid2; if ((pthread_create(&tid1, NULL, task1, NULL)) != 0) { perror("thread creat error"); return -1; } if ((pthread_create(&tid2, NULL, task2, NULL)) != 0) { perror("thread creat error"); return -1; } printf("线程创建成功\n"); while (1) { sem_wait(&sem1); printf("A"); fflush(stdout); sem_post(&sem2); sleep(1); } pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0; }
|
5> 周末完成C语言基础测试题
没写完,哈哈
D6.进程线程通信
作业
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 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <pthread.h> #include <string.h>
int rfd = -1; int wfd = -1; int userid = 0;
void *receive(void *arg) { char rbuf[128] = ""; while (1) { bzero(rbuf, sizeof(rbuf)); read(rfd, rbuf, sizeof(rbuf)); printf("*******新消息*******\n"); printf("\n%s\n\n", rbuf); printf("请输入回复内容:\n");
if (strcmp(rbuf, "quit") == 0) { break; } } close(rfd); pthread_exit(NULL); }
void *send(void *arg) { char wbuf[128] = ""; while (1) { bzero(wbuf, sizeof(wbuf)); fflush(stdout); read(0, wbuf, sizeof(wbuf)); wbuf[strlen(wbuf) - 1] = 0;
write(wfd, wbuf, sizeof(wbuf)); if (strcmp(wbuf, "quit") == 0) { break; } } close(wfd); pthread_exit(NULL); }
int main(int argc, const char *argv[]) { printf("myfifo create success\n");
printf("写端打开成功\n"); printf("请输入用户ID:"); scanf("%d", &userid); printf("等待其他用户上线。\n"); switch (userid) { case 1: if ((wfd = open("./fifo1", O_WRONLY)) == -1) { perror("open error"); return -1; } if ((rfd = open("./fifo2", O_RDONLY)) == -1) { perror("open error"); return -1; }
break; case 2: if ((rfd = open("./fifo1", O_RDONLY)) == -1) { perror("open error"); return -1; } if ((wfd = open("./fifo2", O_WRONLY)) == -1) { perror("open error"); return -1; } break; default: break; }
system("clear");
printf("fifo create success\n");
pthread_t tid1, tid2;
if (pthread_create(&tid1, NULL, receive, NULL) != 0) { printf("tid1 creat error\n"); return -1; }
if (pthread_create(&tid2, NULL, send, NULL) != 0) { printf("tid1 creat error\n"); return -1; }
printf("线程创建成功!\n");
pthread_join(tid1, NULL); pthread_join(tid2, NULL);
return 0; }
|
D7.进程线程通信
作业
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 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <pthread.h> #include <string.h> #include <signal.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>
int userid = 0;
char username1[128]; char username2[128];
struct message { long mtype; char mtext[4096]; };
key_t key = 0;
int msgid = 0;
#define SIZE (sizeof(struct msgbuf) - sizeof(long))
void send_message(int msgid, long mtype, const char *sender, const char *receiver) { struct message msg; msg.mtype = mtype; printf("[%s] Enter a message for %s: ", sender, receiver); fgets(msg.mtext, sizeof(msg.mtext), stdin);
if (msgsnd(msgid, &msg, sizeof(msg.mtext), 0) == -1) { perror("msgsnd"); exit(EXIT_FAILURE); } }
void receive_message(int msgid, long mtype, const char *receiver) { struct message msg;
if (msgrcv(msgid, &msg, sizeof(msg.mtext), mtype, 0) == -1) { perror("msgrcv"); exit(EXIT_FAILURE); }
printf("[%s] Received message: %s\n", receiver, msg.mtext); }
void *receive(void *arg) { while (1) { receive_message(msgid, 2, username1); } }
void *send(void *arg) { send_message(msgid, 1, username1, username2); }
int main(int argc, const char *argv[]) { if ((key = ftok("/", 'a')) == -1) { perror("fork error"); return -1; }
if ((msgid = msgget(key, IPC_CREAT | 0664)) == -1) { perror("msgget error"); return -1; }
printf("请输入您的用户名:"); fgets(username1,sizeof(username1), stdin);
printf("请输入对方的用户名:"); fgets(username2,sizeof(username2), stdin); pthread_t tid1, tid2;
if (pthread_create(&tid1, NULL, receive, NULL) != 0) { printf("tid1 creat error\n"); return -1; }
if (pthread_create(&tid2, NULL, send, NULL) != 0) { printf("tid1 creat error\n"); return -1; }
printf("线程创建成功!\n");
pthread_join(tid1, NULL); pthread_join(tid2, NULL);
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 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
| #include<myhead.h>
void handler(int signum) { if(signum == SIGINT) { printf("用户按下了ctrl + c键\n"); } if(signum == SIGTSTP) { printf("用户按下了ctrl + z键\n"); } }
int main(int argc, const char *argv[]) {
if(signal(SIGINT, handler) == SIG_ERR) { perror("signal error"); return -1; } if(signal(SIGTSTP, handler) == SIG_ERR) { perror("signal error"); return -1; } while(1) { sleep(1); 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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include<myhead.h>
void handler(int signum) { if(signum == SIGINT) { printf("用户按下了ctrl + c键\n"); } if(signum == SIGTSTP) { printf("用户按下了ctrl + z键\n"); } if(signum == SIGSTOP) { printf("用户按下了ctrl + z键\n"); } }
int main(int argc, const char *argv[]) {
if(signal(SIGSTOP, SIG_DFL) == SIG_ERR) { perror("signal error"); return -1; } while(1) { sleep(1); printf("我真的还想再活五百年\n"); } return 0; }
|
3> 将共享内存相关代码重新实现一遍
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 44 45 46 47 48 49 50 51 52 53 54
| #include<myhead.h> #define PAGE_SIZE 4096 int main(int argc, const char *argv[]) { key_t key = -1; if((key = ftok("/", 't')) == -1) { perror("ftok error"); return -1; } printf("key = %#x\n", key); int shmid = 0; if((shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664)) == -1) { perror("shmget error"); return -1; } printf("shmid = %d\n", shmid); char *addr = (char *)shmat(shmid, NULL, 0); if(addr == (void *)-1) { perror("shmat error"); return -1; } printf("addr = %p\n", addr); while(1) { fgets(addr, PAGE_SIZE, stdin); addr[strlen(addr) - 1] = '\0'; if(strcmp(addr, "quit") == 0) { break; } } while(1); 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 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
| #include<myhead.h> #define PAGE_SIZE 4096 int main(int argc, const char *argv[]) { key_t key = -1; if((key = ftok("/", 't')) == -1) { perror("ftok error"); return -1; } printf("key = %#x\n", key); int shmid = 0; if((shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664)) == -1) { perror("shmget error"); return -1; } printf("shmid = %d\n", shmid); char *addr = (char *)shmat(shmid, NULL, 0); if(addr == (void *)-1) { perror("shmat error"); return -1; } printf("addr = %p\n", addr); while(1) { printf("共享内存中的数据为:%s\n", addr); sleep(1); if(strcmp(addr, "quit") == 0) { break; } } if(shmdt(addr) == -1) { perror("shmdt error"); return -1; } if(shmctl(shmid, IPC_RMID, NULL) == -1) { perror("shmctl error"); return -1; } return 0; }
|
D8. 信号量(信号灯集)&库的制作
作业
使用信号灯集完成三个进程的同步,A进程输出字符A,B进程输出字符B,C进程输出字符C,要求输出结果为ABCABCABCABCABC…
网络通信基础(2024/01/12~01/22)
D1.发展史&TCP/IP
D2.TCP和UDP基础通信模型
D3.
D4.多点通信&域套接字
作业
1> 将广播、组播、流式域套接字、报式域套接字各实现一遍
2> 完成TFTP文件传输作业
D5.IO模型分类
作业
1> 使用select实现TCP客户端的并发
2> 使用poll实现TCP服务器的并发
D6&D7.数据库
C++&QT(2024/01/24~NOW)
D1.C++基础
提示并输入一个字符串,统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数
要求使用C++风格字符串完成
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
| #include <iostream>
using namespace std;
int main() { string str; cout << "请输入一个字符串:"; getline(cin, str); int uppercaseCount = 0; int lowercaseCount = 0; int digitCount = 0; int spaceCount = 0; int otherCount = 0; for (char ch : str) { if (isupper(ch)) uppercaseCount++; else if (islower(ch)) lowercaseCount++; else if (isdigit(ch)) digitCount++; else if (isspace(ch)) spaceCount++; else otherCount++; }
cout << "大写:" << uppercaseCount << endl; cout << "小写:" << lowercaseCount << endl; cout << "数字:" << digitCount << endl; cout << "空格:" << spaceCount << endl; cout << "其他:" << otherCount << endl;
return 0; }
|
D2&D3.C++基础
作业:
设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数和拷贝构造函数。