C/C++基础(初级)

C/C++基础(初级) 所有程序均为Dev-CC是C的扩展所以初级部分C和C的知识点相同常量1、#define 宏常量 #define 常量名 常量值通常在文件上方定义表示一个常量2、const 修饰的变量 const 数据类型 常量名 常量值通常在变量定义前加关键字const修饰该变量为常量不可修改数据类型数据类型的意义是给变量分配合适的内存空间利用sizeof求出数据类型占用内存的大小。sizeof(数据类型/变量)整形short2个字节 int long4个字节 long long 8个字节long在windows中占4个字节在linux中占8个字节浮点型实型在使用单精度float4个字节和双精度double8个字节时默认情况下输出一个小数会显示6为有效数字。科学计数法float f2 3e2//表示3*10^2就是300float f3 3e-2;//表示3*0.1^2,就是0.03字符型char占用1个字节char ch a;//单引号里面只能有一个字符常见错误创建字符型变量时误将单引号写为双引号创建字符型变量时单引号内只能有一个字符查看字符的ASCII码char ch a;std::cout (int)ch std::endl;转义字符常用的转义字符1、换行符 \ncout Hello World\n;//换行2、反斜杠 \\,如果想输出一个反斜杠必须要两个反斜杠才行cout \\ endl;//输出为一个反斜杠3、水平制表符 \tcout aaa\thelloworld endl;//输出为aaa helloworld一个水平制表符有8个位置上面a占3个位置那么就还剩下5个空格好处是有对齐的效果。字符串型1、C风格字符串char str[] Hello World;cout str endl;注意事项定义规范char 字符串名[] Hello等号后面要用双引号2、C风格字符串string str2 hello world;//加头文件stringcout str2 endl;注意事项包含头文件string布尔数据booltrue 真本质是1false假本质是0bool flag true;cout flag endl;//输出1flag false;cout flag endl;//输出0占用内存为1个字节。bool只要是0就为假其余都代表真。数据的输入cin a;向a变量输入值运算符算数运算符1、、 -、 *、 /加减乘除注除数不能为02、%取模比如10%3结果为1 两个小数不能取模3、a前置递增相当于a a1,先加一再进行表达式运算a后置递增先进行表达式运算再加一4、----a前置递减与a--后置递减与同理赋值运算符、、-、*、/、%a b,相当于 a a b其余同理。比较运算符a b a等于ba b a不等于ba b a小于ba b a 大于ba b a小于等于ba b a大于等于b逻辑运算符a 非 若a为真则a为假a b 与 a与b都为真则为真至少一个为假则为假a || b 或 a与b都为假则为假至少一个为真则为真在C中只有0为假其余都为真程序流程结构程序流程结构包括顺序结构、选择结构和循环结构其中顺序结构是指按照顺序执行程序语句。选择结构if语句执行满足条件的语句。1、单行if语句语法if条件{条件满足执行的语句}条件为真则执行为假则不执行。2、多行if语句语法if条件{条件满足执行的语句} else {条件不满足执行的语句}3、多条件if语句语法if条件1{条件1满足执行的语句}else if条件2{条件2满足执行的语句}......else{条件都不满足的情况下执行的语句}4、嵌套if语句if(条件1){条件1满足执行的语句; if(条件2){条件2满足执行的语句} }//比大小#include iostreamusing namespace std;int main(){int A,B,C;cout 请输入三个数 endl;while(cin A B C){if(A B){if(A C){cout A最重为 A endl;}else{cout C最重为 C endl;}}else{if(B C){cout B最重为 B endl;}else{cout C最重为 C endl;}}}return 0;}三目运算符作用通过三目运算符实现简单的判断语法表达式1 表达式2 表达式3解释如果表达式1为真执行表达式2并返回表达式2的结果如果表达式1为假执行表达式3并返回表达式3的结果//将a与b比较a大于b返回a否则返回bint a 10,b 12,c 0;c a b ? a : b;cout c endl;在C中三目运算符返回的是变量可以继续赋值。a b ? a : b 100//ab则返回a并将100赋给aswitch语句语法switch(表达式){case 结果1执行语句breakcase 结果2执行语句breakcase 结果3执行语句break....default执行语句break//当没有符合的条件时执行这个语句}int main(){int score 0;cout 请给电影打分 endl;while(cin score){switch(score){case 10:cout 经典电影 endl;break;case 9:cout 经典电影 endl;break;case 8:cout 不错的电影 endl;break;case 7:cout 不错的电影 endl;break;case 6:cout 电影一般 endl;break;default :cout 烂片 endl;break;}}return 0;}switch特点缺点switch(表达式){} 表达式中判断时只能是整形或字符型不可以是一个区间优点结构清晰执行效率高循环结构while循环语句语法while(循环条件){循环语句} //循环条件为真执行循环语句为假不执行//猜测数字#include iostream#include cstdlibusing namespace std;int main(){int a rand()%100 1;//rand()%100 生成0~99的数字cout 请玩家输入1~100的数字 endl;int b 0;while(cin b){if(a b){cout 输入正确 endl;break;}else if(a b){cout 大了请继续输入 endl;}else if(a b){cout 小了请继续输入 endl;}}return 0;}do...while循环语句语法do{循环语句} while{循环条件}注意与while的区别是do...while会先执行一次语句//输出所有三位数的水仙花数int main(){int num 100;do{int a num % 10;//个位int b num % 100 / 10;//十位int c num / 100;//百位if(a*a*a b*b*b c*c*c num){cout num endl;}num 1;}while(num 1000);return 0;}for循环语句语法for起始表达式条件表达式末尾表达式{循环语句}for循环执行流程起始表达式只执行一次。再执行条件表达式若满足则执行循环语句最后执行末尾表达式如此往复直至条件表达式不满足为止。//敲桌子游戏1~100中含7或是7的倍数则输出敲桌子其余正常输出int main(){for(int i 1;i 100;i ){int a 0,b 0,c 0;if(i 0 i 9){if(i 7){cout 敲桌子! endl;}else{cout i endl;}}else if(i 10 i 99){a i % 10;//个位b i / 10;//百位if(a 7 || b 7 || i % 7 0){cout 敲桌子 endl;}else{cout i endl;}}elsecout i endl;}return 0;}当需要判断且没有循环次数时while更好用当没有判断且有循环次数时for更好用当没有循环次数时考虑是否可以通过判断来循环。嵌套循环乘法口诀表int main(){for(int i 1;i 9;i )//打印行数{for(int j 1;j i;j ) //打印列数列数小于等于行数{cout j * i i*j ;}cout endl;//打印完列数后换行}}跳转语句break语句作用用于跳出选择结构和循环结构break使用的情况1、出现在switch语句中作用是终止case并跳出switch2、出现在循环语句中作用是跳出当前的循环语句3、出现在嵌套循环中跳出最近的内层循环语句//嵌套循环中的breakint main(){for(int i 1;i 10;i ){for(int j 1;j 10;j ){if(j 5){break;//退出内层循环}cout *;}cout endl;}return 0;}代码结果因为到第5列时跳出循环所以只打印出4列continue语句作用在循环语句中跳过本次循环中余下未执行的语句继续执行下一次循环。解释continue一般用于循环语句中假设循环体有5段代码。for.....{代码1代码2if(....) continue//代码3代码4代码5}if条件不成立时代码1245都正常执行但是当if条件成立时就会运行continue语句则跳出本次循环所以代码45就不会执行再接着执行下一次循环。goto语句作用可以无条件跳转语句语法goto标记解释如果标记的名称存在执行到goto语句时会跳转到标记的位置。注不推荐使用goto语句会导致代码的可读性变差。int main(){cout 1、****** endl;cout 2、****** endl;goto FLAG;cout 3、****** endl;cout 4、****** endl;FLAG:cout 5、***** endl;return 0;}结果通过goto语句直接跳过了3和4的执行。数组特点1数组里面存放的都是相同类型的数据特点2连续内存存储一维数组定义方式1、数据类型 数组名[数组长度]2、数据类型 数组名[数组长度] {值1值2....}3、数组类型 数组名[ ] {值1值2....};注定义数组时必须有初始长度否组报错数组名用途1、可以统计整个数组在内存中的长度int main(){int arr2[] {1,2,3,4,5,6,7,8,9,10};cout sizeof(arr2) endl;return 0;}结果为40因为int型int占4个字节有10个int型的数据所以为4*10 402、可以获取数组在内存中的首地址int main(){int arr2[] {1,2,3,4,5,6,7,8,9,10};cout arr2 endl;cout arr2[0] endl;//看第一个元素的首地址return 0;}输出的结果相同数组首地址就是第一个元素的地址数组名相当于指针变量这篇文章中有关于数组与指针的讲解指针详解与应用https://mpbeta.csdn.net/mp_blog/creation/editor/147189700找最大值int main(){int arr[5] {470,365,420,410,440};int max 0;for(int i 0;i sizeof(arr)/4;i ){if(max arr[i]){max arr[i];}}cout 最大值为 max endl;return 0;}数组元素逆置//通用只需要更改数组的数据就可以直接使用int main(){int arr[] {34,22,13,25,16};int start 0;//起始下标int end sizeof(arr)/sizeof(arr[0])-1;//末尾下标while(start end){int temp arr[start];arr[start] arr[end];arr[end] temp; start;-- end;}for(int i 0;i sizeof(arr)/sizeof(arr[0]);i ){cout arr[i] endl;}return 0;}冒泡排序规律排序的总轮数 元素个数 - 1每轮对比次数 元素个数 - 排序轮数 - 1int main(){int arr[] {1,4,2,5,3,6,8,9,7,0};cout 排序前的结果 endl;for(int i 0;i sizeof(arr)/sizeof(arr[0]);i ){cout arr[i] ;}cout 排序后的结果 endl;for(int i 0;i sizeof(arr)/sizeof(arr[0]) - 1;i )//轮数{for(int j 0;j sizeof(arr)/sizeof(arr[0]) - i - 1;j )//对比的次数{if(arr[j] arr[j 1]){int temp arr[j];arr[j] arr[j 1];arr[j 1] temp;}}}for(int i 0;i sizeof(arr)/sizeof(arr[0]);i ){cout arr[i] ;}return 0;}二维数组定义方式1、数组类型 数组名[行数][列数]2、数组类型 数组名[行数][列数] {{数据1数据2}{数据3数据4}}3、数组类型 数组名[行数][列数] {数据1数据2数据3数据4}4、数组类型 数组名[ ][列数] {数据1数据2数据3数据4}注第二种定义方式更加直观提高代码的可读性。//第二种定义方式及遍历二维数组int main(){int arr1[2][3] {{1,2,3},{4,5,6}};for(int i 0;i 2;i )//行{for(int j 0;j 3;j )//列{cout arr1[i][j] ;}cout endl;}return 0;}二维数组数组名1、查看二维数组所占的内存空间int main(){int arr1[2][3] {{1,2,3},{4,5,6}};cout 二维数组占用的内存空间 sizeof(arr1) endl;cout 第一行所占用的内存空间 sizeof(arr1[0]) endl;cout 第一个元素占用的内存空间 sizeof(arr1[0][0]) endl;cout 二维数组行数为 sizeof(arr1) / sizeof(arr1[0]) endl;cout 二维数组列数为 sizeof(arr1[0]) / sizeof(arr1[0][0]) endl;return 0;}2、获取二维数组地址int main(){int arr1[2][3] {{1,2,3},{4,5,6}};cout arr1 endl; //0x6ffe00cout arr1[0][0] endl;//0x6ffe00说明首地址就是arr1[0][0]的地址cout arr1[0] endl;//第一行首地址,0x6ffe00cout arr1[1] endl;//第二行首地址,0x6ffe0creturn 0;}计算总分英语数学语文张三100100100李四9050100王五607080#include stringusing namespace std;int main(){string name[] {张三,李四,王五};int score[3][3] {{100,100,100},{90,50,100},{60,70,80}};for(int i 0;i 3;i ){int sum 0;for(int j 0;j 3;j ){sum score[i][j];cout score[i][j] ;}cout name[i] 的总分 sum endl;sum 0;cout endl;}return 0;}函数语法返回值类型 函数名参数列表{函数体语句return 表达式 //返回的表达式类型要与返回值类型一致}函数的调用intadd(int num1,int num2)//加法函数的定义{intsum num1 num2;return sum;}int main(){int sum add(10,12);//函数调用cout sum endl;return 0;}值传递void swap(int num1,int num2) //如果函数不需要返回值声明的时候可以写void{cout 交换前 endl;cout num1: num1 endl;cout num2: num2 endl;cout 交换后 endl;int temp num1;num1 num2;num2 temp;cout num1: num1 endl;cout num2: num2 endl;//return 返回值不需要时可以不写}int main(){int a 10;int b 20;swap(a,b); //当我们做值传递时函数的形参发生改变并不会影响实参cout a: a endl;cout b: b endl;//a与b的值并没有发生改变return 0;}函数常见的形式1、无参无返void test01() //无参无返{cout this is test01 endl;}2、有参无返void test02(int a) //有参无返{cout this is test02 a endl;}3、无参有返int test03() //无参有返{int a 10,b 20;cout this is test03 endl;return ab;}4、有参有返int test04(int a,int b) //有参有返{cout this is test04 endl;return ab;}函数的声明作用常用于分文件编写。告诉函数编译器名称及如何调用函数。函数的实际主体可以单独定义。函数的声明可以多次但是定义只能一次。一般将函数声明写在头文件下面。分文件编写步骤1、创建后缀名为.h的头文件2、创建后缀名为.cpp的源文件3、在头文件中写函数的声明4、在源文件中写函数的定义创建swap.cpp源文件并写函数的定义#include iostreamusing namespace std;void swap(int a,int b){cout a: a endl;cout b: b endl;int temp a;a b;b temp;cout a: a endl;cout b: b endl;}创建swap.h头文件并写函数的声明#ifndef __SWAP_H#define __SWAP_Hvoid swap(int a,int b);#endif指针指针详解与应用https://mpbeta.csdn.net/mp_blog/creation/editor/147189700结构体结构体属于用户自定义的数据类型是一些数据类型集合组成的一个类型允许用户存储不同的数据类型。语法struct 结构体名 { 结构体成员列表 }结构体创建变量的方式//自定义的数据类型struct student{int age;string name;int score;};1、struct 结构体名 变量名struct students1注在C中这种定义方式struct可以省略但是C中不可以省略但是在C中如果typedefstruct student StuStu s1;//先typedef重定义类型名称就可以直接用Stu命名变量当然C中也可以用typedef2、struct 结构体名 变量名 {成员1值成员2值}struct students1 { 23“lisi”98}3、定义结构体时顺便创建变量struct student{int age;string name;int score;}s1;注1、第一种和第二种用的比较多2、通过 . 访问结构体变量中的成员并赋值s1.age 23;s1.name name;s1.score 98;结构体数组作用将自定义的结构体放入到数组中方便维护语法struct 结构体名 数组名[元素个数] { { }{ }{ }...} //C中struct可以省略定义结构体struct student{int age;string name;int score;};创建结构体数组并赋值student stuArry[3] {{22,zhangsan,99},{23,lisi,98},{21,wangwu,100}};修改值stuArry[2].name liliu; //将数组中的wangwu改为liliustuArry[2].age 32; //将数组中的21改为32stuArry[2].score 60; //将数组中的100改为60遍历结构体数组for(int i 0;i 3;i ){cout 年龄 stuArry[i].age 姓名 stuArry[i].name 分数 stuArry[i].score endl;}结构体指针作用通过指针访问结构体的成员定义结构体struct student{int age;string name;int score;};创建学生结构体变量student s1 {23,zhangsan,99};通过指针指向结构体变量student *p s1; //注意指针类型要相同通过指针访问结构体变量的数据p-age 22;p-name niaoren;p-score 10;通过结构体指针访问结构体中的属性需要利用“-”结构体嵌套结构体作用结构体中的成员可以是另一个结构体例如每个老师辅导一个学员一个老师的结构体中记录一个学生的结构体struct student{int age;string name;int score;};struct teacher{int id;string name;int age;student Stu; //老师的结构体中嵌套了学生的结构体};创建老师初始化赋值teacher t {222,laowang,43,{23,lisi,98}};直接赋值teacher t;t.age 43;t.id 222;t.name laowang;t.Stu.age 22;t.Stu.name lisi;t.Stu.score 98;结构体做函数参数作用将结构体作为参数向函数中传递传递方式1、值传递 2、地址传递值传递struct student{int age;string name;int score;};void printStu(student s){cout 年龄: s.age 姓名 s.name 分数 s.score endl;}int main(){student s {23,zhangsan,89};printStu(s);return 0;}地址传递struct student{int age;string name;int score;};void printStu(student* s){cout 年龄: s-age 姓名 s-name 分数 s-score endl;}int main(){student s {23,zhangsan,89};printStu(s);return 0;}区别值传递不改变实参值地址传递改变实参数值传递引用属性用 . ,地址传递引用属性用 -结构体案例每名老师带3个学生总共2名老师需求为设计老师和学生的结构体在老师的结构体中有老师的姓名和一个存放3名学生的数组作为成员学生的成员有姓名和考试分数创建数组存放2名老师通过函数给每个老师及所带的学生赋值最终打印出老师数据和老师所带学生的数据#include iostream#include stringusing namespace std;struct student{string sName;int score;};struct teacher{string tName;student ArryS[3];//学生数组};void InitData(teacher *p, int len){for(int i 0;i len;i ){cout 输入老师姓名 endl;cin p[i].tName;cout 学生1的姓名和分数 endl;cin p[i].ArryS[0].sName p[i].ArryS[0].score;cout 学生2的姓名和分数 endl;cin p[i].ArryS[1].sName p[i].ArryS[1].score;cout 学生3的姓名和分数 endl;cin p[i].ArryS[2].sName p[i].ArryS[2].score;}}void printData(const teacher *t,int len){for(int i 0;i len;i ){cout 老师姓名: t[i].tName;cout 学生1姓名 t[i].ArryS[0].sName 学生1分数 t[i].ArryS[0].score endl;cout 学生2姓名 t[i].ArryS[1].sName 学生2分数 t[i].ArryS[1].score endl;cout 学生3姓名 t[i].ArryS[2].sName 学生3分数 t[i].ArryS[2].score endl;}}int main(){teacher ArryT[2];//创建老师数组int n sizeof(ArryT) / sizeof(ArryT[0]);InitData(ArryT,n);printData(ArryT,n);return 0;}枚举语法enum 枚举名{成员1成员2....}一般与switch结合使用enum Week{Mon, //值默认为0也可以手动调节如Mon 1则下面就从1开始累加Tue, //1Wed, //2Thu, //以此类推Fir,Sat,Sun};int main(){Week today Mon;cout today endl; //输出为0return 0;}在C11以后引入了枚举类也称强类型枚举关键字为enum class它强制我们在使用枚举值时必须带上枚举类名称,这样做有助于避免命名冲突。int main(){Week today Week::Mon;//带枚举类名称cout int(today) endl; //由于cout不认识枚举类所以需要强制转换return 0;}在cout时需要强制转换但在switch时不需要强制转换enum class Week{Mon,Tue,Wed,Thu,Fir,Sat,Sun};int main(){Week today Week::Mon;switch(today){case Week::Mon:cout 星期一 endl;break;case Week::Tue:cout 星期二 endl;break;case Week::Wed:cout 星期三 endl;break;case Week::Thu:cout 星期四 endl;break;case Week::Fir:cout 星期五 endl;break;case Week::Sat:cout 星期六 endl;break;case Week::Sun:cout 星期日 endl;break;}return 0;}结果为 星期一枚举值默认底层数据类型为int我们也可以手动指定为unsigned int和char等enum class Week unsigned int //unsigned int{Mon,Tue,Wed,Thu,Fir,Sat,Sun};应用定义三原色enum class color{Red,Green,Blue};在通过switch去进行指定的操作游戏中的物品分类enum class ItemType{Weapon, //武器Clothing, //服装Consumable //消耗品};