├── README.md ├── 俄罗斯方块 ├── README.md ├── README.txt ├── elsfk.exe ├── main.c └── music.mp3 └── 学生管理系统 ├── 版本1 ├── README.md ├── README.txt ├── main.c └── the C of StudentInfoManagement.exe ├── 版本2 ├── README.md ├── README.txt ├── StuInfoSys.exe └── main.c └── 版本3 ├── README.md ├── README.txt ├── Student.cpp ├── Student.h ├── main.cpp ├── main.h ├── stuFile.cpp ├── stuFile.h └── the C++ of StudentInfoManagement.exe /README.md: -------------------------------------------------------------------------------- 1 | # C-LanguageProjectCombat 2 | 3 | ## 用纯C语言实现的一些项目,C语言入门级的实战程序 4 | 5 | 6 | ### 学生信息管理系统 7 | * 版本1——mian.c源代码和exe执行程序、README.txt文件 8 | * 版本2——mian.c源代码和exe执行程序、README.txt文件 9 | * 版本3——mian.cp等整个项目的源代码和exe执行程序、README.txt文件 10 | 11 | ### 俄罗斯方块游戏 12 | * main.c源代码 13 | * exe可执行程序 14 | * music.mp3音频文件 15 | * README.txt文件 16 | -------------------------------------------------------------------------------- /俄罗斯方块/README.md: -------------------------------------------------------------------------------- 1 | ### 俄罗斯方块游戏 2 | 3 | /* 4 | * 用C语言实现Win32程序,完成俄罗斯方块游戏程序 5 | * 1、窗口创建 6 | * 初始化窗口类 7 | * 注册、创建、显示窗口 8 | * 消息循环、回调函数 9 | * 10 | * 2、游戏业务逻辑实现 11 | * 二维数组布局 12 | * 13 | * 3、游戏结束 14 | * 15 | * 4、音乐媒体播放器 16 | */ 17 | 18 | #### 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 19 | #### 字符集:UTF-8 20 | #### 音乐文件放在与执行文件同一文件夹下,命名为music.mp3 21 | 22 | 23 | #### 知识点 24 | 1)C语言的量声明和定义,以及变量初始化和生命周期与可见性 25 | 2)C语言指针的定义,初始化 26 | 3)C语言内存的申请和释放 27 | 4)C语言循环结构、选择结构、分支结构 28 | 5)C语言结构体 29 | 6)C语言函数声明、实现、调用 30 | 7)C语言函数的参数、返回值 31 | 32 | 33 | #### Win32程序 34 | * 初始化窗口类,也就是一个结构体 35 | * 注册窗口 36 | * 创建窗口 37 | * 显示窗口 38 | * 消息循环,Windows就是消息驱动的 39 | * 回调函数 40 | 41 | -------------------------------------------------------------------------------- /俄罗斯方块/README.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * 用C语言实现Win32程序,完成俄罗斯方块游戏程序 3 | * 1、窗口创建 4 | * 初始化窗口类 5 | * 注册、创建、显示窗口 6 | * 消息循环、回调函数 7 | * 8 | * 2、游戏业务逻辑实现 9 | * 二维数组布局 10 | * 11 | * 3、游戏结束 12 | * 13 | * 4、音乐媒体播放器 14 | */ 15 | 16 | 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 17 | 字符集:UTF-8 18 | 音乐文件放在与执行文件同一文件夹下,命名为music.mp3 19 | 20 | 知识点 21 | 1)C语言的量声明和定义,以及变量初始化和生命周期与可见性 22 | 2)C语言指针的定义,初始化 23 | 3)C语言内存的申请和释放 24 | 4)C语言循环结构、选择结构、分支结构 25 | 5)C语言结构体 26 | 6)C语言函数声明、实现、调用 27 | 7)C语言函数的参数、返回值 28 | 29 | Win32程序 30 | 初始化窗口类,也就是一个结构体 31 | 注册窗口 32 | 创建窗口 33 | 显示窗口 34 | 消息循环,Windows就是消息驱动的 35 | 回调函数 36 | -------------------------------------------------------------------------------- /俄罗斯方块/elsfk.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2793134925/C-LanguageProjectCombat/12c3ede031ba53d1a9694cd4c42b04a0dbd9ac9d/俄罗斯方块/elsfk.exe -------------------------------------------------------------------------------- /俄罗斯方块/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.c 4 | * Author 黎为 5 | * Description 主函数作为程序的入口 6 | */ 7 | 8 | /* 9 | * 用C语言实现Win32程序,完成俄罗斯方块游戏程序 10 | * 1、窗口创建 11 | * 初始化窗口类 12 | * 注册、创建、显示窗口 13 | * 消息循环、回调函数 14 | * 15 | * 2、游戏业务逻辑实现 16 | * 二维数组布局 17 | * 18 | * 3、游戏结束 19 | * 20 | * 4、音乐媒体播放器 21 | */ 22 | #include 23 | #include 24 | #include 25 | #pragma comment(lib,"winmm.lib") 26 | 27 | #define DEF_TIMER1 1234 // 定时器 28 | 29 | int g_iSqareID = -1; 30 | int g_iLine = -1; 31 | int g_iList = -1; 32 | int g_iScore = 0; 33 | 34 | // 回调函数 35 | LRESULT CALLBACK PELouSi(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam); 36 | 37 | // 绘制函数 38 | void OnPaint(HDC hDc); 39 | 40 | // 初始化数据 41 | void onCreate(); 42 | 43 | // 背景数组 44 | char g_arrBackGroud[20][10] = {0}; 45 | // 随机方块 46 | char g_arrSqare[2][4] = {0}; 47 | 48 | // 显示方块 49 | void PaintSqare(HDC hMemDC); 50 | 51 | // 随机方块产生 52 | int CreateRandomSqare(); 53 | 54 | // 随机方块贴到背景 55 | void CopySqareToBack(); 56 | 57 | // Enter回车按键处理函数 58 | void OnReturn(HWND hWnd); 59 | 60 | // 方块下落 61 | void SqareDown(); 62 | 63 | // 定时器响应函数 64 | void OnTime(HWND hWnd); 65 | 66 | // 方块停止在最底部 0不可以落,1可以落 67 | int CanSqareDown(); 68 | // 方块停止在最底部,不覆盖其他方块,而是重叠 0不可以落,1可以落 69 | int CanSqareDown2(); 70 | // 方块是否能够左移,边界判断,0不可以左移,1可以左移 71 | int CanSqareLeft(); 72 | // 方块是否能够左移,边界左有方块情况判断,0不可以左移,1可以左移 73 | int CanSqareLeft2(); 74 | // 方块是否能够右移,边界判断,0不可以左移,1可以左移 75 | int CanSqareRight(); 76 | // 方块是否能够右移,边界左有方块情况判断,0不可以左移,1可以左移 77 | int CanSqareRight2(); 78 | 79 | // 1 to 2 停止标志 80 | void Change1To2(); 81 | 82 | // 显示2的情况方块,停止时 83 | void ShowSqare2(HDC hMemDC); 84 | 85 | // 左移动消息 86 | void OnLeft(HWND hWnd); 87 | // 右移动消息 88 | void OnRight(HWND hWnd); 89 | 90 | // 方块左移 91 | void SqareLeft(); 92 | // 方块右移 93 | void SqareRight(); 94 | 95 | // 向下加速消息 96 | void OnDown(HWND hWnd); 97 | 98 | // 向上变型 99 | void OnChangeSqare(HWND hWnd); 100 | 101 | // 一般形状变型 102 | void ChangeSqare(); 103 | // 一般形状方块能否变型条件判断 104 | int CanSqareChangeShape(); 105 | // 长方形变型 106 | void ChangeLineSqare(); 107 | // 长方形方块能否变型条件判断 108 | int CanLineSqareChangeShape(); 109 | 110 | // 消除一行方块 111 | void DestroyOneLineSqare(); 112 | 113 | // 显示积分 114 | void ShowScore(HDC hMemDC); 115 | 116 | // TODO 游戏结束失败 117 | int CanGameOver(); 118 | 119 | // WINAPI 调用约定 _stdcall 参数的入栈顺序,栈空间的清理者 120 | // 参数1,句柄:一个数,是窗口的唯一标识 121 | // 参数2,前一个句柄:同一个窗口同时打开多个 122 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR IpCmdLine, int nCmdShow) 123 | { 124 | // 初始化窗口类 125 | WNDCLASSEX wc; // WNDCLASS 126 | HWND hWnd; // 窗口句柄 127 | MSG msg; // 消息结构体 128 | 129 | wc.cbClsExtra = 0; 130 | wc.cbSize = sizeof(WNDCLASSEX); 131 | wc.cbClsExtra = 0; 132 | wc.hbrBackground = (HBRUSH)COLOR_INFOTEXT; // 背景颜色 133 | wc.hCursor = LoadCursor(NULL,IDC_ARROW); // TODO 加载系统光标,可以自定义光标图片 134 | //wc.hIcon = LoadIcon(hInstance,HAKEINTRESOURCE(IDI_ICON)); // TODO 可以自定义加载图标 135 | wc.hIcon = LoadIcon(NULL,IDI_INFORMATION); // TODO 加载系统图标,可以自定义加载图标 136 | wc.hIconSm = NULL; // NULL 默认与Icon一致 137 | wc.hInstance = hInstance; 138 | wc.lpfnWndProc = PELouSi; // 回调函数地址 139 | wc.lpszClassName = "els"; //窗口类名字,操作系统看的 140 | wc.lpszMenuName = NULL; 141 | wc.style = CS_HREDRAW | CS_VREDRAW; // 窗口风格 142 | 143 | // 注册窗口 144 | if (0 == RegisterClassEx(&wc)) 145 | { 146 | // 注册出错 147 | //int a = GetLastError(); 148 | //printf("窗口注册出错,出错码为:%d",a); 149 | return 0; 150 | } 151 | 152 | // 创建窗口 153 | hWnd = CreateWindowEx(WS_EX_TOPMOST,"els","俄罗斯方块",WS_OVERLAPPEDWINDOW,100,100,500,650,NULL,NULL,hInstance,NULL); 154 | if (NULL == hWnd)// 窗口句柄 155 | { 156 | return 0; 157 | } 158 | 159 | // 显示窗口 160 | ShowWindow(hWnd,SW_SHOWNORMAL);// nCmdShow 161 | 162 | // 播放音乐 163 | // 需要在编译器中自己连接库文件libwinmm.a,是编译器自带的静态库文件,在链接器中加入 164 | mciSendString((LPCSTR)"open .\\music.mp3 alias mymusic", NULL, 0, NULL); 165 | mciSendString((LPCSTR)"play mymusic", NULL, 0, NULL); 166 | 167 | 168 | // 消息循环 169 | while (GetMessage(&msg,NULL,0,0))// 循环获取消息队列的消息 170 | { 171 | // 翻译消息 172 | TranslateMessage(&msg); 173 | // 分发消息:标准消息、命令消息、通知消息、自定义消息 174 | DispatchMessage(&msg); 175 | } 176 | 177 | return 0; 178 | } 179 | 180 | // 回调函数 181 | LRESULT CALLBACK PELouSi(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) 182 | { 183 | PAINTSTRUCT pt; 184 | HDC hDc; 185 | 186 | switch (nMsg) 187 | { 188 | // 回调函数第一次调用,只产生一次 189 | case WM_CREATE: 190 | // 用于数据初始化,什么都没有,编译器会优化处理 191 | //GetLastError(); // 调试用的,编译器不会优化 192 | onCreate(); 193 | break; 194 | case WM_TIMER: 195 | // TODO Enter按键定时器产生消息 196 | // 定时器响应函数 197 | OnTime(hWnd); 198 | break; 199 | // 回调函数第二次调用,窗口更新(重新绘制) 200 | case WM_PAINT: 201 | // 比如窗口拉大缩小变化重绘 202 | hDc = BeginPaint(hWnd,&pt); // getDc,窗口可操作区域标识 203 | 204 | // 绘制开始 205 | OnPaint(hDc); 206 | 207 | EndPaint(hWnd,&pt); 208 | break; 209 | case WM_KEYDOWN: 210 | switch (wParam) 211 | { 212 | case VK_RETURN: 213 | // Enter回车按键处理函数 214 | OnReturn(hWnd); 215 | break; 216 | case VK_LEFT: 217 | // 左移动 218 | OnLeft(hWnd); 219 | break; 220 | case VK_RIGHT: 221 | // 右移动 222 | OnRight(hWnd); 223 | break; 224 | case VK_UP: 225 | // 向上变型 226 | OnChangeSqare(hWnd); 227 | break; 228 | case VK_DOWN: 229 | // 向下加速 230 | OnDown(hWnd); 231 | break; 232 | } 233 | break; 234 | // 退出程序窗口 235 | case WM_DESTROY: 236 | // 关闭定时器 237 | KillTimer(hWnd,DEF_TIMER1); 238 | PostQuitMessage(0); // WM_CLOSE, WM_DESTROY, WM_QUIT 239 | break; 240 | } 241 | 242 | return DefWindowProc(hWnd, nMsg, wParam, lParam); // 243 | } 244 | 245 | // 绘制函数 246 | void OnPaint(HDC hDc) 247 | { 248 | // 创建兼容性DC-ID编号 249 | HDC hMemDC = CreateCompatibleDC(hDc); 250 | // 创建一张画纸-位图 251 | HBITMAP hBitmapBack = CreateCompatibleBitmap(hDc,500,600); 252 | // 关联ID编号与画纸位图 253 | SelectObject(hMemDC,hBitmapBack); 254 | 255 | // 显示方块 256 | PaintSqare(hMemDC); 257 | ShowSqare2(hMemDC);//停止时显示方块 258 | // 显示积分 259 | ShowScore(hMemDC); 260 | 261 | // 传递图片 从内存dc传递到窗口 262 | BitBlt(hDc,0,0,500,600,hMemDC,0,0,SRCCOPY); 263 | 264 | // 释放兼容性DC 265 | DeleteObject(hBitmapBack); 266 | DeleteDC(hMemDC); 267 | } 268 | 269 | // 初始化数据 270 | void onCreate() 271 | { 272 | // 随机方块,随机种子 273 | srand((unsigned int)time(NULL)); 274 | // 产生一次 275 | CreateRandomSqare(); 276 | // 复制一次 277 | CopySqareToBack(); 278 | } 279 | 280 | // 显示方块 281 | void PaintSqare(HDC hMemDC) 282 | { 283 | int i = 0; 284 | int j = 0; 285 | HBRUSH hOldBrush;//原来画刷 286 | HBRUSH hNewBrush;//新画刷 287 | 288 | // 大方块背景 289 | Rectangle(hMemDC,0,0,300,600); 290 | 291 | // 指定显示方块 292 | /*g_arrBackGroud[2][4] = 1; 293 | g_arrBackGroud[3][3] = 1; 294 | g_arrBackGroud[3][4] = 1; 295 | g_arrBackGroud[3][5] = 1;*/ 296 | 297 | // 画刷颜色,给方块涂色 298 | 299 | hNewBrush = CreateSolidBrush(RGB(63,191,49)); 300 | hOldBrush = (HBRUSH)SelectObject(hMemDC,hNewBrush); 301 | 302 | // 遍历 303 | for (i = 0; i < 20; i++) 304 | { 305 | for (j = 0; j < 10; j++) 306 | { 307 | if (1 == g_arrBackGroud[i][j]) 308 | { 309 | // 画小方块 310 | Rectangle(hMemDC,j*30,i*30,j*30+30,i*30+30); 311 | } 312 | } 313 | 314 | } 315 | // 释放画刷 316 | hNewBrush = (HBRUSH)SelectObject(hMemDC,hOldBrush); 317 | DeleteObject(hNewBrush); 318 | } 319 | 320 | // 随机方块产生 321 | int CreateRandomSqare() 322 | { 323 | // 七个不同形状方块 324 | int iInde = rand()%7; 325 | 326 | switch(iInde) 327 | { 328 | case 0: 329 | g_arrSqare[0][0] = 1,g_arrSqare[0][1] = 1,g_arrSqare[0][2] = 0,g_arrSqare[0][3] = 0; 330 | g_arrSqare[1][0] = 0,g_arrSqare[1][1] = 1,g_arrSqare[1][2] = 1,g_arrSqare[1][3] = 0; 331 | g_iLine =0; 332 | g_iList =3; 333 | break; 334 | case 1: 335 | g_arrSqare[0][0] = 0,g_arrSqare[0][1] = 1,g_arrSqare[0][2] = 1,g_arrSqare[0][3] = 0; 336 | g_arrSqare[1][0] = 1,g_arrSqare[1][1] = 1,g_arrSqare[1][2] = 0,g_arrSqare[1][3] = 0; 337 | g_iLine =0; 338 | g_iList =3; 339 | break; 340 | case 2: 341 | g_arrSqare[0][0] = 1,g_arrSqare[0][1] = 0,g_arrSqare[0][2] = 0,g_arrSqare[0][3] = 0; 342 | g_arrSqare[1][0] = 1,g_arrSqare[1][1] = 1,g_arrSqare[1][2] = 0,g_arrSqare[1][3] = 0; 343 | g_iLine =0; 344 | g_iList =3; 345 | break; 346 | case 3: 347 | g_arrSqare[0][0] = 1,g_arrSqare[0][1] = 0,g_arrSqare[0][2] = 0,g_arrSqare[0][3] = 0; 348 | g_arrSqare[1][0] = 1,g_arrSqare[1][1] = 1,g_arrSqare[1][2] = 1,g_arrSqare[1][3] = 0; 349 | g_iLine =0; 350 | g_iList =3; 351 | break; 352 | case 4: 353 | g_arrSqare[0][0] = 0,g_arrSqare[0][1] = 1,g_arrSqare[0][2] = 0,g_arrSqare[0][3] = 0; 354 | g_arrSqare[1][0] = 1,g_arrSqare[1][1] = 1,g_arrSqare[1][2] = 1,g_arrSqare[1][3] = 0; 355 | g_iLine =0; 356 | g_iList =3; 357 | break; 358 | case 5: 359 | g_arrSqare[0][0] = 0,g_arrSqare[0][1] = 1,g_arrSqare[0][2] = 1,g_arrSqare[0][3] = 0; 360 | g_arrSqare[1][0] = 0,g_arrSqare[1][1] = 1,g_arrSqare[1][2] = 1,g_arrSqare[1][3] = 0; 361 | g_iLine =0; 362 | g_iList =4; 363 | break; 364 | case 6: 365 | g_arrSqare[0][0] = 1,g_arrSqare[0][1] = 1,g_arrSqare[0][2] = 1,g_arrSqare[0][3] = 0; 366 | g_arrSqare[1][0] = 0,g_arrSqare[1][1] = 0,g_arrSqare[1][2] = 0,g_arrSqare[1][3] = 0; 367 | g_iLine =0; 368 | g_iList =4; // TODO 以中心点为轴心进行变型 369 | break; 370 | } 371 | 372 | g_iSqareID = iInde; 373 | 374 | return iInde; 375 | } 376 | 377 | // 随机方块贴到背景 378 | void CopySqareToBack() 379 | { 380 | int i = 0; 381 | int j = 0; 382 | 383 | for(i = 0; i < 2; i++) 384 | { 385 | for (j = 0; j < 4; j++) 386 | { 387 | g_arrBackGroud[i][j+3] = g_arrSqare[i][j]; 388 | } 389 | } 390 | } 391 | 392 | // Enter回车按键处理函数 393 | void OnReturn(HWND hWnd) 394 | { 395 | // 打开定时器 396 | SetTimer(hWnd,DEF_TIMER1,500,NULL);// 1000毫秒=1秒 397 | 398 | // 关闭定时器 399 | } 400 | 401 | // 方块下落 402 | void SqareDown() 403 | { 404 | int i = 0; 405 | int j = 0; 406 | 407 | for (i = 19; i >= 0; i--) 408 | { 409 | for (j = 0; j < 10; j++) 410 | { 411 | if (1 == g_arrBackGroud[i][j]) 412 | { 413 | g_arrBackGroud[i+1][j] = g_arrBackGroud[i][j]; 414 | g_arrBackGroud[i][j] = 0; 415 | } 416 | } 417 | } 418 | } 419 | 420 | // 定时器响应函数 421 | void OnTime(HWND hWnd) 422 | { 423 | HDC hDc = GetDC(hWnd); 424 | if (1 == CanSqareDown() && 1 == CanSqareDown2()) 425 | { 426 | SqareDown(); 427 | g_iLine++; 428 | } 429 | else 430 | { 431 | // 1 to 2 停止标志 432 | Change1To2(); 433 | // 消除一行方块 434 | DestroyOneLineSqare(); 435 | 436 | // TODO 游戏结束失败 437 | if (0 == CanGameOver()) 438 | { 439 | // 结束程序 440 | KillTimer(hWnd, DEF_TIMER1); 441 | return ; 442 | } 443 | 444 | // 产生随机块 445 | CreateRandomSqare(); 446 | // 复制到背景上 447 | CopySqareToBack(); 448 | } 449 | 450 | // 显示方块 451 | //PaintSqare(hDc); 452 | OnPaint(hDc);// 内存DC, 兼容性DC 453 | 454 | ReleaseDC(hWnd,hDc); 455 | } 456 | 457 | // 方块停止在最底部 0不可以落,1可以落 458 | int CanSqareDown() 459 | { 460 | int i = 0; 461 | 462 | for (i = 0; i < 10; i++) 463 | { 464 | if (1 == g_arrBackGroud[19][i]) 465 | { 466 | return 0;// 不可以下落了,到最底部了 467 | } 468 | } 469 | return 1;// 还可以下落 470 | } 471 | 472 | // 1 to 2 停止标志 473 | void Change1To2() 474 | { 475 | int i = 0, 476 | j = 0; 477 | for (i = 0; i < 20; i++) 478 | { 479 | for (j = 0; j < 10; j++) 480 | { 481 | if (1 == g_arrBackGroud[i][j]) 482 | { 483 | g_arrBackGroud[i][j] = 2; 484 | } 485 | } 486 | } 487 | } 488 | 489 | // 显示2的情况方块,停止时方块颜色改变 490 | void ShowSqare2(HDC hMemDC) 491 | { 492 | int i = 0, 493 | j = 0; 494 | 495 | HBRUSH hOldBrush; 496 | HBRUSH hNewBrush; 497 | hNewBrush = CreateSolidBrush(RGB(233,27,182)); 498 | hOldBrush = (HBRUSH)SelectObject(hMemDC,hNewBrush); 499 | 500 | for (i = 0; i < 20; i++) 501 | { 502 | for (j = 0; j < 10; j++) 503 | { 504 | if (2 == g_arrBackGroud[i][j]) 505 | { 506 | // 画小方块 507 | Rectangle(hMemDC,j*30,i*30,j*30+30,i*30+30); 508 | } 509 | } 510 | } 511 | 512 | hNewBrush = (HBRUSH)SelectObject(hMemDC,hOldBrush); 513 | DeleteObject(hNewBrush); 514 | } 515 | 516 | // 方块停止在最底部,不覆盖其他方块,而是重叠 0不可以落,1可以落 517 | int CanSqareDown2() 518 | { 519 | int i = 0, 520 | j = 0; 521 | for (i = 19; i >= 0; i--) 522 | { 523 | for (j = 0; j < 10; j++) 524 | { 525 | if (1 == g_arrBackGroud[i][j]) 526 | { 527 | if (2 == g_arrBackGroud[i+1][j]) 528 | { 529 | return 0; 530 | } 531 | } 532 | } 533 | } 534 | return 1; 535 | } 536 | 537 | // 左移动 538 | void OnLeft(HWND hWnd) 539 | { 540 | // 方块左移 541 | if (1 == CanSqareLeft() && 1 == CanSqareLeft2()) 542 | { 543 | HDC hDc = GetDC(hWnd); 544 | SqareLeft(); 545 | g_iList--; 546 | // 显示方块 547 | OnPaint(hDc); 548 | 549 | ReleaseDC(hWnd,hDc); 550 | } 551 | } 552 | 553 | // 方块左移 554 | void SqareLeft() 555 | { 556 | int i = 0, 557 | j = 0; 558 | 559 | for (i = 0; i < 20; i++) 560 | { 561 | for (j = 0; j < 10; j++) 562 | { 563 | if (1 == g_arrBackGroud[i][j]) 564 | { 565 | g_arrBackGroud[i][j-1] = g_arrBackGroud[i][j]; 566 | g_arrBackGroud[i][j] = 0; 567 | } 568 | } 569 | } 570 | } 571 | 572 | // 方块是否能够左移,边界判断,0不可以左移,1可以左移 573 | int CanSqareLeft() 574 | { 575 | int i = 0; 576 | 577 | for (i = 0; i < 20; i++) 578 | { 579 | if (1 == g_arrBackGroud[i][0]) 580 | { 581 | return 0; 582 | } 583 | } 584 | return 1; 585 | } 586 | 587 | // 方块是否能够左移,边界左有方块情况判断,0不可以左移,1可以左移 588 | int CanSqareLeft2() 589 | { 590 | 591 | int i = 0, 592 | j = 0; 593 | 594 | for (i = 0; i < 20; i++) 595 | { 596 | for (j = 0; j < 10; j++) 597 | { 598 | if (1 == g_arrBackGroud[i][j]) 599 | { 600 | if (2 == g_arrBackGroud[i][j-1]) 601 | { 602 | return 0; 603 | } 604 | } 605 | } 606 | } 607 | 608 | return 1; 609 | } 610 | 611 | // 右移动消息 612 | void OnRight(HWND hWnd) 613 | { 614 | // 方块右块 615 | if (1 == CanSqareRight() && 1 == CanSqareRight2()) 616 | { 617 | HDC hDc = GetDC(hWnd); 618 | SqareRight(); 619 | g_iList++; 620 | // 显示方块 621 | OnPaint(hDc); 622 | 623 | ReleaseDC(hWnd,hDc); 624 | } 625 | } 626 | 627 | // 方块右移 628 | void SqareRight() 629 | { 630 | int i = 0, 631 | j = 0; 632 | 633 | for (i = 0; i < 20; i++) 634 | { 635 | for (j = 9; j >= 0; j--) 636 | { 637 | if (1 == g_arrBackGroud[i][j]) 638 | { 639 | g_arrBackGroud[i][j+1] = g_arrBackGroud[i][j]; 640 | g_arrBackGroud[i][j] = 0; 641 | } 642 | } 643 | } 644 | } 645 | 646 | // 方块是否能够右移,边界判断,0不可以左移,1可以左移 647 | int CanSqareRight() 648 | { 649 | int i = 0; 650 | 651 | for (i = 0; i < 20; i++) 652 | { 653 | if (1 == g_arrBackGroud[i][9]) 654 | { 655 | return 0; 656 | } 657 | } 658 | 659 | return 1; 660 | } 661 | 662 | // 方块是否能够右移,边界左有方块情况判断,0不可以左移,1可以左移 663 | int CanSqareRight2() 664 | { 665 | int i = 0, 666 | j = 0; 667 | 668 | for (i = 0; i < 20; i++) 669 | { 670 | for (j = 9; j >= 0; j--) 671 | { 672 | if (1 == g_arrBackGroud[i][j]) 673 | { 674 | if (2 == g_arrBackGroud[i][j+1]) 675 | { 676 | return 0; 677 | } 678 | } 679 | } 680 | } 681 | 682 | return 1; 683 | } 684 | 685 | // 向下加速消息 686 | void OnDown(HWND hWnd) 687 | { 688 | OnTime(hWnd); 689 | } 690 | 691 | // 向上变型 692 | void OnChangeSqare(HWND hWnd) 693 | { 694 | HDC hDc = GetDC(hWnd); 695 | 696 | switch (g_iSqareID) 697 | { 698 | case 0: 699 | case 1: 700 | case 3: 701 | case 2: 702 | case 4: 703 | // 一般形状 704 | // 一般形状方块能否变型条件判断 705 | if (1 == CanSqareChangeShape()) 706 | { 707 | ChangeSqare(); 708 | } 709 | else 710 | { 711 | return ; 712 | } 713 | break; 714 | case 5: 715 | // 正方形,不需要变型 716 | return ; 717 | case 6: 718 | // 长方形变型 719 | // 长方形方块能否变型条件判断,0不可以变型,1可以变型 720 | if (1 == CanLineSqareChangeShape()) 721 | { 722 | ChangeLineSqare(); 723 | } 724 | break; 725 | } 726 | 727 | // 显示 728 | OnPaint(hDc); 729 | // 释放DC 730 | ReleaseDC(hWnd,hDc); 731 | } 732 | 733 | // 一般形状变型 734 | void ChangeSqare() 735 | { 736 | int i = 0; 737 | int j = 0; 738 | int iTemp = 2; 739 | 740 | char arrSqare[3][3] = {0}; 741 | 742 | // 背景复制出来 743 | for (i = 0; i < 3; i++) 744 | { 745 | for (j = 0; j < 3; j++) 746 | { 747 | arrSqare[i][j] = g_arrBackGroud[g_iLine + i][g_iList + j]; 748 | } 749 | } 750 | 751 | // 变型后复制回去 752 | for (i = 0; i < 3; i++) 753 | { 754 | for (j = 0; j < 3; j++) 755 | { 756 | g_arrBackGroud[g_iLine + i][g_iList + j] = arrSqare[iTemp][i]; 757 | iTemp--; 758 | } 759 | iTemp = 2; 760 | } 761 | 762 | } 763 | 764 | // 一般形状方块能否变型条件判断 0不可以变型,1可以变型 765 | int CanSqareChangeShape() 766 | { 767 | int i = 0; 768 | int j = 0; 769 | 770 | // 背景复制出来 771 | for (i = 0; i < 3; i++) 772 | { 773 | for (j = 0; j < 3; j++) 774 | { 775 | if (2 == g_arrBackGroud[g_iLine + i][g_iList + j]) 776 | { 777 | return 0; 778 | } 779 | } 780 | } 781 | 782 | // 左右两边数组边界越界问题情况 783 | /*if (g_iList < 0 || g_iList > 9) 784 | { 785 | return 0; 786 | }*/ 787 | if (g_iList < 0) 788 | { 789 | g_iList = 0; 790 | } 791 | else if (g_iList + 2 > 9) 792 | { 793 | g_iList = 7; 794 | } 795 | 796 | return 1; 797 | } 798 | 799 | // 长方形变型 800 | void ChangeLineSqare() 801 | { 802 | if (1 == g_arrBackGroud[g_iLine][g_iList - 1])// 长方形是横着的 803 | { 804 | // 背景清零 805 | g_arrBackGroud[g_iLine][g_iList - 1] = 0; 806 | g_arrBackGroud[g_iLine][g_iList + 1] = 0; 807 | g_arrBackGroud[g_iLine][g_iList + 2] = 0; 808 | 809 | if (2 == g_arrBackGroud[g_iLine + 1][g_iList]) 810 | { 811 | // 复制数组 812 | g_arrBackGroud[g_iLine - 1][g_iList] = 1; 813 | g_arrBackGroud[g_iLine - 2][g_iList] = 1; 814 | g_arrBackGroud[g_iLine - 3][g_iList] = 1; 815 | 816 | } 817 | else if (2 == g_arrBackGroud[g_iLine + 2][g_iList]) 818 | { 819 | // 复制数组 820 | g_arrBackGroud[g_iLine + 1][g_iList] = 1; 821 | g_arrBackGroud[g_iLine - 1][g_iList] = 1; 822 | g_arrBackGroud[g_iLine - 2][g_iList] = 1; 823 | } 824 | else 825 | { 826 | // 元素复制 827 | g_arrBackGroud[g_iLine - 1][g_iList] = 1; 828 | g_arrBackGroud[g_iLine + 1][g_iList] = 1; 829 | g_arrBackGroud[g_iLine + 2][g_iList] = 1; 830 | } 831 | 832 | } 833 | else// 长方形是竖着的 834 | { 835 | // 背景清零 836 | g_arrBackGroud[g_iLine - 1][g_iList] = 0; 837 | g_arrBackGroud[g_iLine + 1][g_iList] = 0; 838 | g_arrBackGroud[g_iLine + 2][g_iList] = 0; 839 | 840 | if (2 == g_arrBackGroud[g_iLine][g_iList + 1] || 9 == g_iList) 841 | { 842 | // 元素复制 843 | g_arrBackGroud[g_iLine][g_iList - 1] = 1; 844 | g_arrBackGroud[g_iLine][g_iList - 2] = 1; 845 | g_arrBackGroud[g_iLine][g_iList - 3] = 1; 846 | // 中心点标记改变 847 | g_iList = g_iList - 2; 848 | // g_iList -= 2; 849 | } 850 | else if (2 == g_arrBackGroud[g_iLine][g_iList + 2] || 8 == g_iList) 851 | { 852 | // 元素复制 853 | g_arrBackGroud[g_iLine][g_iList + 1] = 1; 854 | g_arrBackGroud[g_iLine][g_iList - 1] = 1; 855 | g_arrBackGroud[g_iLine][g_iList - 2] = 1; 856 | // 中心点标记改变 857 | g_iList = g_iList - 1; 858 | // g_iList -= 1; 859 | } 860 | else if (2 == g_arrBackGroud[g_iLine][g_iList - 1] || 0 == g_iList) 861 | { 862 | // 元素复制 863 | g_arrBackGroud[g_iLine][g_iList + 1] = 1; 864 | g_arrBackGroud[g_iLine][g_iList + 2] = 1; 865 | g_arrBackGroud[g_iLine][g_iList + 3] = 1; 866 | // 中心点标记改变 867 | g_iList = g_iList + 1; 868 | // g_iList += 1; 869 | } 870 | else 871 | { 872 | // 元素复制 873 | g_arrBackGroud[g_iLine][g_iList - 1] = 1; 874 | g_arrBackGroud[g_iLine][g_iList + 1] = 1; 875 | g_arrBackGroud[g_iLine][g_iList + 2] = 1; 876 | } 877 | } 878 | } 879 | 880 | // 长方形方块能否变型条件判断,0不可以变型,1可以变型 881 | int CanLineSqareChangeShape() 882 | { 883 | int i = 0; 884 | int j = 0; 885 | 886 | for (i = 1; i < 4; i++) 887 | { 888 | if (2 == g_arrBackGroud[g_iLine][g_iList + i] || g_iList + i > 9) 889 | { 890 | break; 891 | } 892 | } 893 | for (j = 1; j < 4; j++) 894 | { 895 | if (2 == g_arrBackGroud[g_iLine][g_iList - j] || g_iList - j < 0) 896 | { 897 | break; 898 | } 899 | } 900 | 901 | if ((i-1 + j-1) < 3) 902 | { 903 | return 0; 904 | } 905 | 906 | return 1; 907 | } 908 | 909 | // 消除方块 910 | void DestroyOneLineSqare() 911 | { 912 | int i = 0, 913 | j = 0; 914 | int iSum = 0; 915 | int iTampi = 0; 916 | 917 | for (i = 19; i >= 0; i--) 918 | { 919 | for (j = 0; j < 10; j++) 920 | { 921 | iSum += g_arrBackGroud[i][j]; 922 | } 923 | 924 | if (20 == iSum) 925 | { 926 | // 消除一行 927 | for (iTampi = i - 1; iTampi >= 0; iTampi--) 928 | { 929 | for (j = 0; j < 10; j++) 930 | { 931 | g_arrBackGroud[iTampi + 1][j] = g_arrBackGroud[iTampi][j]; 932 | } 933 | 934 | } 935 | // 消除一行积分 10 936 | g_iScore += 10; 937 | //g_iScore ++; 938 | // 解决同时多行消除情况 939 | i = 20; 940 | } 941 | 942 | iSum = 0; 943 | } 944 | } 945 | 946 | // 显示积分 947 | void ShowScore(HDC hMemDC) 948 | { 949 | // 字符数组 最高积分 950 | char strScore[10] = {0}; 951 | char strTopScore[10] = {0}; 952 | 953 | Rectangle(hMemDC, 300, 0, 500, 600); 954 | 955 | // 积分显示 956 | itoa(g_iScore, strScore, 10); 957 | TextOut(hMemDC, 350, 60, "总积分:", strlen("总积分:")); 958 | TextOut(hMemDC, 400, 80, strScore, strlen(strScore)); 959 | 960 | // 显示提示信息 961 | itoa(200000, strTopScore, 10); 962 | TextOut(hMemDC, 350, 130, "最高积分:", strlen("最高积分:")); 963 | TextOut(hMemDC, 400, 150, strTopScore, strlen(strTopScore)); 964 | 965 | TextOut(hMemDC, 350, 200, "开始键:Enter", strlen("开始键:Enter")); 966 | TextOut(hMemDC, 330, 250, "方向键↑:方块变型", strlen("方向键↑:方块变型")); 967 | TextOut(hMemDC, 330, 300, "方向键↓:方块加速", strlen("方向键↑:方块变型")); 968 | TextOut(hMemDC, 330, 350, "方向键←:方块左移", strlen("方向键↑:方块变型")); 969 | TextOut(hMemDC, 330, 400, "方向键→:方块右移", strlen("方向键↑:方块变型")); 970 | 971 | } 972 | 973 | // TODO 游戏结束失败 974 | int CanGameOver() 975 | { 976 | int i = 0; 977 | for (i = 0; i < 10; i++) 978 | { 979 | if (2 == g_arrBackGroud[0][i]) 980 | { 981 | // 游戏结束 982 | MessageBox(NULL, "很遗憾,游戏失败了,再接再厉吧!", "提示", MB_OK);//MB_YESNO 983 | return 0; 984 | } 985 | if (200000 == g_iScore) 986 | { 987 | // 游戏获胜 988 | MessageBox(NULL, "恭喜你,通关了,消除了2万行方块!", "提示", MB_OK);//MB_YESNO 989 | return 0; 990 | } 991 | } 992 | 993 | return 1; 994 | } 995 | -------------------------------------------------------------------------------- /俄罗斯方块/music.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2793134925/C-LanguageProjectCombat/12c3ede031ba53d1a9694cd4c42b04a0dbd9ac9d/俄罗斯方块/music.mp3 -------------------------------------------------------------------------------- /学生管理系统/版本1/README.md: -------------------------------------------------------------------------------- 1 | ##### 高校学生信息管理系统 2 | 3 | /* 设计高校学生管理系统 4 | * 1、实现功能: 5 | * 1.1、录入(添加)学生信息:学号、姓名、平时成绩和考试成绩,总评成绩。 6 | * 1.2、查询学生成绩:输入要查询的学生的学号,查询该学生的信息并显示。 7 | * 1.3、显示学生成绩单:按学号顺序显示学生成绩单。 8 | * 1.4、删除学生信息:输入要删除的学生的学号,,删除该学生的信息。 9 | * 1,5、修改学生信息:输入要修改的学生的学号,显示该学生的原有信息, 10 | * 用户输入修改后*的信息。 11 | */ 12 | 13 | /* CollegeStudentManagementSystem.cpp: 14 | * 1功能:高校学生信息管理系统 15 | * 2著者:云主宰苍穹——黎为 16 | * 3版本:V1.0.0 17 | * 4编写语言:C语言 18 | */ 19 | 20 | ##### 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 21 | ##### 字符集:UTF-8 22 | 23 | 24 | ##### 知识点 25 | 1)C语言的量声明和定义,以及变量初始化和生命周期与可见性 26 | 2)C语言指针的定义,初始化 27 | 3)C语言内存的申请和释放 28 | 4)C语言循环结构、选择结构、分支结构 29 | 5)C语言结构体 30 | 6)C语言数据结构之链表 31 | 7)C语言函数声明、实现、调用 32 | 8)C语言函数的参数、返回值 33 | 9)C语言文件打开、操作(读写)、关闭 34 | -------------------------------------------------------------------------------- /学生管理系统/版本1/README.txt: -------------------------------------------------------------------------------- 1 | /* 设计高校学生管理系统 2 | * 1、实现功能: 3 | * 1.1、录入(添加)学生信息:学号、姓名、平时成绩和考试成绩,总评成绩。 4 | * 1.2、查询学生成绩:输入要查询的学生的学号,查询该学生的信息并显示。 5 | * 1.3、显示学生成绩单:按学号顺序显示学生成绩单。 6 | * 1.4、删除学生信息:输入要删除的学生的学号,,删除该学生的信息。 7 | * 1,5、修改学生信息:输入要修改的学生的学号,显示该学生的原有信息, 8 | * 用户输入修改后*的信息。 9 | */ 10 | 11 | /* CollegeStudentManagementSystem.cpp: 12 | * 1功能:高校学生信息管理系统 13 | * 2著者:云主宰苍穹——黎为 14 | * 3版本:V1.0.0 15 | * 4编写语言:C语言 16 | */ 17 | 18 | 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 19 | 字符集:UTF-8 20 | 21 | 22 | 知识点 23 | 1)C语言的量声明和定义,以及变量初始化和生命周期与可见性 24 | 2)C语言指针的定义,初始化 25 | 3)C语言内存的申请和释放 26 | 4)C语言循环结构、选择结构、分支结构 27 | 5)C语言结构体 28 | 6)C语言数据结构之链表 29 | 7)C语言函数声明、实现、调用 30 | 8)C语言函数的参数、返回值 31 | 9)C语言文件打开、操作(读写)、关闭 -------------------------------------------------------------------------------- /学生管理系统/版本1/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.c 4 | * Author 黎为 5 | * Description 主函数作为程序的入口 6 | * Version V1.0.0 7 | */ 8 | 9 | /* 设计高校学生管理系统 10 | * 1、实现功能: 11 | * 1.1、录入(添加)学生信息:学号、姓名、平时成绩和考试成绩,总评成绩。 12 | * 1.2、查询学生成绩:输入要查询的学生的学号,查询该学生的信息并显示。 13 | * 1.3、显示学生成绩单:按学号顺序显示学生成绩单。 14 | * 1.4、删除学生信息:输入要删除的学生的学号,,删除该学生的信息。 15 | * 1,5、修改学生信息:输入要修改的学生的学号,显示该学生的原有信息, 16 | 用户输入修改后*的信息。 17 | * 2、业务流程 18 | * 3、实现代码 19 | */ 20 | 21 | /* CollegeStudentManagementSystem.cpp: 22 | * 1功能:高校学生信息管理系统 23 | * 2著者:云主宰苍穹——黎为 24 | * 3版本:V1.0.0 25 | * 4编写语言:C语言 26 | */ 27 | 28 | //宏定义区 29 | #define _CRT_SECURE_NO_DEPRECATE 30 | 31 | //头文件区 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | //全局变量区 39 | //学生结构体 40 | typedef struct tagStudent 41 | { 42 | char Num[10];//学号 43 | char Name[20];//姓名 44 | double Regular_Score;//平时成绩 45 | double Final_Score;//期末成绩 46 | double Total_Score;//总评成绩 47 | }Student; 48 | 49 | //学生链表结点 50 | typedef struct tagNode 51 | { 52 | Student Stu;//数据域:学生信息 53 | struct tagNode *pNext;//指针域:指向下一个学生结点 54 | }Node; 55 | 56 | //定义链表的第一个学生,即学生单链表的头结点 57 | Node *g_pHead = NULL; 58 | 59 | //全局函数定义区 60 | // 打印功能菜单 61 | void Print_Menu(); 62 | //1录入学生信息 63 | void Enter_Students(); 64 | //2查询学生信息 65 | Node* Inquire_Students(); 66 | //3显示学生信息 67 | void Display_Students(); 68 | //4删除学生信息 69 | void Deleting_Students(); 70 | //5修改学生信息 71 | void Amend_Students(); 72 | 73 | //程序的主函数——程序入口 74 | int main(int argc, char *argv[]) 75 | { 76 | while (1)//死循环 77 | { 78 | //清屏 79 | system("CLS"); 80 | 81 | //打印功能菜单 82 | Print_Menu(); 83 | 84 | char ch; 85 | //控制台无回显获取信息 86 | ch = _getch(); 87 | 88 | //switch分支选择结构 89 | switch (ch) 90 | { 91 | case'1': //1录入学生信息 92 | Enter_Students(); 93 | break; 94 | 95 | case'2': //2查询学生信息 96 | { 97 | Node *pNode = Inquire_Students(); 98 | if (pNode != NULL) 99 | { 100 | printf("%s\t %s\t %0.2lf \t%0.2lf \t%0.2lf\t\n", 101 | pNode->Stu.Num, //学号 102 | pNode->Stu.Name, //姓名 103 | pNode->Stu.Regular_Score,//平时成绩 104 | pNode->Stu.Final_Score, //期末成绩 105 | pNode->Stu.Total_Score); //总评成绩 106 | } 107 | else 108 | { 109 | printf("未找到学生信息,请确认学生信息!\n"); 110 | } 111 | break; 112 | } 113 | 114 | case'3': //3显示学生信息 115 | Display_Students(); 116 | break; 117 | 118 | case'4': //4删除学生信息 119 | Deleting_Students(); 120 | break; 121 | 122 | case'5': //5修改学生信息 123 | Amend_Students(); 124 | break; 125 | 126 | case'0': //退出程序系统 127 | printf("欢迎再次使用!\n"); 128 | return 0; 129 | break; 130 | 131 | default: //程序的健壮性,友好提示 132 | printf("您输入的选择有错误,请重新选择功能!\n"); 133 | break; 134 | } 135 | system("PAUSE"); 136 | } 137 | return 0; 138 | } 139 | 140 | //全局函数实现区 141 | // 打印功能菜单 142 | void Print_Menu() 143 | { 144 | //清屏 145 | system("CLS"); 146 | printf("=================================================\n"); 147 | printf("===============欢迎使用高校学生管理系统==========\n"); 148 | printf("=================================================\n"); 149 | printf("===================请选择对应功能================\n"); 150 | printf("=================================================\n"); 151 | printf("=\t\t1、录入学生信息\t\t\t=\n"); 152 | printf("=\t\t2、查询学生信息\t\t\t=\n"); 153 | printf("=\t\t3、显示学生信息\t\t\t=\n"); 154 | printf("=\t\t4、删除学生信息\t\t\t=\n"); 155 | printf("=\t\t5、修改学生信息\t\t\t=\n"); 156 | printf("=\t\t0、退出程序系统\t\t\t=\n"); 157 | printf("=================================================\n"); 158 | 159 | return; 160 | } 161 | 162 | //1录入学生信息 163 | void Enter_Students() 164 | { 165 | //清屏 166 | system("CLS"); 167 | printf("=================================================\n"); 168 | printf("===============欢迎使用高校学生管理系统==========\n"); 169 | printf("=================================================\n"); 170 | printf("===================录入学生信息功能================\n"); 171 | printf("=================================================\n"); 172 | printf("\n请依次输入学生信息:\n\n|学号 \t|姓名 |平时成绩| |期末成绩| |总评成绩|\n"); 173 | 174 | //定义单链表的一个结点:当前结点 175 | Node *p; 176 | 177 | //将头结点给当前结点 178 | p = g_pHead; 179 | 180 | //在插入新结点前找到尾结点, 181 | while (g_pHead != NULL && p->pNext != NULL) 182 | { 183 | p = p->pNext; 184 | } 185 | 186 | //为新的学生元素分配一个空间 187 | //mallac void* 泛类型 强制类型转换 188 | Node* pNewNode = (Node*)malloc(sizeof(Node)); 189 | pNewNode->pNext = NULL; 190 | 191 | //将新节点插入尾结点或者作为头结点 192 | if (g_pHead == NULL) 193 | { 194 | g_pHead = pNewNode; 195 | p = g_pHead; 196 | } 197 | else 198 | { 199 | //p的下一个节点为pNewNode 200 | p->pNext = pNewNode; 201 | } 202 | 203 | //输入新的学生数据信息 204 | scanf("%s %s %lf %lf %lf", pNewNode->Stu.Num, //学号 数组名就是数组首地址 205 | pNewNode->Stu.Name, //姓名 206 | &pNewNode->Stu.Regular_Score, //平时成绩 207 | &pNewNode->Stu.Final_Score, //期末成绩 208 | &pNewNode->Stu.Total_Score); //总评成绩 209 | 210 | printf("\n学生信息录入系统成功!\n"); 211 | 212 | return; 213 | } 214 | 215 | //2查询学生信息 216 | Node *Inquire_Students() 217 | { 218 | //清屏 219 | system("CLS"); 220 | printf("=================================================\n"); 221 | printf("===============欢迎使用高校学生管理系统==========\n"); 222 | printf("=================================================\n"); 223 | printf("===================查询学生信息功能================\n"); 224 | printf("=================================================\n"); 225 | char Num[10]; //学号 226 | 227 | printf("\n请输入需要查询学生的学号:\n"); 228 | 229 | scanf("%s",Num); 230 | 231 | Node *p = g_pHead; 232 | printf("\n学号\t姓名\t平时成绩\t期末成绩\t总评成绩\t\n"); 233 | 234 | //遍历链表 235 | while (p != NULL) 236 | { 237 | /*if (p->Stu.Num == Num) 字符数组不能比较 238 | 需要字符比较 调用函数stricmp 以大小写不敏感方式比较两个串 239 | 用法:int stricmp( char *str1, char *str2); 240 | 返回值大于0,则str1>str2 241 | 返回值小于0,则str1Stu.Num , Num); 244 | //如果找到学生信息 245 | if (ptr == 0) 246 | { 247 | return p; 248 | } 249 | //否则继续找,直到遍历完链表退出while 250 | p = p->pNext; 251 | } 252 | 253 | //遍历完没有找到学生信息 254 | if (p == NULL) 255 | { 256 | return NULL; 257 | } 258 | 259 | return NULL; 260 | } 261 | 262 | //3显示学生信息 263 | void Display_Students() 264 | { 265 | //清屏 266 | system("CLS"); 267 | printf("=================================================\n"); 268 | printf("===============欢迎使用高校学生管理系统==========\n"); 269 | printf("=================================================\n"); 270 | printf("===================显示学生信息功能================\n"); 271 | printf("=================================================\n"); 272 | 273 | Node *p = g_pHead; 274 | printf("学号\t| 姓名\t| 平时成绩\t| 期末成绩\t| 总评成绩\t|\n"); 275 | 276 | //如果链表里没有学生信息 277 | if (p == NULL) 278 | { 279 | printf("未找到学生信息,请先录入学生信息!\n\n"); 280 | return; 281 | } 282 | 283 | //如果链表里有学生信息,则遍历链表 284 | while (p != NULL) 285 | { 286 | printf("%s\t| %s\t| %0.2lf \t| %0.2lf \t| %0.2lf\t|\n", 287 | p->Stu.Num, //学号 288 | p->Stu.Name, //姓名 289 | p->Stu.Regular_Score, //平时成绩 290 | p->Stu.Final_Score, //期末成绩 291 | p->Stu.Total_Score); //总评成绩); 292 | 293 | p = p->pNext; 294 | } 295 | printf("=================================================\n"); 296 | return; 297 | } 298 | 299 | //4删除学生信息 300 | void Deleting_Students() 301 | { 302 | //清屏 303 | system("CLS"); 304 | printf("=================================================\n"); 305 | printf("===============欢迎使用高校学生管理系统==========\n"); 306 | printf("=================================================\n"); 307 | printf("===================删除学生信息功能================\n"); 308 | printf("=================================================\n"); 309 | char Num[10]; //学号 310 | 311 | printf("\n请输入需要删除学生的学号:\n"); 312 | 313 | scanf("%s", Num); 314 | 315 | Node *p = g_pHead; 316 | 317 | //定义一个临时变量结点 318 | Node *p2 = NULL; 319 | 320 | //如果要删除的学生信息是链表的头结点 321 | int ptr = _stricmp(g_pHead->Stu.Num , Num); 322 | if (ptr == 0) 323 | { 324 | p2 = g_pHead; 325 | g_pHead = g_pHead->pNext; 326 | //释放内存,删除信息 327 | free(p2); 328 | printf("删除学生信息成功!"); 329 | return; 330 | } 331 | 332 | //删除的学生信息不是头结点 333 | while (p->pNext != NULL) 334 | { 335 | int ptr = _stricmp(p->pNext->Stu.Num, Num); 336 | if (ptr == 0) 337 | { 338 | p2 = p->pNext; 339 | p->pNext = p->pNext->pNext; 340 | //释放内存,删除信息 341 | free(p2); 342 | printf("删除学生信息成功!"); 343 | return; 344 | } 345 | if (ptr != 0) 346 | { 347 | printf("学生信息不正确,请确认学生信息!"); 348 | } 349 | //遍历链表 350 | p = p->pNext; 351 | } 352 | //遍历完没有找到学生信息 353 | if (p == NULL) 354 | { 355 | printf("未找到学生信息,请确认学生信息!\n\n"); 356 | } 357 | return; 358 | } 359 | 360 | //5修改学生信息 361 | void Amend_Students() 362 | { 363 | //清屏 364 | system("CLS"); 365 | printf("=================================================\n"); 366 | printf("===============欢迎使用高校学生管理系统==========\n"); 367 | printf("=================================================\n"); 368 | printf("===================修改学生信息功能================\n"); 369 | printf("=================================================\n"); 370 | 371 | char Num[10]; //学号 372 | 373 | printf("\n请输入需要修改学生的学号:"); 374 | 375 | scanf("%s", Num); 376 | 377 | Node *p = g_pHead; 378 | 379 | //遍历链表 380 | while (p != NULL) 381 | { 382 | int ptr = _stricmp(p->Stu.Num, Num); 383 | if (ptr == 0) 384 | { 385 | //显示要修改学生信息 386 | printf("=================================================\n"); 387 | printf("%s\t| %s\t| %0.2lf \t| %0.2lf \t| %0.2lf\t|\n", 388 | p->Stu.Num, //学号 389 | p->Stu.Name, //姓名 390 | p->Stu.Regular_Score, //平时成绩 391 | p->Stu.Final_Score, //期末成绩 392 | p->Stu.Total_Score); //总评成绩); 393 | printf("=================================================\n"); 394 | printf("请修改学生信息\n\n"); 395 | printf("学号\t姓名\t平时成绩\t期末成绩\t总评成绩\t\n"); 396 | scanf("%s %s %lf %lf %lf", 397 | p->Stu.Num, //学号 398 | p->Stu.Name, //姓名 399 | &p->Stu.Regular_Score, //平时成绩 400 | &p->Stu.Final_Score, //期末成绩 401 | &p->Stu.Total_Score); //总评成绩 402 | printf("修改学生信息成功!\n"); 403 | break; 404 | } 405 | //遍历链表 406 | p = p->pNext; 407 | } 408 | //遍历完没有找到学生信息 409 | if (p == NULL) 410 | { 411 | printf("未找到学生信息,请确认学生信息!\n\n"); 412 | } 413 | return; 414 | } 415 | -------------------------------------------------------------------------------- /学生管理系统/版本1/the C of StudentInfoManagement.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2793134925/C-LanguageProjectCombat/12c3ede031ba53d1a9694cd4c42b04a0dbd9ac9d/学生管理系统/版本1/the C of StudentInfoManagement.exe -------------------------------------------------------------------------------- /学生管理系统/版本2/README.md: -------------------------------------------------------------------------------- 1 | 2 | #### 学生信息管理系统 3 | 4 | /*学生信息管理系统 5 | 本系统的操作指令如下 6 | 1、 增加学生的信息(尾结点法) 7 | 11、 增加学生的信息(头结点法) 8 | 111、 在指定位置增加学生的信息 9 | 2、 查找指定学生的信息(学号) 10 | 3、 修改指定学生的信息 11 | 4、 保存学生的信息到文件 12 | 5、 读取文件中的学生信息 13 | 6、 删除指定学生的信息 14 | 7、 恢复删除的学生的信息 15 | 8、 显示所有学生的信息 16 | 9、 查看系统所有指令 17 | 0、 退出学生管理系统 18 | */ 19 | 20 | 21 | #### 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 22 | 23 | #### 字符集:UTF-8 24 | 25 | 26 | #### 知识点 27 | 1)C语言的量声明和定义,以及变量初始化和生命周期与可见性 28 | 2)C语言指针的定义,初始化 29 | 3)C语言内存的申请和释放 30 | 4)C语言循环结构、选择结构、分支结构 31 | 5)C语言结构体 32 | 6)C语言数据结构之链表 33 | 7)C语言函数声明、实现、调用 34 | 8)C语言函数的参数、返回值 35 | 9)C语言文件打开、操作(读写)、关闭 36 | 37 | #### 链表 38 | 头结点法创建链表 39 | 尾节点法创建链表 40 | 指定位置插入节点 41 | 释放链表内存资源 42 | -------------------------------------------------------------------------------- /学生管理系统/版本2/README.txt: -------------------------------------------------------------------------------- 1 | /*学生信息管理系统 2 | 本系统的操作指令如下 3 | 1、 增加学生的信息(尾结点法) 4 | 11、 增加学生的信息(头结点法) 5 | 111、 在指定位置增加学生的信息 6 | 2、 查找指定学生的信息(学号) 7 | 3、 修改指定学生的信息 8 | 4、 保存学生的信息到文件 9 | 5、 读取文件中的学生信息 10 | 6、 删除指定学生的信息 11 | 7、 恢复删除的学生的信息 12 | 8、 显示所有学生的信息 13 | 9、 查看系统所有指令 14 | 0、 退出学生管理系统 15 | */ 16 | 17 | 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 18 | 字符集:UTF-8 19 | 20 | 知识点 21 | 1)C语言的量声明和定义,以及变量初始化和生命周期与可见性 22 | 2)C语言指针的定义,初始化 23 | 3)C语言内存的申请和释放 24 | 4)C语言循环结构、选择结构、分支结构 25 | 5)C语言结构体 26 | 6)C语言数据结构之链表 27 | 7)C语言函数声明、实现、调用 28 | 8)C语言函数的参数、返回值 29 | 9)C语言文件打开、操作(读写)、关闭 30 | 31 | 链表 32 | 头结点法创建链表 33 | 尾节点法创建链表 34 | 指定位置插入节点 35 | 释放链表内存资源 -------------------------------------------------------------------------------- /学生管理系统/版本2/StuInfoSys.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2793134925/C-LanguageProjectCombat/12c3ede031ba53d1a9694cd4c42b04a0dbd9ac9d/学生管理系统/版本2/StuInfoSys.exe -------------------------------------------------------------------------------- /学生管理系统/版本2/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.c 4 | * Author 黎为 5 | * Description 主函数作为程序的入口 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | //#include "main.h" 12 | 13 | // 学生节点 14 | typedef struct _STU 15 | { 16 | char arrStuNum[10]; 17 | char arrStuName[10]; 18 | int iStuScore; 19 | struct _STU *pNext; 20 | }STUNODE; 21 | // 声明链表的头和尾 22 | STUNODE *g_pHead = NULL; 23 | STUNODE *g_pEnd = NULL; 24 | 25 | // TODO 添加学生信息 26 | void AddStuMSG(char *arrStuNum, char *arrStuName, int iStuScore); 27 | 28 | // 清空链表 29 | void FreeLinkData(); 30 | 31 | // 打印数据 32 | void ShowStuData(); 33 | 34 | // 查看显示指令 35 | void ShowOrder(); 36 | 37 | // 在链表头添加一个节点 38 | void AddStuMSGToLinkHead(char *arrStuNum, char *arrStuName, int iStuScore); 39 | 40 | // 查找指定学生 41 | STUNODE *FindStuByNum(char *arrStuNum); 42 | 43 | // 指定位置插入节点 44 | void InsertNode(STUNODE *pTemp,char *arrStuNum, char *arrStuName, int iStuScore); 45 | 46 | // 删除指定节点 47 | void DeleteStuNode(STUNODE *pNode); 48 | 49 | // 保存信息到文件 50 | void SaveStuToFile(); 51 | 52 | // 读取文件中的学生信息 53 | void ReadStuFromFile(); 54 | 55 | 56 | int main(int argc, char *argv[]) 57 | { 58 | int iOrder = -1; 59 | int iFlag = 1; 60 | char arrStuNum[10] = {"\0"}; 61 | char arrStuName[10] = {"\0"}; 62 | int iStuScore = 0; 63 | STUNODE *pTemp = NULL;//labe case 111 64 | 65 | // TODO 查看系统指令 66 | ShowOrder(); 67 | 68 | // 读取文件中的学生信息 69 | ReadStuFromFile(); 70 | 71 | while(iFlag) 72 | { 73 | //printf("Enter the Order(【9】查看系统所有指令):"); 74 | printf("请输入指令(【9】查看系统所有指令):"); 75 | scanf("%d",&iOrder); 76 | switch (iOrder) 77 | { 78 | case 1: 79 | // TODO 添加学生信息 80 | //printf("Enter the student number:"); 81 | printf("请输入学生的学号:"); 82 | scanf("%s",arrStuNum); 83 | printf("请输入学生的姓名:"); 84 | scanf("%s",arrStuName); 85 | printf("请输入学生的总学分:"); 86 | scanf("%d",&iStuScore); 87 | 88 | AddStuMSG(arrStuNum, arrStuName, iStuScore); 89 | break; 90 | case 11: 91 | // TODO 头添加法 92 | /*printf("Enter the student information:\n"); 93 | scanf("学号:%s,姓名:%s,学分:%d",arrStuNum,arrStuName,&iStuScore);*/ 94 | printf("请输入学生的学号:"); 95 | scanf("%s",arrStuNum); 96 | printf("请输入学生的姓名:"); 97 | scanf("%s",arrStuName); 98 | printf("请输入学生的总学分:"); 99 | scanf("%d",&iStuScore); 100 | AddStuMSGToLinkHead(arrStuNum, arrStuName, iStuScore); 101 | break; 102 | case 111: 103 | //TODO 在指定位置节点的后面增加学生的信息 104 | printf("请输入指定学生学号:"); 105 | scanf("%s",arrStuNum); 106 | pTemp = FindStuByNum(arrStuNum); 107 | if (NULL != pTemp) 108 | { 109 | // TODO 插入 110 | printf("请输入学生的学号:"); 111 | scanf("%s",arrStuNum); 112 | printf("请输入学生的姓名:"); 113 | scanf("%s",arrStuName); 114 | printf("请输入学生的总学分:"); 115 | scanf("%d",&iStuScore); 116 | 117 | InsertNode(pTemp,arrStuNum,arrStuName,iStuScore); 118 | } 119 | break; 120 | case 2: 121 | // TODO 查找指定学生的信息 122 | printf("请输入指定学生学号:"); 123 | scanf("%s",arrStuNum); 124 | // 查找 125 | pTemp = FindStuByNum(arrStuNum); 126 | // 打印 127 | if (NULL != pTemp) 128 | { 129 | printf("学号:%s,姓名:%s,学分:%d\n",pTemp->arrStuNum,pTemp->arrStuName,pTemp->iStuScore); 130 | } 131 | break; 132 | case 3: 133 | // TODO 修改指定学生的信息 134 | printf("请输入指定学生学号:"); 135 | scanf("%s",arrStuNum); 136 | pTemp = FindStuByNum(arrStuNum); 137 | // 修改 138 | if (NULL != pTemp) 139 | { 140 | // TODO 智能提示是否需要修改 141 | 142 | // 修改学号 143 | printf("请输入新的学号"); 144 | scanf("%s",arrStuNum); 145 | strcpy(pTemp->arrStuNum,arrStuNum); 146 | 147 | // 修改姓名 148 | printf("请输入新的姓名"); 149 | scanf("%s",arrStuName); 150 | strcpy(pTemp->arrStuName,arrStuName); 151 | 152 | // 修改学分 153 | printf("请输入新的学分"); 154 | scanf("%d",&iStuScore); 155 | pTemp->iStuScore = iStuScore; 156 | } 157 | break; 158 | case 4: 159 | // TODO 保存学生的信息到文件 160 | SaveStuToFile(); 161 | break; 162 | case 5: 163 | // TODO 读取文件中的学生信息 164 | ReadStuFromFile(); 165 | break; 166 | case 6: 167 | // TODO 删除指定学生的信息 168 | printf("请输入指定学生学号:"); 169 | scanf("%s",arrStuNum); 170 | pTemp = FindStuByNum(arrStuNum); 171 | // 删除 172 | if (NULL != pTemp) 173 | { 174 | // TODO 调用删除节点函数 175 | DeleteStuNode(pTemp); 176 | } 177 | break; 178 | case 7: 179 | // TODO 恢复删除的学生的信息 180 | // TODO 恢复删除的学生的信息 181 | /* 第一种方法:在内存中保存删除之前备份保存上一个链表,占据内存资源大,读取速度快 182 | 第二种方法:在文件中备份每一次删除的链表,读取速度慢 183 | 第三种方法:在文件中进行一次备份,恢复到数据最初状态 */ 184 | // 释放链表 185 | FreeLinkData(); 186 | g_pHead = NULL; 187 | g_pEnd = NULL; 188 | // 添加节点 189 | ReadStuFromFile(); 190 | printf("学生信息已经恢复到最初状态!\n"); 191 | break; 192 | case 8: 193 | // TODO 显示所有学生的信息 194 | ShowStuData(); 195 | break; 196 | case 9: 197 | // TODO 查看系统指令 198 | ShowOrder(); 199 | break; 200 | case 0: 201 | // TODO 退出学生管理系统 202 | iFlag = 0; 203 | break; 204 | default: 205 | printf("Please Enter the Right Order[0-8]!\n"); 206 | break; 207 | } 208 | } 209 | 210 | // 保存信息到文件 211 | SaveStuToFile(); 212 | // 清空链表 213 | FreeLinkData(); 214 | 215 | system("pause"); 216 | return 0; 217 | } 218 | 219 | 220 | // TODO 添加学生信息 【尾添加法】 221 | void AddStuMSG(char *arrStuNum, char *arrStuName, int iStuScore) 222 | { 223 | // 第一步,检验参数的合法性 224 | if(NULL == arrStuName || NULL == arrStuNum || iStuScore < 0) 225 | { 226 | printf("学生录入的信息出错!\n"); 227 | return ; 228 | } 229 | 230 | // 第二步,处理业务逻辑 231 | // 创建新节点 232 | STUNODE *pTemp = malloc (sizeof (STUNODE)); 233 | // 节点成员符初始值 234 | strcpy(pTemp->arrStuNum,arrStuNum); 235 | strcpy(pTemp->arrStuName,arrStuName); 236 | pTemp->iStuScore = iStuScore; 237 | pTemp->pNext = NULL; 238 | 239 | // 连接节点成为链 240 | if(NULL == g_pEnd || NULL == g_pHead) 241 | { 242 | g_pHead = pTemp; 243 | // g_pEnd = pTemp; 244 | } 245 | else 246 | { 247 | g_pEnd->pNext = pTemp; 248 | // g_pEnd = pTemp; 249 | } 250 | g_pEnd = pTemp; 251 | } 252 | 253 | // 清空链表 254 | void FreeLinkData() 255 | { 256 | STUNODE *pTemp = g_pHead; 257 | 258 | while(g_pHead != NULL) 259 | { 260 | // 保存需要删除的节点 261 | pTemp = g_pHead; 262 | // 头结点指针指向下一个节点 263 | g_pHead->pNext = g_pHead; 264 | // 释放节点内存资源 265 | free(pTemp); 266 | } 267 | } 268 | 269 | // 打印数据 270 | void ShowStuData() 271 | { 272 | STUNODE *pTemp = g_pHead; 273 | // pTemp->pNext = NULL; 274 | 275 | while (pTemp != NULL) 276 | { 277 | printf ("学号:%s, 姓名:%s, 学分:%d\n",pTemp->arrStuNum,pTemp->arrStuName,pTemp->iStuScore); 278 | // 向下移动节点 279 | pTemp = pTemp->pNext; 280 | } 281 | } 282 | 283 | // 查看显示指令 284 | void ShowOrder() 285 | { 286 | printf("******************学生信息管理系统******************\n"); 287 | printf("****************本系统的操作指令如下****************\n"); 288 | printf("*** 1、 增加学生的信息(尾结点法) ***\n"); 289 | printf("*** 11、 增加学生的信息(头结点法) ***\n"); 290 | printf("*** 111、 在指定位置增加学生的信息 ***\n"); 291 | printf("*** 2、 查找指定学生的信息(学号) ***\n"); 292 | printf("*** 3、 修改指定学生的信息 ***\n"); 293 | printf("*** 4、 保存学生的信息到文件 ***\n"); 294 | printf("*** 5、 读取文件中的学生信息 ***\n"); 295 | printf("*** 6、 删除指定学生的信息 ***\n"); 296 | printf("*** 7、 恢复删除的学生的信息 ***\n"); 297 | printf("*** 8、 显示所有学生的信息 ***\n"); 298 | printf("*** 9、 查看系统所有指令 ***\n"); 299 | printf("*** 0、 退出学生管理系统 ***\n"); 300 | printf("****************************************************\n"); 301 | } 302 | 303 | // 在链表头添加一个节点,【头添加法】 304 | void AddStuMSGToLinkHead(char *arrStuNum, char *arrStuName, int iStuScore) 305 | { 306 | // 第一步,检验参数的合法性 307 | if(NULL == arrStuName || NULL == arrStuNum || iStuScore < 0) 308 | { 309 | printf("学生录入的信息出错!\n"); 310 | return ; 311 | } 312 | 313 | // 创建一个节点 314 | STUNODE *pTemp = malloc (sizeof (STUNODE)); 315 | // 节点成员符初始值 316 | strcpy(pTemp->arrStuNum,arrStuNum); 317 | strcpy(pTemp->arrStuName,arrStuName); 318 | pTemp->iStuScore = iStuScore; 319 | pTemp->pNext = NULL; 320 | 321 | // 链表为空 322 | if (NULL == g_pHead || NULL == g_pEnd) 323 | { 324 | g_pHead = pTemp; 325 | // g_pEnd = pTemp; 326 | } 327 | else 328 | { 329 | // 新节点的下一个节点 指向头结点 330 | pTemp->pNext = g_pHead; 331 | // 头结点向前移动 332 | // g_pHead = pTemp; 333 | } 334 | g_pHead = pTemp; 335 | } 336 | 337 | // 查找指定学生 338 | STUNODE *FindStuByNum(char *arrStuNum) 339 | { 340 | // 检测参数合法性 341 | if (NULL == arrStuNum)//赋值语句和相等判断,最佳写法 342 | { 343 | printf("学号输入错误!\n"); 344 | return NULL; 345 | } 346 | 347 | // 判断链表是否为空 348 | if (NULL == g_pHead || NULL == g_pEnd) 349 | { 350 | printf("当前链表为空[NULL]!\n"); 351 | return NULL; 352 | } 353 | //遍历链表 354 | STUNODE *pTemp = g_pHead; 355 | while(pTemp != NULL) 356 | { 357 | if (0 == strcmp(pTemp->arrStuNum,arrStuNum)) 358 | { 359 | return pTemp; 360 | } 361 | // 向下移动节点 362 | pTemp = pTemp->pNext; 363 | } 364 | printf("查询无果,查无节点"); 365 | return NULL; 366 | } 367 | 368 | // 指定位置插入节点 369 | void InsertNode(STUNODE *pTemp,char *arrStuNum, char *arrStuName, int iStuScore) 370 | { 371 | // 创建节点 372 | STUNODE *pNewTemp = malloc(sizeof(STUNODE)); 373 | 374 | // 节点成员符初始值 375 | strcpy(pNewTemp->arrStuNum,arrStuNum); 376 | strcpy(pNewTemp->arrStuName,arrStuName); 377 | pNewTemp->iStuScore = iStuScore; 378 | pNewTemp->pNext = NULL;// 记得一定赋值为空NULL 379 | 380 | // 插入节点 381 | if (pTemp == g_pEnd)// 尾节点 382 | { 383 | g_pEnd->pNext = pNewTemp; 384 | g_pEnd = pNewTemp; 385 | } 386 | else 387 | { 388 | pNewTemp->pNext = pTemp->pNext; 389 | pTemp->pNext = pNewTemp; 390 | } 391 | } 392 | 393 | // 删除指定节点 394 | void DeleteStuNode(STUNODE *pNode) 395 | { 396 | // 只有一个节点 397 | if (g_pEnd == g_pHead) 398 | { 399 | free(g_pEnd); 400 | g_pEnd = NULL; 401 | g_pHead = NULL; 402 | } 403 | // 只有两个节点 404 | else if (g_pHead->pNext == g_pEnd) 405 | { 406 | if (g_pHead == pNode) 407 | { 408 | free(g_pHead); 409 | g_pHead = g_pEnd; 410 | } 411 | else 412 | { 413 | free(g_pEnd); 414 | g_pEnd = g_pHead; 415 | g_pHead->pNext = NULL; 416 | } 417 | } 418 | // 一般情况,三个节点以上 419 | else 420 | { 421 | STUNODE *pTemp = g_pHead; 422 | if (g_pHead == pNode)// 要删除的是头节点 423 | { 424 | // 记住头 425 | pTemp == g_pHead; 426 | // 删除头 427 | g_pHead = g_pHead->pNext; 428 | free(pTemp); 429 | pTemp = NULL; 430 | 431 | return ; 432 | } 433 | else 434 | { 435 | while(pTemp != NULL) 436 | { 437 | if (pTemp->pNext == pNode) 438 | { 439 | // 删除 440 | if (g_pEnd == pNode)//要删除的是尾节点 441 | { 442 | free(pNode); 443 | pNode = NULL; 444 | g_pEnd = pTemp; 445 | g_pEnd->pNext = NULL; 446 | return ; 447 | } 448 | else// 要删除的是中间节点 449 | { 450 | // 记住要删除的节点 451 | STUNODE *p = pTemp->pNext; 452 | // 链接下一个节点 453 | pTemp->pNext = pTemp->pNext->pNext; 454 | // 释放节点P 455 | free(p); 456 | p = NULL;// 指针释放之后一定赋值为空,防止野指针 457 | return ; 458 | } 459 | } 460 | pTemp = pTemp->pNext; 461 | } 462 | } 463 | } 464 | } 465 | 466 | // 保存信息到文件 467 | void SaveStuToFile() 468 | { 469 | FILE *pFile = NULL; 470 | STUNODE *pTemp = g_pHead; 471 | //static char *strBuff[30] = {"\0"}; 472 | char *strBuff[30] = {"\0"}; 473 | //static char *strScroe[10] ={"\0"}; 474 | char *strScroe[10] ={"\0"}; 475 | 476 | // 判断链表是否为空 477 | if (NULL == g_pHead) 478 | { 479 | printf("链表为空,没有学生"); 480 | return ; 481 | } 482 | 483 | // 打开文件 484 | pFile = fopen("./stu.txt","wb+"); 485 | //pFile = fopen("./stu.txt","w+"); 486 | if (NULL == pFile) 487 | { 488 | printf("文件打开失败!\n"); 489 | return ; 490 | } 491 | // 操作文件 492 | while(pTemp != NULL) 493 | { 494 | // 学号赋值到strBuff 495 | // TODO cannot access memory at address 496 | // strcat函数不能访问,堆栈溢出,???? 497 | strcpy(strBuff,pTemp->arrStuNum); 498 | strcat(strBuff,",");// 以,间隔每一个字段,是一个字符串用双引号“” 499 | // 姓名 500 | strcat(strBuff,pTemp->arrStuName); 501 | strcat(strBuff,","); 502 | // 学分 503 | itoa(pTemp->iStuScore,strScroe,10); 504 | strcat(strBuff,strScroe); 505 | 506 | fwrite(strBuff,1,strlen(strBuff),pFile); 507 | fwrite("\r\n",1,strlen("\r\n"),pFile);// 每一个条记录进行换行储存 508 | 509 | pTemp = pTemp->pNext; 510 | } 511 | // 关闭文件 512 | fclose(pFile); 513 | } 514 | 515 | // 读取文件中的学生信息 516 | void ReadStuFromFile() 517 | { 518 | //char strBuff[30] = {"\0"}; 519 | char strBuff[30] = {0}; 520 | char strStuNum[10] = {0}; 521 | char strStuName[10] = {0}; 522 | char strStuScore[10] = {0}; 523 | //int iCount = 0;// 读取文件的字段间隔标志位 524 | //int j = 0; 525 | 526 | // 打开文件 527 | FILE *pFile = fopen("./stu.txt","ab+"); 528 | //FILE *pFile = fopen("./stu.txt","r+"); 529 | if (NULL == pFile) 530 | { 531 | printf("文件打开失败!\n"); 532 | return ; 533 | } 534 | // 操作指针,读取函数 535 | //while(EOF != fgets(strBuff,30,pFile))// EOF 文件结束标识符 536 | while(NULL != fgets(strBuff,30,pFile))// EOF 文件结束标识符 537 | { 538 | int i = 0; 539 | int iCount = 0; 540 | int j = 0; 541 | int n = 0; 542 | 543 | for (i = 0; strBuff[i] != '\r'; i++) 544 | { 545 | if (0 == iCount)// 没到分隔符 , 546 | { 547 | strStuNum[i] = strBuff[i]; 548 | if (',' == strBuff[i]) 549 | { 550 | strStuNum[i] = '\0';// 去掉分隔符 , 551 | iCount++; 552 | } 553 | } 554 | else if (1 == iCount)// 第一个分隔符 , 555 | { 556 | strStuName[j] = strBuff[i]; 557 | //j++; 558 | if (',' == strBuff[i]) 559 | { 560 | strStuName[j] = '\0';// 去掉分隔符 , 561 | iCount++; 562 | //j = 0; 563 | } 564 | j++; 565 | } 566 | else // 第二个分隔符 , 567 | { 568 | strStuScore[n] = strBuff[i]; 569 | n++; 570 | } 571 | } 572 | //int iStuScore = atoi(strStuScore); 573 | // 插入节点到链表 574 | // TODO 添加学生信息 575 | AddStuMSG(strStuNum, strStuName, atoi(strStuScore)); 576 | } 577 | // 关闭文件 578 | fclose(pFile); 579 | } 580 | -------------------------------------------------------------------------------- /学生管理系统/版本3/README.md: -------------------------------------------------------------------------------- 1 | #### 学生信息管理系统 2 | 3 | /*学生信息管理系统 4 | 1)添加学生信息 5 | 2)删除学生信息 6 | 3)查询学生信息 7 | 4)修改学生信息 8 | 5)显示所有学生信息以及统计信息 9 | 0)退出软件 10 | */ 11 | 12 | 13 | #### 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 14 | #### 字符集:UTF-8 15 | 16 | #### 知识点 17 | 1)C++语言的量声明和定义,以及变量初始化和生命周期与可见性 18 | 2)C++语言指针的定义,初始化 19 | 3)C++语言内存的申请和释放 20 | 4)C++语言循环结构、选择结构、分支结构 21 | 5)C++语言类的概念和对象的概念 22 | 6)C++语言析构函数和构造函数 23 | 7)C++语言函数声明、实现、调用 24 | 8)C++语言函数的参数、返回值 25 | 9)C++语言的输入输出以及格式控制 26 | -------------------------------------------------------------------------------- /学生管理系统/版本3/README.txt: -------------------------------------------------------------------------------- 1 | /*学生信息管理系统 2 | 1)添加学生信息 3 | 2)删除学生信息 4 | 3)查询学生信息 5 | 4)修改学生信息 6 | 5)显示所有学生信息以及统计信息 7 | 0)退出软件 8 | */ 9 | 10 | 11 | 编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) 12 | 字符集:UTF-8 13 | 14 | 知识点 15 | 1)C++语言的量声明和定义,以及变量初始化和生命周期与可见性 16 | 2)C++语言指针的定义,初始化 17 | 3)C++语言内存的申请和释放 18 | 4)C++语言循环结构、选择结构、分支结构 19 | 5)C++语言类的概念和对象的概念 20 | 6)C++语言析构函数和构造函数 21 | 7)C++语言函数声明、实现、调用 22 | 8)C++语言函数的参数、返回值 23 | 9)C++语言的输入输出以及格式控制 24 | -------------------------------------------------------------------------------- /学生管理系统/版本3/Student.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.cpp 4 | * Author 黎为 5 | * Description 主函数作为程序的入口 6 | */ 7 | 8 | #include "Student.h" 9 | #include 10 | 11 | //Student类的构造函数 12 | Student::Student() { 13 | name[20] = {}; 14 | age = 0; 15 | sex[10] = {}; 16 | } 17 | //Student类的构造函数重载 18 | Student::Student(char name[], int age, char sex[]) { 19 | //已知strcpy函数的原型是:char *strcpy(char *dst, const char *src); 20 | strcpy(this->name, name); 21 | this->age = age; 22 | strcpy(this->sex, sex); 23 | } 24 | char* Student::getname() { 25 | return this->name; 26 | } 27 | void Student::putname(char name[]) { 28 | strcpy(this->name, name); 29 | } 30 | int Student::getage() { 31 | return age; 32 | } 33 | void Student::putage(int age) { 34 | this->age = age; 35 | } 36 | char* Student::getsex() { 37 | return this->sex; 38 | } 39 | void Student::putsex(char sex[]) { 40 | strcpy(this->sex, sex); 41 | } 42 | //类的析构函数 43 | Student::~Student() 44 | { 45 | } 46 | -------------------------------------------------------------------------------- /学生管理系统/版本3/Student.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.h 4 | * Author 黎为 5 | * Description 作为main函数的头文件 6 | */ 7 | 8 | #ifndef STUDENT_H_INCLUDED 9 | #define STUDENT_H_INCLUDED 10 | 11 | #include 12 | #include 13 | using namespace std; 14 | //定义demo1命名空间,并将类纳入此空间中 15 | namespace demo1 { 16 | class Student 17 | { 18 | public: 19 | Student(); 20 | Student(char name[],int age,char sex[]); 21 | ~Student(); 22 | 23 | public: 24 | char* getname(); 25 | void putname(char name[]); 26 | int getage(); 27 | void putage(int age); 28 | char* getsex(); 29 | void putsex(char sex[]); 30 | private: 31 | char name[20]; 32 | int age; 33 | char sex[10]; 34 | }; 35 | } 36 | using demo1::Student; 37 | 38 | 39 | #endif // STUDENT_H_INCLUDED 40 | -------------------------------------------------------------------------------- /学生管理系统/版本3/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 云主宰苍穹 3 | * FileName main.cpp 4 | * Author 黎为 5 | * Description main主函数作为整个程序的入口 6 | */ 7 | 8 | #include 9 | #include 10 | #include "stuFile.h" 11 | 12 | using namespace std; 13 | //指明函数所在的命名空间namespace 14 | using demo1::cue; 15 | using demo1::addStu; 16 | using demo1::dispFile; 17 | 18 | int main(int argc, char *argv[]) 19 | { 20 | int num; 21 | cue();//格式化输出提示信息 22 | cin >> num; 23 | 24 | //循环进行学生信息的增删查改操作 25 | while (num!=0) 26 | { 27 | if (num < 0 || num>5) { 28 | cout << "输出错误,请重新输入!"; 29 | cue(); 30 | cin >> num; 31 | } 32 | else { 33 | char name[20] = {}; 34 | int age=0; 35 | char sex[10] = {}; 36 | 37 | switch (num) 38 | { 39 | case 1: 40 | { 41 | cout << "请输入学生信息" << endl; 42 | cout << "学生姓名:"; 43 | cin >> name; 44 | cout << "学生年龄:"; 45 | cin >> age; 46 | cout << "学生性别:"; 47 | cin >> sex; 48 | Student newStu(name,age,sex); 49 | addStu(newStu); 50 | cout << "添加成功" << endl; 51 | system("pause"); 52 | break; 53 | } 54 | case 2: 55 | { 56 | int num2; 57 | int n; 58 | cout << "******************************" << endl; 59 | cout << "* 1、按姓名删除: *" << endl; 60 | cout << "* 2、按年龄删除: *" << endl; 61 | cout << "* 3、按性别删除: *" << endl; 62 | cout << "* 4、按姓名、年龄、性别删除:*" << endl; 63 | cout << "******************************" << endl; 64 | cin >> num2; 65 | switch (num2) 66 | { 67 | case 1: 68 | { 69 | cout << "按姓名删除学生:" << endl; 70 | cin >> name; 71 | n = 1; 72 | break; 73 | } 74 | case 2: 75 | { 76 | cout << "按照年龄删除学生:" << endl; 77 | cin >> age; 78 | n = 2; 79 | break; 80 | } 81 | case 3: 82 | { 83 | cout << "按性别删除学生:" << endl; 84 | cin >> sex; 85 | n = 3; 86 | break; 87 | } 88 | case 4: 89 | { 90 | cout << "学生姓名:"; 91 | cin >> name; 92 | cout << "学生年龄:"; 93 | cin >> age; 94 | cout << "学生性别:"; 95 | cin >> sex; 96 | n = 4; 97 | break; 98 | } 99 | default: 100 | break; 101 | } 102 | Student delStu2(name, age, sex); 103 | demo1::delStu(delStu2,n); 104 | cout << "成功删除" << endl; 105 | system("pause"); 106 | break; 107 | } 108 | case 3: 109 | { 110 | int num3; 111 | cout << "********************" << endl; 112 | cout << "* 1、按姓名查找: *" << endl; 113 | cout << "* 2、按年龄查找: *" << endl; 114 | cout << "* 3、按性别查找: *" << endl; 115 | cout << "********************" << endl; 116 | cin >> num3; 117 | switch (num3) 118 | { 119 | case 1: 120 | { 121 | cout << "输入要查找的姓名:" << endl; 122 | cin >> name; 123 | Student newStu1; 124 | newStu1.putname(name); 125 | demo1::seleStu(newStu1); 126 | break; 127 | } 128 | case 2: 129 | { 130 | cout << "输入要查找的年龄:" << endl; 131 | cin >> age; 132 | Student newStu2; 133 | newStu2.putage(age); 134 | demo1::seleStu(newStu2); 135 | break; 136 | } 137 | case 3: 138 | { 139 | cout << "输入要查找的性别:" << endl; 140 | cin >> sex; 141 | Student newStu3; 142 | newStu3.putsex(sex); 143 | demo1::seleStu(newStu3); 144 | break; 145 | } 146 | default: 147 | break; 148 | } 149 | system("pause"); 150 | break; 151 | } 152 | case 4: 153 | { 154 | int num4; 155 | char newName[20] = {}; 156 | int newage = 0; 157 | char newsex[10] = {}; 158 | cout << "******************************" << endl; 159 | cout << "* 1、根据学生姓名更改信息: *" << endl; 160 | cout << "* 2、标准更改学生信息方式: *" << endl; 161 | cout << "******************************" << endl; 162 | cin >> num4; 163 | switch (num4) 164 | { 165 | case 1: 166 | { 167 | cout << "输入该学生原姓名:" << endl; 168 | cin >> name; 169 | cout << "输入学生新姓名:" << endl; 170 | cin >> newName; 171 | break; 172 | } 173 | case 2: 174 | { 175 | cout << "请输入原学生信息" << endl; 176 | cout << "学生姓名:"; 177 | cin >> name; 178 | cout << "学生年龄:"; 179 | cin >> age; 180 | cout << "学生性别:"; 181 | cin >> sex; 182 | 183 | cout << "请输入该学生新信息:" << endl; 184 | cout << "学生姓名:"; 185 | cin >> newName; 186 | cout << "学生年龄:"; 187 | cin >> newage; 188 | cout << "学生性别:"; 189 | cin >> newsex; 190 | break; 191 | } 192 | default: 193 | break; 194 | } 195 | Student stu(name, age, sex); 196 | Student newStu(newName, newage, newsex); 197 | demo1::changeStu(stu, newStu, num4); 198 | cout << "成功修改学生信息:" << endl; 199 | system("pause"); 200 | break; 201 | } 202 | case 5: 203 | demo1::displayStus(); 204 | system("pause"); 205 | default: 206 | break; 207 | } 208 | cout << endl; 209 | cue(); 210 | cin >> num; 211 | } 212 | } 213 | return 0; 214 | } 215 | -------------------------------------------------------------------------------- /学生管理系统/版本3/main.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.h 4 | * Author 黎为 5 | * Description 作为main函数的头文件 6 | */ 7 | 8 | #ifndef __MAIN__H__ 9 | #define __MAIN__H__ 10 | 11 | 12 | 13 | #endif // __MAIN__H__ 14 | 15 | -------------------------------------------------------------------------------- /学生管理系统/版本3/stuFile.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.cpp 4 | * Author 黎为 5 | * Description 主函数作为程序的入口 6 | */ 7 | 8 | #include "stuFile.h" 9 | #include 10 | 11 | void demo1::cue() { 12 | system("cls"); 13 | printf("***********欢迎使用学生信息管理系统(当前共有%02d名学生)***********\n", dispFile()); 14 | printf("* *\n"); 15 | printf("* --------------------------------- *\n"); 16 | printf("* | https://2694048168.github.io | *\n"); 17 | printf("* --------------------------------- *\n"); 18 | printf("* *\n"); 19 | printf("* 1)添加学生信息 *\n"); 20 | printf("* 2)删除学生信息 *\n"); 21 | printf("* 3)查询学生信息 *\n"); 22 | printf("* 4)修改学生信息 *\n"); 23 | printf("* 5)显示所有学生信息以及统计信息 *\n"); 24 | printf("* 0)退出软件 *\n"); 25 | printf("* *\n"); 26 | printf("******************************************************************\n"); 27 | } 28 | //添加学生信息 29 | void demo1::addStu(Student stu) { 30 | //打开文件 31 | ofstream examplefile("student.txt", ios::app|ios::binary); 32 | if (examplefile.is_open()) 33 | { 34 | //向文件中写入stu学生信息 35 | examplefile.write((char*)&stu,sizeof(stu)); 36 | 37 | } 38 | else { 39 | cout << "存储失败" << endl; 40 | } 41 | //关闭文件 42 | examplefile.close(); 43 | } 44 | //查询指定学生信息 45 | void demo1::seleStu(Student stu) { 46 | ifstream examplefile("student.txt", ios::in | ios::binary); 47 | if (examplefile.is_open()) { 48 | Student evastu; 49 | int i = 0; 50 | printf("***************************************\n"); 51 | printf("*----姓名--------年龄--------性别-----*\n"); 52 | while (examplefile.read((char*)&evastu, sizeof(stu))) { 53 | if (stu.getname() && !strcmp(evastu.getname(), stu.getname())) { 54 | i++; 55 | printf("*%8s%12d%12s *\n", evastu.getname(), evastu.getage(), evastu.getsex()); 56 | } 57 | else if (stu.getage() && (stu.getage() == evastu.getage())) { 58 | i++; 59 | printf("*%8s%12d%12s *\n", evastu.getname(), evastu.getage(), evastu.getsex()); 60 | } 61 | else if (stu.getsex() && !strcmp(evastu.getsex(), stu.getsex())) { 62 | i++; 63 | printf("*%8s%12d%12s *\n", evastu.getname(), evastu.getage(), evastu.getsex()); 64 | } 65 | } 66 | examplefile.close(); 67 | printf("***************************************\n"); 68 | cout << "共查找到" << i << "项数据"<< endl; 69 | } 70 | } 71 | //删除指定学生信息 72 | void demo1::delStu(Student stu,int n) { 73 | fstream samplefile("student.txt", ios::in | ios::out | ios::binary); 74 | Student evastu; 75 | if (samplefile.is_open()) { 76 | //建立并打开新的空文件 77 | ofstream examplefile("copyStu.txt", ios::out | ios::binary); 78 | if (examplefile.is_open()) { 79 | //将除stu之外的所有学生信息全部读入新文件中 80 | while (samplefile.read((char*)&evastu, sizeof(evastu))) 81 | { 82 | if (n == 1) { 83 | if (strcmp(evastu.getname(), stu.getname())) { 84 | examplefile.write((char*)&evastu, sizeof(evastu)); 85 | } 86 | } 87 | else if (n == 2) { 88 | if (evastu.getage() != stu.getage()) { 89 | examplefile.write((char*)&evastu, sizeof(evastu)); 90 | } 91 | } 92 | else if (n == 3) { 93 | if (strcmp(evastu.getsex(), stu.getsex())) { 94 | examplefile.write((char*)&evastu, sizeof(evastu)); 95 | } 96 | } 97 | else if (n == 4) { 98 | if ((evastu.getage() != stu.getage()) || strcmp(evastu.getname(), stu.getname()) || strcmp(evastu.getsex(), stu.getsex())) { 99 | examplefile.write((char*)&evastu, sizeof(evastu)); 100 | } 101 | } 102 | } 103 | //关闭两个文件 104 | examplefile.close(); 105 | samplefile.close(); 106 | } 107 | } 108 | //将新文件中的数据再拷贝到原文件中 109 | ofstream oldfile("student.txt", ios::trunc | ios::out | ios::binary); 110 | ifstream cpfile("copyStu.txt", ios::in | ios::binary); 111 | if (oldfile.is_open() && cpfile.is_open()) { 112 | while (cpfile.read((char*)&evastu, sizeof(evastu))) { 113 | oldfile.write((char*)&evastu, sizeof(evastu)); 114 | } 115 | } 116 | cpfile.close(); 117 | oldfile.close(); 118 | } 119 | //修改学生信息 120 | void demo1::changeStu(Student stu, Student newStu,int n) { 121 | fstream samplefile("student.txt", ios::in | ios::out | ios::binary); 122 | Student evastu; 123 | if (samplefile.is_open()) { 124 | ofstream examplefile("copyStu.txt", ios::out | ios::binary); 125 | if (examplefile.is_open()) { 126 | while (samplefile.read((char*)&evastu, sizeof(evastu))) 127 | { 128 | if (n == 1) { 129 | if (strcmp(evastu.getname(), stu.getname())) { 130 | examplefile.write((char*)&evastu, sizeof(evastu)); 131 | } 132 | else { 133 | newStu.putage(evastu.getage()); 134 | newStu.putsex(evastu.getsex()); 135 | examplefile.write((char*)&newStu, sizeof(newStu)); 136 | } 137 | } 138 | else if (n == 2) { 139 | if ((evastu.getage() != stu.getage()) || strcmp(evastu.getname(), stu.getname()) || strcmp(evastu.getsex(), stu.getsex())) { 140 | examplefile.write((char*)&evastu, sizeof(evastu)); 141 | } 142 | else { 143 | examplefile.write((char*)&newStu, sizeof(newStu)); 144 | } 145 | } 146 | } 147 | examplefile.close(); 148 | samplefile.close(); 149 | } 150 | } 151 | 152 | ofstream oldfile("student.txt", ios::trunc | ios::out | ios::binary); 153 | ifstream cpfile("copyStu.txt", ios::in | ios::binary); 154 | if (oldfile.is_open() && cpfile.is_open()) { 155 | while (cpfile.read((char*)&evastu, sizeof(evastu))) { 156 | oldfile.write((char*)&evastu, sizeof(evastu)); 157 | } 158 | } 159 | cpfile.close(); 160 | oldfile.close(); 161 | 162 | 163 | } 164 | //计算文件中所有学生的数量 165 | int demo1::dispFile() { 166 | int StuNum = 0; 167 | ifstream xamplefile("student.txt",ios::in|ios::binary); 168 | 169 | Student stu; 170 | while (xamplefile.read((char*)&stu, sizeof(stu))) { 171 | StuNum++; 172 | } 173 | xamplefile.close(); 174 | return StuNum; 175 | } 176 | //输出所有学生的信息 177 | void demo1::displayStus(){ 178 | printf("***********当前共有%02d名学生************\n", dispFile()); 179 | printf("*----姓名--------年龄--------性别-----*\n"); 180 | ifstream xamplefile("student.txt", ios::in | ios::binary); 181 | 182 | Student stu; 183 | while (xamplefile.read((char*)&stu, sizeof(stu))) { 184 | printf("*%8s%12d%12s *\n",stu.getname(),stu.getage(),stu.getsex()); 185 | } 186 | printf("***************************************\n"); 187 | xamplefile.close(); 188 | } 189 | -------------------------------------------------------------------------------- /学生管理系统/版本3/stuFile.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) https://2694048168.github.io 3 | * FileName main.h 4 | * Author 黎为 5 | * Description 作为main函数的头文件 6 | */ 7 | 8 | #ifndef STUFILE_H_INCLUDED 9 | #define STUFILE_H_INCLUDED 10 | 11 | #include "Student.h" 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | //定义一个demo1命名空间 17 | namespace demo1 { 18 | //格式化输出提示信息 19 | void cue(); 20 | //添加学生信息 21 | void addStu(Student stu); 22 | //查询学生信息 23 | void seleStu(Student stu); 24 | //删除学生信息 25 | void delStu(Student stu,int n); 26 | //修改学生信息 27 | void changeStu(Student stu,Student newStu,int n); 28 | //输出文件中学生信息的数量 29 | int dispFile(); 30 | //输出文件中所有学生的详细信息 31 | void displayStus(); 32 | } 33 | 34 | #endif // STUFILE_H_INCLUDED 35 | -------------------------------------------------------------------------------- /学生管理系统/版本3/the C++ of StudentInfoManagement.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2793134925/C-LanguageProjectCombat/12c3ede031ba53d1a9694cd4c42b04a0dbd9ac9d/学生管理系统/版本3/the C++ of StudentInfoManagement.exe --------------------------------------------------------------------------------