C++入门篇,每天复盘下所学的知识点,写下来加深下印象。

根据b站黑马的视频学习。

一、基础

1、注释

单号注释 // 注释的内容

多行注释 /* 注释的内容*/

2、变量

给内存空间起个名字,方便对这内存操作。

规则:数据类型 变量名 = 初值;

​ int a = 10;

创建变量必须赋初值,不然报错。

3、常量

后续不允许修改。

宏常量 #define 一般在代码文件最上面,即最前面几行。

​ #define 常量名 常量值 #define num1 10 没有分号。

const修饰的变量,和定义变量语法一样,就是加个const,使其成为常量。

​ const int a = 10;

#include<iostream>
using namespace std;//常量定义
//宏常量   #define
#define Day 7
int main() {//  Day = 14;   Day是常量,修改就报错。//const修饰的变量const int month = 12;//month = 24; //const修饰的变量也是常量,修改报错cout << "一周有:"<<Day << "天" << endl;cout << "一年有:" << month << "月" << endl;system("pause");return 0;}

一些解释

1、#include用于引用位于其他文件中的代码

​ C++标准库文件后面就用<>,其他文件就()

2、using namespace std; 让代码更简洁。

​ 提示编译器在此文件中使用C++标准库中内容,不然,库中的每个关键字都必须用std::开头表示范围

​ 如 std::cout

3、cout关键字,用于打印输出。

​ <<运算符,提示编译器输入右侧内容。

4、endl关键字和Enter建类似,换行。

一般建议在" "里面加\n表示换行,因为endl会刷新缓冲区,影响程序的性能,endl在非常小的应用可以增加代码可读性。

5、main()必须要有,相当于程序的入口。

4、关键字

C++内置的标识符,定义常量变量时不可用这些,具体后面会慢慢了解。

asm do if return typedef
auto double inline short typeid
bool dynamic_cast int signed typename
break else long sizeof union
case enum mutable static unsigned
catch explicit namespace static_cast using
char export new struct virtual
class extern operator switch void
const false private template volatile
const_cast float protected this wchar_t
continue for public throw while
default friend register true
delete goto reinterpret_cast try

5、标识符

字面意思,一个标记符号,来命名常量、变量,命名最好要做到见到就知道含义即代表什么。

规则:1,不能是关键字。

​ 2,字母、数字、下划线组成,首字母必须是字母或者下划线。

​ 3,标识符区分大小写。

二、数据类型

C++规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存

数据类型存在意义:给变量分配合适的内存空间

1、整型

整型可有四种,short、int、long、long long,所占字节个数不同,表示数的范围不同。

数据类型 占用空间 取值范围
short(短整型) 2字节 (-215 ~ 215-1)
int(整型) 4字节 (-231 ~ 231-1)
long(长整形) Windows为4字节,Linux为4字节(32位),8字节(64位) (-231 ~ 231-1)
long long(长长整形) 8字节 (-263 ~ 263-1)

2、sizeof关键字

可以求出数据类型所占内存空间大小。

语法,sizeof(数据类型/变量名)

 short num1 = 10;cout << "short占内存:" << sizeof(short) << endl;cout << "short占内存:" << sizeof(num1) << endl;

3、实型(浮点型)

分为float和double两种,所占内存空间不同,表示有效数字位数不同。

不过,一般默认输出6位有效数字(超过6位时)。

对于float,需要在赋值的后面加个f,告诉编译器这个是float型的数据,因为一般编译器会用double。

数据类型 占用空间 有效数字范围
float 4字节 7位有效数字
double 8字节 15~16位有效数字
 float f1 = 3.14159265354f; //默认为double,加个f就转为floatcout << "f1 =" << f1 << endl;double d1 = 3.14159265354;cout << "d1 =" << d1 << endl;
//输出均为3.14159

科学计数法表示浮点数

3e2 // 3*102

3e-2 //3*10-2

4、字符型

用于显示单个字符,定义时用单引号。

语法: char 变量名 = ‘字符’;

​ char ch = ‘a’;

字符变量占一个字节

字符变量不是将字符放在内存中存储,而是将其对应的ASCII码放在内存中。

#include<iostream>
using namespace std;int main() {//1 变量创建方式char ch = 'A';cout << ch << endl;//2 所占内存cout<<sizeof(char) << endl;//3 常见错误//char ch2 = "b";//创建字符要单引号//char ch3 = 'dswdr';//单引号只能一个字符//4 ASCII//a-97  A-65   大+32=小cout << (int)ch << endl;//转为十进制的数字system("pause");return 0;
}

ASCII 码大致由以下两部分组成:

  • ASCII 非打印控制字符: ASCII 表上的数字 0-31 分配给了控制字符,用于控制像打印机等一些外围设备。
  • ASCII 打印字符:数字 32-126 分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。

记住 A 65 a 97 大写+32=小写

5、转义字符

用来显示不能显示出来的ASCII字符,目前主要先了解

\\  \t   \n
#include<iostream>
using namespace std;int main() {//换行 \ncout << "hello \n";//返斜杠 \\cout<<"\\"<<endl;//水平制表  \t 作用,整齐输出数据。cout << "123456789\thello" << endl;// \t占8个空间,连前面的一起,比如1234\t,这样就剩下4个空格了,123 剩5个空格。//这个会先123456789,9后面跟7个空格再hellosystem("pause");return 0;
}

6、字符串型

用于输出一串字符。

有两种风格:

  • C语言风格:char 变量名[] = “字符串”;
  • C++风格:string 变量名 = “字符串”;

C++风格,需加一个头文件 #include < string > ,不然会报错,不过我用的vs2022没有报错,建议加上,使代码有好的可移植性。

#include<iostream>
using namespace std;
#include<string>  //使用C++风格的字符串时要加此头文件int main() {//C风格     1、要加[]在字符名后,  2、等号后面双引号char str[] = "hello";cout << "str =" << str << endl;//C++风格    1、包含头文件string str2 = "hello world";cout << "str2 =" << str2 << endl;  //加头文件,为可移植性system("pause");return 0;
}

