Loading... # C语言笔记 ## 一、基本结构: #include "main.h" #include <stdio.h>//包含头文件 #include<string.h>//包含头文件 #include<ctype.h>//专门专门处理字符串 #define PI 3.1415926//声明常量,下面不可修改 红定义 ```C int main(void) { const int a = 18;//这个也是声明常量,后面不能修改,(放在函数内) int num; num = 1; printf("yyds"); return 0; } ```  | | | - | | | --- 调用常数小练习: 练习1 float r; float C; printf("输入半径:"); scanf("%f", &r); C = r\*PI\*2; printf("圆的周长是:%.2f",C); 练习2. ```C int main() { int c; c=max(1,2); printf("%d",c); } ``` --- 二、主函数: 一个C程序有且只有一个主函数,即main函数。主函数就是C语言中的唯一入口,也是C语言的运行起点。即使有其他函数定义了,也要用过main函数来调用。 | | | - | | | void空 void main()空类型 int main() //主函数int整型 返回值int类型 --- 三、编写规范: 最顶行。如果在本目录下寻找头文件就用"",如果使用系统的头文件就用<>。 C语言的一般错误: 1.语法错误: 2.语义(逻辑)错误: 3.系统错误: --- Vs的使用规则: //F9可以生成断点,修改语义错误 //F5先生成,再运行 //F10单步步过 //F11单步步入 //32位程序和64位程序 //Release发行版 更小 做了优化,运行速度更快 //Debug 调试版 更大 优化更少 附带调试信息 --- 四、注释: //单行注释 /\* 整段注释 \*/ 五、标识符:  六、基本数据类型:  十一种基础类型: int,short,unsigned,char,float,double,signed,\_Bool,\_compiex(负数),\_Imaginary(虚数) 包含一个头文件:inttype.h 2进制 0 1 10 8进制 0 1 2 3 4 5 6 7 10 10进制 0 1 2 3 4 5 6 7 8 9 10 16进制 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 int num = 100; printf("num的8进制显示:%o,10进制显示:%d,16进制显示:%x", num, num, num); 整数类型: int类型占三十二位 -2^31到2^31-1 -2,147,483,648到2,147,483,647  IDM PC -2^15到2^15-1 -32768到32767 int 32位 short int 16位(short 不长于int类型) long int 32位(long 不短于int类型) long long int 64位(long long) unsigned无符号修饰int,short,long也就是说是正数 %ld就是长整型。%hd是短整型。%u无符号 这些都可以组合使用 //字符类型char //理论上占8位,-128到127。 Ascii码0到127。 Unicode 16位,甚至是32位。 //正确方式:char name = 'A'或char name1; // name1 = 'A' //双引号是字符串,单引号是字符 //float 单精度浮点型 32位 //double 双精度浮点型 64位 //其实浮点寄存器不能精确存储。是用科学记数法 //\_Bool类型是从c99的时候引入的 //声明\_Bool a = 0; //0代表false 假。1代表true 真 **sizeof** 返回的是实际占用的内存数 **strlen** 计算字符串的有效字符数,遇到NULLL结束,NULL = 00 printf("计算int类型数据宽度:%d\\n",sizeof(int));//4 printf("计算char类型数据宽度:%d\\n", sizeof(char));//1 printf("计算float类型数据宽度:%d\\n", sizeof(float));//4 printf("计算double类型数据宽度:%d\\n", sizeof(double));//8 printf("计算long类型数据宽度:%d\\n", sizeof(long));//4 printf("计算short类型数据宽度:%d\\n", sizeof(short));//2 printf("计算long long类型数据宽度:%d\\n", sizeof(long long));//8 return 0; 七、格式化输出语句:  小练习: char m[8]; int a; float h; double k; printf("输入姓名,年龄,升高,体重:\\n"); scanf("%s",m); scanf(" %d", &a); scanf(" %f", &h); scanf(" %lf", &k); printf("姓名:%s,年龄:%d,升高:%f,体重:%.2lf",m,a,h,k); 八、自动转化类型:  九、强制类型转换:  十、运算符: (一).算数运算符:  1.除法运算中注意: 如果相除的两个数字都是整数的话,则结果也为整数,小数部分省略; 两数中有一个为小数,则结果为小数。 2.取余运算注意事项: 取余运算中只适合两个整数进行取余运算;运算后的符号取决于被模数的符号。 注意:C语言中没有乘方这个运算符,也不可用x,➗等算数符。 =是赋值。==是看两边是否相等 (二).自增运算符和减运算符:  (三).赋值运算符: 1.简单赋值运算符:“=” 2.复合赋值运算符:在简单赋值运算符“=”之前加上其他运算符构成,例如:+=,-=,\*=,/=,%=。 例子: 分析:定义类型变量a赋值为3,**a += 5这个式子就等价于a = a+5;将变量a和5相加之后再赋值给a.** (四).关系运算符:  关系表达式的值是“真”和“假”,再C程序用整数1和0表示。如:  注意:像 >=,<=,==,!=这种符号之间不能存放空格。 (五).逻辑运算符: //&& || !相当于and or not 相当于 与 或 非 (六).位运算: int main() { //位运算(都是转化为二进制进行) //与&。 或|。 非\~变量名(取反)。抑或^ int a = 100; int b = 50; int c = a & b;//一个是0就是0,两个是1才是1 int d = a | b;//一个是1就为1,两个是0才是0 int e = \~a;//二进制取反 int f = a ^ b;//二进制相同时是0,不同时是1 <<二进制左移。高位丢弃,低位补零。 >> 二进制右移。 符号后加数字表示移动了几位。低位丢弃,高位补零或者补符号位 >> } (七).三目运算符:”?” 格式:表达式1? 表达式2:表达式3 执行过程:先判断表达式是否为真,如果是真的话执行表达式2;如果是假的话执行表达式3。 //? : 三步运算符 int a = 5; int b = 6; int c; c = (a < b) ? 7 : 8;//如果括号为真,则c=7,否则c=8 (八).优先级比较:  牢记最高级! //运算符+ - \* / () = == 小括号的运算级别最高。%求模运算符 //C语言除法运算中,如果你的类型是整形,就会被结尾 //如果是浮点型,就会保留小数 //a++就是a=1+1。a--就是a=1-1。 十一.参数的声明方式: 整数型: // int Num; //类型名 变量名 // int Num1, Num2, Num3; //类型名 变量名,变量名,变量名 int Num1; int Num2; int Num3; Num = 1; Num1 = 2; Num2 = 3; Num3 = 4; //scanf 输入函数 scanf("%d",&Num) //scanf\_s 输入函数 scanf\_s("%d",&Num,10) int Num4; //scanf("%d", &Num4); //%d就相当于告诉程序,接受的参数是一个int类型 //&Num4 告诉程序,接受到的数据,储存到Num4里面 int Num5 = 5; int Num6, Num7 = 5; //int Num6=Num7 = 5这样才可以两个都赋值位5,一个等号只赋值一个 整数型小练习: 练习1. //printf("%d",Num5); //int age; //\\n换行 printf("请输入你的年龄:\\n"); scanf("%d", &age); printf("您的年龄是:%d",age); 练习2. int Num1; int Num2; int RetNum; printf("请输入一个数字:"); scanf("%d",&Num1); printf("请再次输入一个数字:"); scanf("%d", &Num2); RetNum = Num1 + Num2; //一个等于号是赋值的过程 printf("%d + %d = %d",Num1,Num2,RetNum); return 0; //返回值0 (二).字符类型: //char name[128] = { 'A', 'B', 'C', 0 }; //char name[128] = "ABC"; //char name[] = "ABC"; char name[128]; scanf("%s", name); //字符串变量不需要再作作为scanf参数的时候加&符合哦 printf("%s", name); char name[] = "ABCD12345";//该字符串有九个字符,加上00占10个字符 sizeof(name);//10 strlen(name);//9 关于字符的常用函数: //char a; //a = getchar();//专门获取字符 //putchar(a);//只打印一个字符 //char flag = tolower(a);//把大写字符转化为小写字符 //char flag = toupper(a);//把小写字符转化为大写字符 //int flag = isalpha(a);//判断参数是否位字母,非字母返回值为0,是字母就返回真值 //isalpha()判断()是不是字母或者数字 //isblank()判断参数是否位空字符比如空格、换行 //iscntrl()判断是不是空字符 //isdigit()判断是不是阿拉伯数字 //isgraph()判断是不是除空格外的可打印字符 //islower()判断是不是小写字母 //isprintf()判断是不是可打印字符 //ispunct()判断是不是标点符号 //isspace()判断是不是空字符 //isupper()判断是不是大写字母 //isxdigit()判断是不是十六进制的数 strrev()函数将字符串逆置 实用小技巧: char string; while ((string = getchar()) != "#") { putchar(string);//只要不是#(推荐使用EOF)什么串都可以打印出花来 } //有个缓冲区 //假如当输入“123456789”其实都保存到了缓冲区 //getchar实际上从缓冲区获取了字符。但其实是一次取一个出来拼接出来的 //Ctrl+c可以随时结束 //Ctrl+z前面没字符可以结束 (三).字符串: char szStr0[50] = "My name is zhongyuwen";//双引号会自动加结尾00 puts (szStr0); char szStr1[50] = { 'M','y',' ','n','a','m','e','\\0' };//最后添加\\0才会把字符变成字符串 puts(szStr1); char szStr2[] = "My name is yitai";//未定义元素个数,先写会再自动计算元素个数 puts(szStr2); char \*szStr3 = "My name is zhongyuwen"; puts(szStr3); (四).数组: 一维数组: int Number[10] = { 0,1,2,3,4,5,6,7,8,9 };//[]里面一定要是一个常量(define红定义) //{[5]=5};这样就只给第五个元素赋值 //{0};给所有元素初始化为零 //Number[1] = 2 后面只能一个一个的给他里面的元素赋值,注意不能越界 //const 加在int前,数组就全部变成了常量,不可像上面重新赋值了 //Number[0] 首元素 //Number[9] 最后一个元素 二维数组: //二维数组 int NumberN[3][5] = { {0,1,2,3,4},{5,6,7,8,9},{9,8,7,6,5} };//相当于有3个5个元素的一维数组,三个数组都有五个元素 多维数组以此类推… 十二.循环: 1.while 2.do while 3.for 例子: [int]() main() //主函数int整型 返回值int类型的 { //死循环,没有退出的可能,或者说没有退出的条件 int x = 0; while (1)//true=1 { printf("%d\\n", x); x++; } //执行100 + 1 = 101次 //1.判断(x<=100)返回值是否为ture(1) //2.如果返回值是1,那么就进入代码块中执行,否则到循环外的第一条代码执行 //do while循环无论如何都会进入代码块中执行一次 int x = 0; do { //代码块 printf("循环第%d\\n次!", x); x++; } while (x<=100); //1.首先执行代码块 //2.进行表达式判断 //3.如果表达式返回结果是1,那么就进入代码块继续执行,否则退出循环 循环对数组 int arr[10]; for (int i = 0; i < 10;i++) { arr[i] = i; } for (int i = 0; i < 10;i++) { printf("%d\\n",arr[i]); } for (int i = 0; i <= 100; i++) { printf("%d\\n", i); } //1.循环计数器赋初值 //2.判断是否符合表达式 //3.执行代码块 //4.计数器的自增 //5.判断是否符合表达式...... //循环语句 //x+=2就是x=x+2 //嵌套式 int flag = 0; for (int i = 0; i < 100; i++) { for (int x = 0; x < 100; x++) { printf("%d\\n", flag); flag++; } } //第一层循环会执行100次 //第二层也会执行100次 //每次执行第一层循环1次,第二层就会执行100次 //所以总共=100\*100=10000 int a = 0; int b = 1; int c = 0; printf("输入一个整形:%d", c); scanf("%d",&c); //c = a + b;//把a+b的结果放到c里面存储。 =是赋值。==是看两边是否相等 if (c == a + b) { printf("c与a+b相等"); } else { printf("c与a+b不相等"); } return 0; 结束循环: continue跳出单次循环 break跳出大循环 for (int i = 0; i < 5; i++) { if (i == 3) { continue;//跳出单次循环,该例子系统打出0 1 2 4 //break;//跳出大循环,该例子系统打出0 1 2 } printf("%d\\n", i); } 十三.结构: //1.顺序结构 //2.循环结构 int x = 100; while (x >= 0) { printf("%d ", x); x = x - 1; } return 0; //3.选择结构 // if和else if和esle //swith和case //[gato]() if和else if和esle int flag = 5; int num = 0; printf("请输入一个数字!"); scanf("%d", &num); if (num == 1) { printf("num = 1"); } else if (num == 2) { printf("num = 2"); } else { printf("num != 1 && num !=2"); } return 0; swith和case case语句后面的必须是整型常量 int flag = 5; switch (flag) { case 1://以冒号为结尾 printf("1"); break;//加break才不会往下走 case 2: printf("2"); break; case 3: printf("3"); break; case 4: printf("4"); break; case 5: printf("5"); break; default://如果上面的都不匹配则进入缺省这里 printf("default"); break; } return 0; gato loop://以冒号结尾 printf("1\\n"); printf("1\\n"); printf("1\\n"); printf("1\\n"); //goto loop;//到这里就会跳回上面的loop printf("2\\n"); printf("2\\n"); printf("2\\n"); printf("2\\n"); return 0; int x = 1000; if (x == 100) { printf("x == 100"); } else { printf("x != 100"); } return 0; 小练习: int max(int a,int b) { int c; if(a>=b) { c=a; } else { c=b; } return c; } 猜数字游戏作业 int x; while(1) { printf("请输入一个整形:"); scanf(" %d", &x); if (x == 8) { printf("你答对啦!\\n"); break; } else { printf("你答错了!\\n"); } } return 0; 猜一猜游戏测试 如果这样,可以限制输入范围 int n = 0; int MaxNum = 1000; int MinNum = -1000; if (n <= MaxNum && n >= -1000) { //把下面的游戏放入这里就可以限定范围啦1 } while (1) { int num; int flag = 15; printf("猜一猜我预置的数时多时!"); scanf("%d", &num); if (num == 15) { printf("你答对啦!\\n"); break; } else { printf("错啦!\\n"); } } return 0; 十三.函数学习啦! 记得要在头文件创建声明与定义。 返回值类型 函数名(参数--形式参数) { Code; //Return 变量名; //具有返回值的一个自定义函数 } 如果自定义函数没有返回值,在定义函数时函数返回类型需写为void空类型。 如果函数没有形式参数,那么参数为void   //功能:把一类功能封装起来,反复使用。 int add(int a,int b)//这里()里面的是形式参数 { int c = a + b; return c; } /\* 函数类型 函数名(参数表) { 实现代码 返回值(return x) } \*/ int main() { int num = add(1,2);//实际参数 //int num = add(5, 7); return 0; } //递归 int main() { printNumber(0);//实际参数 return 0; } int printNumber(int a) { printf("%d\\n", a); if (a <= 10) printNumber(a + 1); return 0; } //作业:实现一个四则运算的计算器函数 int main() { int a = 0; char b = 0; int c = 0; //int rat = 0; printf("输入第一个数:"); scanf(" %d", &a); printf("输入第二个数:"); scanf(" %d", &c); printf("输入运算符:"); scanf(" %c", &b); MyCalc(a, c, b); //rat=MyCalc(a, c, b); //printf("%d %c %d = %d", a, b, c, rat); return 0; } int MyCalc(int a,int c, char b)//记得在头文件里给函数定义 { int ret; switch (b) { case '+': ret = a + c; printf("%d和%d的和为%d", a, c, ret); break; case '-': ret = a - c; printf("%d和%d的差为%d", a, c, ret); break; case'%': ret = a % c; printf("%d除以%d的余为%d", a, c, ret); break; case'\*': ret = a \* c; printf("%d乘以%d的积为%d", a, c, ret); break; case'/': ret = a / c; printf("%d除以%d的商为%d", a, c, ret); break; default: break; } return 0; } 十四.数组: 数组:是由多个同类型的变量组成的连续的变量集合 | Int | int | int | int | int | int | int | int | int | int | | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | | 11 | 22 | 33 | 44 | 232 | 545 | 24 | 643 | 6353 | 345 | | Arr[0] | Arr[1] | Arr[2] | Arr[3] | Arr[4] | Arr[5] | Arr[6] | Arr[7] | Arr[8] | Arr[9] | #define MAX 10 int main() { //数组 其实就是一组相同变量所组成的集合 [int]() Number[10] = { 0,1,2,3,4,5,6,7,8,9 };//[]里面一定要是一个常量(define红定义) //{[5]=5};这样就只给第五个元素赋值 //{0};给所有元素初始化为零 //Number[1] = 2 后面只能一个一个的给他里面的元素赋值,注意不能越界 //const 加在int前,数组就全部变成了常量,不可像上面重新赋值了 //Number[0] 首元素 //Number[9] 最后一个元素 for (size\_t i = 0; i < 10; i++) { printf("%d\\n", Number[i]); } return 0; } int main() { //一维数组 int Number[5] = { 0 }; //多维数组 [//]()二维数组 int NumberN[3][5] = { {0,1,2,3,4},{5,6,7,8,9},{9,8,7,6,5} };//相当于有3个5个元素的一维数组,三个数组都有五个元素 for (int i = 0; i < 3; i++)//循环计数器遍历数组 { printf("正在打印%d个数组:\\n", i); for (int y = 0; y < 5; y++) { printf("%d\\n", NumberN[i][y]); } } //三维数组 //int NummberX[2][3][5] = { 0 }; //四维数组 //int NumberY[2][3][4][5] = { 0 }; return 0; } while循环给数组赋值遍历 int main() { int i = 0; int shuzu[2][3]; while (i < 2) { printf("正在输入第%d个数组:\\n",i); int y = 0; while (y < 3) { printf("输入shuzu[%d]的值:", y); scanf("%d", &shuzu[i][y]); y++; } i++; } int a = 0; while (a < 2) { printf("正在打印第%d个数组\\n", a); int b = 0; while (b < 3) { printf("shuzu[%d][%d]=%d \\n", a, b, shuzu[a][b]); b++; } a++; } return 0; } 练习1.给数组求平均数: int main() { double sum = 0; double shuzu[6] = { 23.5,45.67,12.1,6.4,58.9,98.4 }; double \*p = shuzu; for (size\_t i = 0; i < 6; i++) { sum = sum + \*(p+i); } double a; int b; int x = 0; a = sum / 6; printf("平均值是%.2f\\n", a); for ( b = 0; b < 6; b++) { if (\*(p + b) <= a) { x++; } } printf("符合题意的实数个数有%d个", x); return 0; } 练习2.二维数组的赋值遍历: int main() { int arr[N][Z];//首先,创建一个二维数组。 //根据头文件红定义,这里是定义有了四个包含两个元素的一维数组。 for (int i = 0; i<N; i++)//运用计数器循环,依次进入第i(0,1,2,3)个一维数组,下一个for再去依次赋值。 { for (int j = 0; j < Z; j++)//同理,给一维数组里面的元素依次赋值 { printf("arr[%d][%d]=", i, j);//提示输入元素 scanf(" %d", &arr[i][j]);//赋值 } } printf("\\n\\n");//换行 换行 for (int i = 0; i < N; i++)//同理,上面是赋值,这里就是遍历了 { for (int j = 0; j < Z; j++) { printf("arr[%d][%d]=%d\\n", i, j, arr[i][j]);//打印出数组和赋值后的元素值 } } return 0; } 十五.指针: int main() { //指针 //& 取地址运算符 用法:&变量名 //\* 简介运算符 int Number = 0; int \*pNum = &Number; \*pNum = 5; Number = 6; //&Number = 0x006FFAB4 //pNum = 0x006FFAB4 //\*pNum相等于把(地址:0x006FFAB4=5)内的值取出来 printf("变量Number的值和地址是:%d,%x", Number, &Number); return 0; } 例子: void add(int \* a, int \* b) { int temp = \*a + \*b; \*a = temp; } int main() { int x = 5; int y = 6; add(&x, &y); printf("%d", x); return 0; } //0x00BFF718 = &x = a //0x00BFF70C = &y = b //\*a = 5 = x //\*b = 6 = y //\*a = 11 = x = 11 数组和指针的关系 int main() { int Number[10] = { 0,1,2,3,4,5,6,7,8,9 }; int \* p = Number; for (size\_t i = 0; i < 10; i++) { printf("%d\\n", \*(p + i)); //或者p[i] } return 0; } //0x00BFF810 = Number //0x00BFF810 = p //int类型数组中一个元素占32位 //指针地址 + 1 = 加一个类型长度 相当于(指针地址 + sizeof(int)),减号同理. 十四.字符串: 1. 一个char对应一个字符 2. 一个字符串是一段char 3. 字符串的结尾固定为\\0也就是00 | char | char | char | char | char | char | char | char | char | char | Char | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | A | B | C | 1 | 2 | 3 | D | \\0 | | | | | 61 | 62 | 62 | | | | 64 | 00 | | | | 字符串也可以是一串数字,空格,符号,字母 int main() { /\*//字符串的声明方式 //字符串是用 00 \\0 %s //gets获取 puts输出 char szStr0[50] = "My name is zhongyuwen";//双引号会自动加结尾00 puts (szStr0); char szStr1[50] = { 'M','y',' ','n','a','m','e','\\0' };//最后添加\\0才会把字符变成字符串 puts(szStr1); char szStr2[] = "My name is yitai";//未定义元素个数,先写会再自动计算元素个数 puts(szStr2); char \*szStr3 = "My name is zhongyuwen"; puts(szStr3); //输入输出用法 char szStr4[50]; gets(szStr4); puts(szStr4); \*/ /\*//指针加循环打印字符串 char \*szArrStr[3] = { "My name is!","wo si neng die","ioirr man" }; for (size\_t i = 0; i < 3; i++) { puts(szArrStr[i]); }\*/ /\*//fgets输入 fputs输出 char szStr[50]; fgets(szStr, 50, stdin);//(字符串名,最多读取几个元素,参数(标准输入)) fputs(szStr, stdout);//(字符串名,参数(标准输出)) \*/ char szStr0[50] = "My name is"; int len = strlen(szStr0);//计算字符串的实际有效占位后接收赋值 //strncat字符串拼接函数:在第一个字符串后面再拼接一个新的字符串形成一个新的字符串 char szStr1[50] = " Hello!"; strncat(szStr0, szStr1,10);//顺序拼接以第一个为新名 //(前,后,(可用数字按先后顺序限制后面字符串的实际长度来拼接)) puts(szStr0); //strcmp字符串比对函数:把字符串转化为ASCII码然后相减 strcmp(szStr0, szStr1); if (strcmp(szStr0, szStr1) != 0) { //(名,名,数字(限制比对长度)) printf("不等!"); } else { printf("等!"); } //strcpy strncopy字符串拷贝函数 strcpy(szStr0, szStr1);//把后面的拷贝到前面里,前面的会清空 //(名,名,数字(限制长度)) puts(szStr0); //sprintf拼接函数 char szStr3[50]; sprintf(szStr3, "adasr;daa;SAD;%s%s", szStr0, szStr1); puts(szStr3); return 0; } 十五.存储类 = C语言有6种存储模型 //作用域 存储时期 int c = 0;//全局变量:作用域在整个程序。静态存储时期 int add(int a, int b) { //int c = a + b;//局部变量:作用域在函数内。自动存储时期 c = a + b; return c; } int main() { auto int x = 0; //auto表明局部动态存储类 //register 寄存器 //extern 具有外部链接的静态存储类 //static 具有内部链接的静态存储类 //static 空连接的静态存储类 add(1, 2); return 0; } 十六. 分配和释放内存:malloc 和 free 成对出现 //例子 int main() { char \* szStr; szStr = (char \*)malloc(50 \* sizeof(char));//分配内存 memset(szStr, 0, 50 \* sizeof(char));//初始化成0 free(szStr); //释放内存 return 0; } //用法 int main() { char szStr[] = "My name is rikvir"; char \* szStr1; int length = (strlen(szStr) + 1); szStr1 = (char \*)malloc(length \* sizeof(char)); memset(szStr1, 0, length); //memest() 里面的参数有三个(要初始化的缓冲区,(要刷的值)0,要初始化的长度) strcpy(szStr1, szStr); puts(szStr1); free(szStr1); return 0; } 十七.文件操作: 文件指针:位于文件最开始的位置上,可以来回移动到任意位置,从任意位置开始读取任意长度的数据,通过移动指针进行文件读取,移动到最后位置结束! //文件读取 int main() { FILE \*pFile;//文件指针类型 char \* szReadTextBuffer;//缓冲区 int nReadFileSize;//用来读取文件长度 int nReadRetSize;//返回长度 pFile=fopen("C://xuexi/123456.txt", "rb"); //fopen()里面有两个参数("文件路径","标识符") //r读取 w写出 b二进制 if (pFile == NULL)//如果读取文件失败 { printf("Open filoe failed!"); exit(0);//退出程序 } fseek(pFile, 0, SEEK\_END);//把文件指针放到末尾处,通过文件指针位置,这样就可以获取文件长度 //fseek()里面有三个参数(文件指针,0,移动位置) nReadFileSize = ftell(pFile);//ftell(文件指针)通过文件指针位置,获取文件大小 rewind(pFile);//rewind(文件指针)把文件指针复位到最前面 //申请一个足够大的内存来保存我们读取进来的东西 szReadTextBuffer = (char \*)malloc((nReadFileSize \* sizeof(char)) + 1); if (szReadTextBuffer == NULL)//如果内存申请失败 { printf("malloc memory failed!"); exit(0); } memset(szReadTextBuffer, 0, nReadFileSize + 1);//给申请的内存初始化 //memest() 里面的参数有三个(要初始化的缓冲区,(要刷的值)0,要初始化的长度) nReadRetSize = fread(szReadTextBuffer, 1, nReadFileSize ,pFile);//文件读取 //fread() 里面有四个参数(可存储数据的内存空间,((要传的值)1,要读取的数据长度,文件指针) if (nReadRetSize != nReadFileSize)//如哦读取的真实长度和预设的不相等 { printf("read file failed!"); exit(0); } puts(szReadTextBuffer); fclose(pFile);//把文件指针释放掉 //printf("计算char类型数据宽度:%d\\n", sizeof(char)); return 0; } //写入文件 int main() { char \* szWriteBuffer = "My name is yitai! hahahahaha"; FILE \* pFile; pFile = fopen("C://xuexi/654321.txt", "wb"); if (pFile == NULL) { printf("failed!"); exit(0); } fwrite(szWriteBuffer, strlen(szWriteBuffer), 1, pFile); //写出函数,fwrite()里面有四个参数(要写出的东西,要写的长度,每次写出多少(1),文件指针) fclose(pFile);//怎么说也要报文件指针释放掉吧。 return 0; } 十八.结构体.共用体.枚举类型 (一)结构体: int main() { //比如游戏Game中有,Name,HP,MP等数据很多变量,用结构体便可完美解决 struct GamePlayerInfo//游戏名 { char PlayerName[50]; int HP; int MP; float x; float y; float z; }; //系统设置玩家名和各项参数 struct GamePlayerInfo yitai = { "yitai",500,500,123.25,155.55,0 }; struct GamePlayerInfo weizhi = { .PlayerName = "weizhi",.MP = 1000 }; weizhi.x = 156.55; weizhi.y = 12231.121; weizhi.z = 0; weizhi.HP = 500; //也可以这样给用户输入获取设置 printf("设置你的游戏昵称:"); scanf("%s", weizhi.PlayerName); printf("%s", yitai.PlayerName);//打印游戏昵称 //设置NPC struct NPCInfo//游戏名 { char NPCName[50]; int HP; int MP; float x; float y; float z; }; struct NPCInfo MyNPCInfo[50];//批量化生产 for (size\_t i = 0; i < 50; i++) { strcpy(MyNPCInfo[i].NPCName, "NPC"); MyNPCInfo[i].HP = 100; MyNPCInfo[i].MP = 100; MyNPCInfo[i].HP = rand();//设置成随机数 } (二)结构体的嵌套结构。可以放在头文件里 struct NPCInfo//游戏名 { char NPCName[50]; int HP; int MP; float x; float y; float z; }; struct GamePlayerInfo//游戏名 { char PlayerName[50]; int HP; int MP; float x; float y; float z; struct NPCInfo MyNPCInfo; }; struct GamePlayerInfo yitai; yitai.MyNPCInfo.HP = 100; printf("%d", yitai.MyNPCInfo.HP); (三). 指针操作结构体 struct NPCInfo//游戏名 { char NPCName[50]; int HP; int MP; float x; float y; float z; }; struct GamePlayerInfo//游戏名 { char PlayerName[50]; int HP; int MP; float x; float y; float z; struct NPCInfo MyNPCInfo; }; struct GamePlayerInfo yitai = { "rkvir",100,100,45.111,1232.55,858.55 }; struct GamePlayerInfo \* p; p = &yitai; printf("%s", p->PlayerName);//两种方式都一样可以调用 printf("%s", (\*p).PlayerName);//两种方式都一样可以调用 (四).联合体; ```C union Info { char PlayerName[20]; int MP; float x; }; union Info MyInfo; strcpy(MyInfo.PlayerName, "NPC"); printf("%s\\n%d\\n%f\\n", MyInfo.PlayerName, MyInfo.MP, MyInfo.x); // 0x00D1FA1C = MyInfo = MyInfo.x = MyInfo.MP = My.playerName地址全都相同 //这说明不能同时使用连接体里面的多个元素,当用多个使用时只有最后一个有用,所以每次只能用一个 ``` (五).枚举类型: ```C enum color{red,blue,green};//这样是默认从零开始的 //enum color{red = 10,blue = 20,green = 30};也可以这样自定义 int flag = 0; printf("输入一个数:"); scanf("%d", &flag); switch (flag) { case red: printf("red"); break; case blue: printf("blue"); break; case green: printf("green"); break; default: break; } ``` 十九.typedef的使用:取别名 ```C typedef struct GamePlayerInfo { char PlayerName[50]; int HP; int MP; float x; float y; float z; }yitai;//这样就是可以用yitai代替了struct GamePlayerInfo,变得更简洁 //给类型取别名 typedef int taiyi; taiyi m = 55; //typedef和#define的区别 //前者替换的是类型,后面的是替换的是值 return 0; } ``` 二十. C预处理器和C库 #define MYMUL(X) X\*X//或者printf("This is number:%d",X) //#undef MYMUL(X)//声明注销 //#ifdef #else #endif #define YITAI #define SYS 1 #include <math.h>//数学库 int main() { /\*int c = MYMUL(5); printf("%d", c);\*/ /\*//#ifdef #else #endif #ifdef YITAI//上面要有声明才会执行 printf("this is def"); #else//否则 printf("this is else"); #endif//表示结束\*/ /\*#if SYS == 1//必须要有一个定义符合才运行其中一个 printf("1"); #elif SYS == 2 printf("2"); #endif\*/ /\*//数学库的使用 int c = fabs(-1);//计算绝对值 int a = sqrt(15);//计算平方根 return 0;\*/ //} 二十一. 高级数据表示 //例子 //书名:char BookName[50]; //书号:int BookNumber; //定价:float BookPrice; /\*struct BookInfo { char BookName[50]; int BookNumber; float BookPrice; }; struct BookInfo mybookinfo[9999];//如果书太多就可以用下面的链表了 //指针。 1.定义链表结构。2.实现链表增删改查。\*/ int main() { Node \* head = NULL;//链表头指针 char szBookName[50]; float fBookPrice = 0; float fNewBookPrice = 0; int nBookNumber = 0; int Readflag = 0; while (1) { printf("请选择你需要使用的功能:\\n"); printf("1.添加书籍信息\\n"); printf("2.查询书籍信息\\n"); printf("3.修改书籍信息\\n"); printf("4.删除书籍信息\\n"); scanf("%d", &Readflag); switch (Readflag) { case 1: printf("请输入书名:"); scanf("%s", szBookName); printf("数入定价:"); scanf("%f", &fBookPrice); printf("输入书号:"); scanf("%d", &nBookNumber); head = AppendNode(head, szBookName, fBookPrice, nBookNumber); break; case 2: printf("请输入书名:"); scanf("%s", szBookName); QueryNode(head, szBookName); break; case 3: printf("请输入书名:"); scanf("%s", szBookName); printf("请输入新定价:"); scanf("%f", &fNewBookPrice); ModifyNode(head, szBookName, fNewBookPrice); break; case 4: printf("请输入书名:"); scanf("%s", szBookName); head = DeleteNode(head, szBookName); break; default: break; } } return 0; } Node \* AppendNode(Node \* head,char \*BookName,float BookPrice,int BookNumber)//末尾添加节点 { Node \* pNewNode = NULL;//生成一个新节点指针 Node \* pHeadNode = head;//生成一个指向头指针的指针 pNewNode = (Node \*)malloc(sizeof(Node));//申请一个新的节点并申请内存 if (pNewNode == NULL)//如果没有申请成功 { printf("memory malloc failed!\\n"); exit(0); } if (head == NULL)//如果没有头节点 { head = pNewNode;//设置一个头节点 } else { while (pHeadNode->next !=NULL) { pHeadNode = pHeadNode->next; } pHeadNode->next = pNewNode; } strcpy(pNewNode->BookName, BookName); pNewNode->BookPrice = BookPrice; pNewNode->BookNumber = BookNumber; pNewNode->next = NULL; return head; } void QueryNode(Node \* head, char \*BookName)//查询功能 { int flag = 0; if (head == NULL)//如果头指针为空 { printf("head == NULL!"); exit(0); } if (strcmp(BookName, head->BookName) == 0) { printf("书名:%s\\n定价:%f\\n书号:%d\\n", head->BookName, head->BookPrice, head->BookNumber); flag = 1; } while (head->next != NULL) { head = head->next; if (strcmp(BookName, head->BookName) == 0) { printf("书名:%s\\n定价:%f\\n书号:%d\\n", head->BookName, head->BookPrice, head->BookNumber); flag = 1; } } if (flag == 0) { printf("Query failed!"); } } void ModifyNode(Node \* head, char \* BookName, float BookPrice) { int flag = 0; if (head == NULL)//如果头指针为空 { printf("head == NULL!"); exit(0); } if (strcmp(BookName, head->BookName) == 0) { head->BookPrice = BookPrice; printf("新定价:%f\\n", head->BookName, head->BookPrice, head->BookNumber); flag = 1; } while (head->next != NULL) { head = head->next; if (strcmp(BookName, head->BookName) == 0) { printf("新定价:%f\\n", head->BookName, head->BookPrice, head->BookNumber); flag = 1; } } if (flag == 0) { printf("Modify failed!"); } } Node \* DeleteNode(Node \* head, char \* BookName) { Node * pNode = NULL; if (head == NULL)//如果头指针为空 { printf("head == NULL!"); exit(0); } if (strcmp(BookName, head->BookName) == 0) { if (head->next != NULL) { pNode = head->next; free(head); return pNode; } else { printf("List NNLL!"); return NULL; } } if (strcmp(BookName, head->next->BookName) == 0); { if (head->next->next != NULL) { pNode = head->next->next; head->next = head; return head; } } while (head->next->next != NULL) { if (strcmp(BookName,head->next->next->BookName) == 0) { pNode = head->next->next->next; head->next->next = pNode; return head; } } } 最后修改:2023 年 06 月 25 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 2 如果觉得我的文章对你有用,请随意赞赏