7、bool类型

表示真假。bool只有两个值

  • true—真 1
  • false—假 0

其实除了0外的所有数都是真。

bool占一个字节内存空间。

#include<iostream>
using namespace std;int main() {//创建boolbool flag = true; //true为真 1cout << flag << endl;flag = false; //flase 为假 0cout << flag << endl;//查看内存空间cout << "bool 空间" << sizeof(bool) << endl;system("pause");return 0;}

8、数据输入

从键盘获取数据。

语法:cin << 变量

#include<iostream>
using namespace std;int main() {//cin >> 变量//整型int a = 0;cout << "a =" << a << endl;cout << "请给a赋值:" << endl;cin >> a;cout << "a =" << a << endl;//浮点float f = 3.14f;cout << "f = " << f << endl;cout << "f赋值:" << endl;cin >> f;cout << "f = " << f << endl;//字符char ch = 'a';cout << "ch =" << ch << endl;cout << "ch赋值:" << endl;cin >> ch;cout << "ch = "<< ch << endl;//字符串string str = "hello";cout << "str =" << str << endl;cout << "str赋值:" << endl;cin >> str;cout << "str =" << str << endl;//bool   //赋值用0 1不是输入true或flase   0假  其他都为真bool flag = false;cout << "flag= " << flag << endl;cout << "赋值:" << endl;cin >> flag;cout << "flag= " << flag << endl;system("pause");return 0;
}

三、运算符

1、算术运算符

  • 加减乘除。

    • 除 / 就是取整。

    • 整数相除,结果是整数;有一个是小数,结果为小数,能整除还为整数。

    •  double d1 = 0.5;double d2 = 0.22;cout << d1 / d2 << endl; //运算结果可以是小数。double d3 = 1;cout << d2 / d3 << endl; //也为小数
      
  • 取模运算 %

    • 就是取余数

    • 注意:两小数不能进行取模运算。

    •     //两小数不可取模,会报错。double d01 = 3.14;double d02 = 1.1;cout << d01 % d02 << endl;
      
  • 自增自减运算

    • 分为前置和后置,不过都是加1,主要区别在于应用于表达式中。

    • //自增自减int a = 10;int b = 10;    int c = 0;//前置递增a++; //a+1cout << "a = " << a << endl;                 //11//后置递增a = 10;++a;    //a+1                                  //11cout << "a = " << a << endl;//两者区别,在表达式中有。a = 10;c = a++ * b;   //先表达式运算,在进行++操作cout << "a = " << a << endl;                  //11cout << "c = " << c << endl;                   //100a = 10;c = ++a * b;    //先进行++,在进行表达式操作cout << "a = " << a << endl;                  //11        cout << "c = " << c << endl;                   //110
      
    • 减同理

2、赋值运算符

表达式的值赋值给变量。

 // =int  a = 10;a = 100;cout << "a = " << a << endl;// +=a = 10;a += 2;        //a=a+2cout << "a = " << a << endl;// -=a = 10;a -= 2;        //a=a-2cout << "a = " << a << endl;// *=a = 10;a *= 2;     //a=a*2cout << "a = " << a << endl;// /=a = 10;a /= 2;     //a=a/2cout << "a = " << a << endl;// %=a = 10;a %= 2;     //a=a%2cout << "a = " << a << endl;

3、比较运算符

用于表达式比较,返回一个真值或者假值。

// 返回 真值或假值int a = 10;int b = 20;// ==   !=cout << (a == b) << endl; cout << (a != b) << endl;//  <   <=     cout << (a <= b) << endl;cout << (a <= b) << endl;//  >   >=cout << (a > b) << endl;cout << (a >= b) << endl;

4、逻辑运算符

  • 与 && 全真为真
  • 或|| 有真就真
  • 非 ! 取反
 //返回真假 int a = 10;int b = 10;// !非 取反cout << !a << endl;       //0cout << !!a << endl; //1//  && 与cout << (a&&b) << endl;  //1a = 0;cout << (a && b) << endl; //0//  || 或cout << (a || b) << endl;    //1b = 0;cout << (a || b) << endl; //0

四、程序流程结构

1、选择结构

1.1 if语句

满足则执行。if后面不加分号。

if(条件1){ 条件1满足执行的语句 }else if(条件2){条件2满足执行的语句}... else{ 都不满足执行的语句}

嵌套if语句。比较A、B、C大小

 int a = 10;int b = 20;int c = 30;if (a > b) {if (a > c)cout << c << endl;elsecout << a << endl;}else {if (b > c)cout << b << endl;elsecout << c << endl;}

1.2 三目运算符

表达式1 ? 表达式2 : 表达式3

1为真执行2,反返回2的结果,否则执行3,返回3的结果。

1.3 switch语句

switch(表达式){case 结果1:执行语句;break;case 结果2:执行语句;break;...default:执行语句;break;}

switch表达式类型只能是整型或者字符型

case后加break,为程序不会一直执行下面的,特殊情况下除外可不加

2、循环结构

2.1 while循环

while(循环条件){循环语句}

循环条件为真就一直循环。所以程序需要跳出循环的出口,不然会死循环。

2.2 do while循环

do{循环语句}while(循环条件)

与while区别,就是不论是否满足条件,都会执行一次循环语句。

2.3 for循环

for(起始表达式;条件表达式;末尾循环体) { 循环语句; }

for循环内表达式用分号相隔。

语句执行顺序, for( 0 ; 1 ; 3 ) { 2 }

for循环内的变量是就近原则。不过为了程序代码理解,一般不会使用相同名称变量。

  for (int i = 0; i < 10; i++){for (int i = 0; i < 10; i++){cout << i << " ";        //这个i是指最近的那个}cout << endl;}

3、跳转语句

3.1 break语句

指跳出当前循环或选择结果。

  • switch语句中,终止case并跳出switch
  • 循环语句,跳出当前循环
  • 嵌套循环,跳出最内层的循环

3.2 continue语句

跳过后面的语句,执行下一条循环语句。

3.3 goto语句

无条件跳转语句

goto 标记; 标记 :

如果标记存在,执行到标记位置。

int main() {cout << "1" << endl;goto FLAG;cout << "2" << endl;cout << "3" << endl;cout << "4" << endl;FLAG:cout << "5" << endl;system("pause");return 0;
}

goto 语句最好不用,当然可用少量,跳的太多代码不易阅读。

个人认为,goto语句对于分析mips代码有很大帮助,当然只是个题外话。

五、数组

数组就是相同数据类型元素的集合,在一片连续的内存位置中。

1、一维数组

1.1 定义方式

数据类型 数组名 [数组长度];

数据类型 数组名 [数据长度]={数据};

数据类型 数组名 []={数据};

1.2 数组名用途

  • 统计数组在内存中的长度
  • 获取数组在内存中首地址

数组名是常量,不能进行赋值操作

//一维数组定义//1、数据类型 数组名[数组长度]int arr[3];arr[0] = 0;arr[1] = 1;arr[2] = 2;for (int i = 0; i < 3; i++) {cout << arr[i] << endl;}//2、数据类型 数组名[数组长度]= {值1,值2....}int arr2[3] = { 20,21,22 };for (int i = 0; i < 3; i++) {cout << arr2[i] << endl;}//缺少的用0来代替。int arr2_1[5] = { 20,21,22 };for (int i = 0; i < 5; i++) {cout << arr2_1[i] << endl;}//3、数据类型 数据名[]={值1,值2....};int arr3[] = { 30,31,32,33,34 };for (int i = 0; i < 5; i++) {cout << arr3[i] << endl;}//注意:数组下标用0开始//数组名的作用。//1、统计整个数组在内存中的长度cout <<"arr数组长度(所占内存空间):" << sizeof(arr) << endl;cout << "arr数组每个元素所占内存空间数:" << sizeof(arr[0]) << endl;cout << "arr数组长度:" << sizeof(arr) / sizeof(arr[0]) << endl;//2、获取数组在内存中首地址cout << "数组的首地址为:" << &arr << endl;cout << "数组第一个元素的地址为:" << &arr[0] << endl;cout << "数组第二个元素地址为:" << &arr[1] << endl;//通过int强制转换,将16进制转为10进制。cout << "数组第三个元素首地址为(10进制表示):" << (int)&arr[2] << endl;//注意:数组名是常量,不能赋值//arr=10;//报错

1.3 案例——数组逆置

int arr[5] = { 1,2,3,4,5 };cout << "逆置前:" << endl;for (int i = 0; i < 5; i++) {cout << arr[i] << endl;}//1、记录起始结束下标位置int start = 0;int end = sizeof(arr) / sizeof(arr[0]) - 1;//2、起始结束元素互换,起始加1,结束减1int temp = 0;while (start < end) {temp = arr[start];arr[start] = arr[end];arr[end] = temp;start++; end--;}cout << "逆置后为:" << endl;for (int i = 0; i < 5; i++) {cout << arr[i] << endl;}

1.4 案例——冒泡排序

 //排序总轮数=元素个数-1;//每轮对比次数=元素个数-当前排序轮数-1;int arr[9] = { 9,8,7,6,5,4,3,2,1 };cout << "排序前:" << endl;for (int i = 0; i < 9; i++) {cout << arr[i] << "  ";}cout << endl;for (int i = 0; i < 9 - 1; i++) {for (int j = 0; j < 9 - 1 - i; j++) {if (arr[j + 1] < arr[j]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}//排序后cout << "排序后:" << endl;for (int i = 0; i < 9; i++) {cout << arr[i] << "  ";}cout << endl;

2、二维数组

2.1 定义

数据类型 数组名[行数][列数];

数据类型 数组名[行数][列数]={{},{},{}...}; 建议使用此方法,代码更直观

数据类型 数组名[行数][列数]={数据...};

数据类型 数组名[][列数]={数据...};

2.2 数组名用途

  • 查看二维数组所占内存空间。
  • 获取二维数组首地址。
//二维数组定义,建议第二种。//1、数据类型 数组名[行数][列数];int arr[3][3];arr[0][0] = 1;arr[0][1] = 2;arr[0][2] = 3;arr[1][0] = 4;//后面类似。//2、数据类型 数组名[行数][列数]={{数据元素},{数据元素},{数据元素}};int arr2[3][3] = {{1,2,3},{4,5,6},{7,8,9}};for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {cout << arr2[i][j] << "\t";}cout << endl;}//3、数据类型 数组名[行数][列数]={数据,数据,数据...};int arr3[3][3] = { 1,2,3,4,5,6,7,8,9 };for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {cout << arr3[i][j] << "\t";}cout << endl;}//已经初始化,可以省略行数。//4、数据类型 数组名[][列数]={数据,数据,数据...};int arr4[][3]= { 1,2,3,4,5,6,7,8,9 };for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {cout << arr4[i][j] << "\t";}cout << endl;}//数组名作用,类一维//1、获取二维数组的内存空间cout << "二维数组的大小为:" << sizeof(arr) << endl;cout << "二维数组每行的大小为:" << sizeof(arr[0]) << endl;cout << "二维数组单个元素的大小为:" << sizeof(arr[0][0]) << endl;cout << "二维数组行数为:" << sizeof(arr) / sizeof(arr[0]) << endl;cout << "二维数组的列数为:" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;//2、得到二维数组的首地址cout << "二维数组的首地址为:" << arr << endl;cout << "二维数组的第一行首地址为:" << arr[0] << endl;//这个这为单个元素故需要用&取地址符号。cout << "二维数组的第一个元素的首地址为:" << &arr[0][0] << endl;cout << "二维数组的第二行首地址为:" << arr[1] << endl;cout << "二维数组的第三行首地址为:" <<(int) arr[2] << endl;

2.3 二维数组案例——输出每行和

int scores[3][3] = {{100,100,100},{90,50,100},{60,70,80}};string name[3] = { "张三","李四","王五" };for (int i = 0; i < 3; i++) {int sum = 0;for (int j = 0; j < 3; j++) {sum += scores[i][j];} cout << name[i] << "的总分为:" << sum << endl;}

六、函数

函数,就是将常用的代码封装起来,减少重复代码。

1、函数定义

返回值类型 函数名 (参数列表)
{函数体语句return表达式;}
  • 返回值类型 :一个函数可以返回一个值。在函数定义中
  • 函数名:给函数起个名称
  • 参数列表:使用该函数时,传入的数据
  • 函数体语句:花括号内的代码,函数内需要执行的语句
  • return表达式: 和返回值类型挂钩,函数执行完后,返回相应的数据

2、调用

使用定义好的函数。

函数名(参数)

3、值传递

就是将实参的数值传递给形参,形参改变,实参不会发生改变。

#include<iostream>
using namespace std;//定义函数,   函数类型 函数名(参数列表){函数体语句   return 表达式}
//两个数相加函数
int add(int num1, int num2) {//形参int sum = num1 + num2;return sum;
}//值传递,调用函数将实参的数值传递给形参。
//值传递,形参发生改变,实参不会受到影响。//交换数字函数
void swap1(int num1, int num2) {cout << "交换前为:" << endl;cout << "num1 = " << num1 << "\t";cout << "num2 = " << num2 << "\t";cout << endl;int temp = num1;num1 = num2;num2 = temp;cout << "交换后为:" << endl;cout << "num1 = " << num1 << "\t";cout << "num2 = " << num2 << "\t";cout << endl;
}int main() {int a = 10; int b = 20;//调用add函数       函数名(参数列表)int c = add(a, b);//实参cout << "c = " << c << endl;cout << "a = " << a << "\t";cout << "b = " << b << "\t";cout << endl;swap1(a, b);cout << "a = " << a << "\t";cout << "b = " << b << "\t";cout << endl;system("pause");return 0;
}

4、函数常见形式

  1. 无参无返
  2. 有参无返
  3. 无参有返
  4. 有参有返

5、函数的声明

告诉编译器函数名称以及如何调用函数。

  • 函数的声明可以多次,但是函数的定义只能有一次

一般用于定义的函数写在main函数后面,如果这样没有声明,程序会报错,因为程序是按代码一行一行执行的。或者用于分文件编写的函数中。

//声明可以多次,定义只能一次
//声明
int max(int a, int b);
int max(int a, int b);int main() {int a = 100;int b = 200;cout << max(a, b) << endl;system("pause");return 0;
}
//定义
int max(int a, int b)
{return a > b ? a : b;
}

6、函数分文件编写

为了让代码结构更加清晰。

步骤:

  1. 创建后缀名为.h的头文件
  2. 创建后缀名为.cpp的源文件
  3. 在头文件中写函数的声明
  4. 在源文件中写函数的定义

示例:

//swap.h文件
#include<iostream>
using namespace std;//实现两个数字交换的函数声明
void swap(int a, int b);
//swap.cpp文件
#include "swap.h"    //使用此将两个文件联系起来,双引号表示自己定义的头文件。void swap(int a, int b)
{int temp = a;a = b;b = temp;cout << "a = " << a << endl;cout << "b = " << b << endl;
}
//main函数文件
#include<iostream>
using namespace std;
#include "swap.h" //同样使用此,联系起来
int main() {int a = 100;int b = 200;swap(a, b);system("pause");return 0;
}

七、指针

指针就是能通过其间接访问内存空间。内存编号从0开始,十六进制表示。指针变量保存地址

1、定义和使用

定义:数据类型 * 指针变量名;

此变量存的是地址,也是一个数。&也可以访问内存。

可以用* 也即是解引用操作,来操作指针指向的内存里的内容。

 //指针记录变量的地址。//指针定义  数据类型 * 指针变量名;int a = 10;int* p;p = &a;cout << "a的地址为:" << &a << endl;cout << "a的地址为:" << p << endl;//指针的使用 //解引用的方式找到指针指向的内存//指针前加 * 代表解引用,找到指针指向内存中的数据。   *p = 1000;cout << "a = " << a << endl;cout << "*p = " << *p << endl;//指针所占内存空间//在32位OS下,指针占4个字节空间大小,不论数据类型.X86//63位,占8个字节空间大小。X64cout << "sizeof(int *) = " << sizeof(int*) << endl;cout << "sizeof(float *) = " << sizeof(float*) << endl;cout << "sizeof(double *) = " << sizeof(double*) << endl;cout << "sizeof(char *) = " << sizeof(char*) << endl;

所占内存空间根据OS而定。

2、空指针和野指针

空指针:指向内存编号为0的空间,用来初始化指针变量。

空指针的内存是不能够被访问的

野指针:指针变量指向非法的内存空间。这片内存空间并非自己定义,不知里面内容。

//空指针,指针变量指向地址变量为0的空间int* p = NULL;//空指针访问会报错,因为不是自己定义的空间。0~255为系统占用的内存,不允许用于访问//cout << *p << endl;//野指针,指针变量只想非法的内存空间。int* q = (int*)0x0321;//访问野指针会报错,因为野指针所指的内存空间并非自己所创建的。这块区域存了什么自己不知道。//cout << *q << endl;

3、const修饰的指针

有三种,修饰指针,修饰常量,两者都修饰。

 int a = 10;int b = 10;//const修饰指针,常量指针const int* p = &a;//指针指向的值不能够修改,指向可修改//*p = 20; 错误p = &b;//const修饰常量,指针常量int* const p2 = &a;//指针指向的值可以修改,指向不能够修改//p2 = &b; 错误*p2 = 100;//const修饰指针和常量const int* const p3 = &a;//指针指向的值,和指针指向都不能修改//*p3 = 100;    错误//p3 = &b;   错误

4、指针和数组

利用指针访问数组中的元素。

对数组的数组名取指就是数组首地址

 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;//arr就是数组的首地址//访问数组首个元素cout << "数组的第一个元素为:" << arr[0] << endl;cout << "利用指针看数组的第一个元素为:" << *p << endl;p++;cout << "利用指针看数组的第二个元素为:" << *p << endl;p = arr;for (int i = 0; i < 10; i++) {cout << *p << endl;p++;}

5、指针和函数

指针地址传递,和值传递不同,可以改变实参的数值。

void swap01(int a, int b) {int temp = a;a = b;b = temp;cout << "swap01 a = " << a << endl;cout << "swap01 b = " << b << endl;}void swap02(int* c, int* d) {int temp = *c;*c = *d;*d = temp;cout << "swap02 c = " << *c << endl;cout << "swap02 d = " << *d << endl;
}int main() {int a = 10;int b = 20;int c = 30;int d = 40;//1.值传递,swap01函数swap01(a, b);cout << "main a = " << a << endl;cout << "main b = " << b << endl;//2.地址传递,swap02函数,改变实参的值swap02(&c,&d);  //地址传递cout << "main c = " << c << endl;cout << "main d = " << d << endl;

6、案例——指针函数数组

**案例描述:**封装一个函数,利用冒泡排序,实现对整型数组的升序排序

例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };

#include<iostream>
using namespace std;//冒泡排序函数
void bubbleSort(int* arr, int len) {for (int i = 0; i < len - 1; i++) {for (int j = 0; j < len - 1 - i; j++) {//如果j比j+1大则交换if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;             }}}
}//打印数组函数
void printArray(int* arr, int len) {for (int i = 0; i < len ; i++) {cout << arr[i] << endl;}
}
//数组名传入函数作为参数时,被退化为指向首元素的指针。
int main() {//构建数组int arr[10]= { 4,3,6,9,1,2,10,8,7,5 };int len = sizeof(arr) / sizeof(arr[0]);//cout << len << endl;bubbleSort(arr, len);//arr就是数组首地址,地址传递。printArray(arr, len);system("pause");return 0;
}

八、结构体

1、定义和使用

结构体就是用于自定义的数据类型,在一个结构体中可以有不同的数据类型。

struct 结构体名{成员变量列表};

创建结构体变量方式:

  • struct 结构体名 变量名
  • struct 结构体名 变量名={成员值…};
  • 在定义结构体时就创建变量。

创建结构体时,struct是关键字,不能省略。

创建变量时,struct可以省略。

结构体变量通过"."访问成员。

#include<iostream>
using namespace std;
#include<string>//定义 struct 结构体名 {结构体成员列表};
struct student          //定义结构体的关键字是struct,不可省去。
{//成员列表string name;int age;int score;
}s3;    //3.定义结构体时顺便定义变量,不过此法一般不用。int main() {//定义结构体成员变量//1.struct 结构体名 结构体成员变量名struct student s1;  //创建变量时,可以省去structs1.name = "张三";s1.age = 18;s1.score = 100;//访问结构体成员变量时,用.访问cout << "姓名:" << s1.name << " 年龄:" << s1.age << " 成绩:" << s1.score << endl;//2.struct 结构体名 变量名={成员列表};struct  student s2 = {"李四",20,90};cout << "姓名:" << s2.name << " 年龄:" << s2.age << " 成绩:" << s2.score << endl;//3.定义结构体时定义变量s3.name = "王五";s3.age = 21;s3.score = 80;cout << "姓名:" << s3.name << " 年龄:" << s3.age << " 成绩:" << s3.score << endl;system("pause");return 0;
}

2、结构体数组

将结构体放入数组中方便后续维护。

struct 结构体名 数组名[元素个数]={ {} , {} , {} ...};

#include<iostream>
using namespace std;
#include<string>struct student
{string name;int age;int score;
};int main() {//结构体数组,将自定义的结构放入数组中,方便维护。//struct 结构体名 数组名[元素个数]={{},{},{}...};struct student arr[3] = {{"张三",18,100},{"李四",20,90},{"王五",22,80}};for (int i = 0; i < 3; i++) {cout << "姓名:" << arr[i].name << " 年龄:" << arr[i].age << " 成绩:" << arr[i].score << endl;}system("pause");return 0;
}

3、结构体指针

通过指针访问结构体中成员。->操作符

 //结构体指针,使用指针访问结构体成员。struct student s1 = { "张三",18,100 };struct student* p = &s1;//使用->访问成员变量p->score = 90;cout << "姓名:" << p->name << " 年龄:" << p->age << " 成绩:" << p->score << endl;

4、结构体嵌套

结构体的成员时另一个结构体。

如,每个老师一个学生,一个老师结构体中,记录一个学生的结构体

#include<iostream>
using namespace std;
#include<string>struct student
{string name;int age;int score;
};struct teacher {int id;string name;int age;struct student stu;    //子结构体,学生
};int main() {struct teacher t1;t1.id = 1000;t1.age = 30;t1.name = "张三";t1.stu.name = "李四";t1.stu.age = 18;t1.stu.score = 99;cout << "教师编号:" << t1.id << " 教师年龄:" << t1.age << " 教师姓名:" << t1.name << endl;cout << "辅导学生姓名:" << t1.stu.name << " 年龄:" << t1.stu.age << " 成绩:" << t1.stu.score << endl;system("pause");return 0;
}

5、结构体做函数参数

同样有值传递和地址传递两种方式。

#include<iostream>
using namespace std;
#include<string>struct student
{//成员列表string name;  int age;      int score;
};//值传递
void printStudent(student stu) {stu.age = 30;cout << "子函数 姓名:" << stu.name << " 年龄:" << stu.age << " 成绩:" << stu.score << endl;}
//地址传递
void printStudent1(student * stu) {stu->score = 90;cout << "子函数 姓名:" << stu->name << " 年龄:" << stu->age << " 成绩:" << stu->score << endl;}
//修改结构体中的值就用地址传递,否则就值传递。
int main() {student s1 = { "张三",18,100 };printStudent(s1);cout << "main函数 姓名:" << s1.name << " 年龄:" << s1.age << " 成绩:" << s1.score << endl;student s2 = { "李四",20,99 };printStudent1(&s2);cout << "main函数 姓名:" << s2.name << " 年龄:" << s2.age << " 成绩:" << s2.score << endl;system("pause");return 0;
}

6、结构体中使用const

使用const就是为了在函数中防止修改了成员变量值。

//const使用场景
void printStudent(const student *stu) //加const防止函数体中的误操作
{//stu->age = 100; //操作失败,因为加了const修饰cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;}

7、结构体案例1

案例描述:

学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下

设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员

学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值

最终打印出老师数据以及老师所带的学生数据。

 #include<iostream>
using namespace std;
#include<string>struct student
{string name;      int score;
};
struct teacher1
{string name;student sArray[5];
};void allocateSpace(teacher1 tArray[], int len) {string tName = "教师";string sName = "学生";string nameSeed = "ABCDE";for (int i = 0; i < len; i++) {tArray[i].name = tName+nameSeed[i];for (int j = 0; j < 5; j++) {tArray[i].sArray[j].name = sName + nameSeed[j];tArray[i].sArray[j].score = rand() % 61 + 40;//40~100分}}
}void printTeachers(teacher1 tArray[], int len) {for (int i = 0; i < len; i++) {cout << tArray[i].name << endl;for (int j = 0; j < 5; j++) {cout << "姓名:" << tArray[i].sArray[j].name <<" 成绩:" << tArray[i].sArray[j].score << endl;}}}int main() {srand((unsigned int)time(NULL));//随机数种子,跟随系统时间teacher1 tArray[3];int len = sizeof(tArray) / sizeof(tArray[0]);//cout << len << endl;allocateSpace(tArray, len);printTeachers(tArray, len);system("pause");return 0;
}

8、案例2

案例描述:

设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。

通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。

#include<iostream>
using namespace std;
#include<string>struct hero
{string name;int age;string sex;
};void bubbleSort(hero hArray[],int len) {for (int i = 0; i < len-1; i++) {for (int j = 0; j < len - 1 - i; j++) {if (hArray[j].age > hArray[j + 1].age) {hero temp = hArray[j];hArray[j] = hArray[j + 1];hArray[j + 1] = temp;}}}}void printHero(hero hArray[],int len) {for (int i = 0; i < len; i++) {cout << "姓名:" << hArray[i].name << " 年龄:" << hArray[i].age << " 性别:" << hArray[i].sex << endl;}
}int main() {struct hero hArray[5] = {{"刘备",23,"男"},{"关羽",22,"男"},{"张飞",20,"男"},{"赵云",21,"男"},{"貂蝉",19,"女"}, };int len = sizeof(hArray) / sizeof(hArray[0]);for (int i = 0; i < len; i++) {cout << "姓名:" << hArray[i].name << " 年龄:" << hArray[i].age << " 性别:" << hArray[i].sex << endl;}cout << "--------------------------------------------" << endl;bubbleSort(hArray, len);printHero(hArray, len);system("pause");return 0;
}

如果你看到这,恭喜你,马上就可以出新手村了,新手村的boss挑战请看下一节:

通讯录管理系统

新手村——C++入门篇相关推荐

  1. 女友问粉丝过万如何庆祝,我发万字长文《保姆级大数据入门篇》感恩粉丝们支持,学姐|学妹|学弟|小白看了就懂

    2021大数据领域优质创作博客,带你从入门到精通,该博客每天更新,逐渐完善大数据各个知识体系的文章,帮助大家更高效学习. 有对大数据感兴趣的可以关注微信公众号:三帮大数据 目录 粉丝破万了 新星计划申 ...

  2. Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:没有了 下一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置 前言 V1.x版本终于到来了.本次 ...

  3. SQL注入漏洞全接触--入门篇

    随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进 ...

  4. Symbian开发系列 - 入门篇

    要开始我的Symbian开发之旅了, 先收集一些相关资料,如Symbian概述, 开发平台搭建, 参考书籍与网络资源. [基础] 什么是Symbian 学习Symbian的基本概念  Symbian操 ...

  5. 《Ansible权威指南 》一 第一篇 Part 1 基础入门篇

    本节书摘来自华章出版社<Ansible权威指南 >一书中的第1章,第1.1节,李松涛 魏 巍 甘 捷 著更多章节内容可以访问云栖社区"华章计算机"公众号查看. 第一篇 ...

  6. 【SSRS】入门篇(二) -- 建立数据源

    原文:[SSRS]入门篇(二) -- 建立数据源 通过 [SSRS]入门篇(一) -- 创建SSRS项目 这篇,我们建立了一个SSRS项目: 接下来,我们以 AdventureWorks2012 示例 ...

  7. Python从入门到精通 - 入门篇 (下)

    上一讲回顾:Python从入门到精通 - 入门篇 (上) 接着上篇继续后面两个章节,函数和解析式. 4 函数 Python 里函数太重要了 (说的好像在别的语言中函数不重要似的).函数的通用好处就不用 ...

  8. Python从入门到精通 - 入门篇 (上)

    转载自微信公众号:王的机器 0 引言 微信公众号终于可以插代码了,Python 可以走一波了.首先我承认不是硬核搞 IT 的,太高级的玩法也玩不来,讲讲下面基本的还可以,之后带点机器学习.金融工程和量 ...

  9. matplotlib中文文档_python绘图库——Matplotlib及Seaborn使用(入门篇1)

    在数据分析过程中,数据及模型可视化是无可避免的,同时这也是展示我们数据分析成果的最佳方式.因此,熟悉掌握绘图库的使用,对精进我们的数据分析技能起着不可替代的作用. 今天,我们就来了解一下python强 ...

最新文章

  1. 开发工具之Eclipse快捷键
  2. 对我国6G早期研究布局的几点建议
  3. python密码学编程pdf-Python密码学编程PDF电子书免费下载
  4. hdu2133: What day is it
  5. 2022年最值得学习的 5 种编程语言,你有在学习吗?
  6. log nginx 客户端请求大小_nginx log记录请求响应时间
  7. Microsoft Visual Studio下编译缺少头文件unistd.h解决办法
  8. js学习总结----简单的动画库封装tween.js
  9. linux lamp框架,LAMP架构协同应用的实例——phpMyAdmin
  10. mysql-5.5.17-win64 安装方法
  11. 继承求不同形状图形的周长和面积
  12. Java编程提高性能时需注意的地方
  13. html载入hta文件,浅谈HTA(HTML Application)和病毒的关系
  14. 国笔手机输入法MTK支持的语言
  15. HTML5 之 Meta 标签
  16. 各种三角形边长的计算公式
  17. IMX6 LCD 参数匹配过程分析
  18. [Android]自己动手做个拼图游戏
  19. Android MultiDex 源码分析
  20. MDCC王戈点爆全场:Smule乐器王是怎样炼成的

热门文章

  1. java mycat reload_MyCAT 1.6 使用reload @@config_all报错
  2. 按ASC码对字符串排序
  3. mac 邮箱客户端之腾讯企业邮箱设置 无法验证账号或密码
  4. arduino 1 读取电机编码器值
  5. 角度转度分秒lisp函数_自改小程序,提示错误,运行另一个lisp后就不会出错,求帮忙!...
  6. 苹果app商品定价_苹果将调整应用商店定价:中国区应用最低价涨至8元
  7. 一只小蜜蜂 C语言 函数 递归
  8. DNS故障的几种常见原因及解决方法
  9. 诗词锦集(持续更新)
  10. Nacos配置服务原理