C++基础

一、C++基础

1.第一个C++程序:

#include<iostream>
using namespace std;
int main()
{
    cout <<" hello world!" <<endl;
    system("pause");
    return 0;    
}

2. 单行注释://    多行注释: /* */

3. 变量

  作用:给一段指定的内存空间起名,方便操作这段内存;

  语法:数据类型 变量名 = 变量初始值; (int a = 10;)

  变量存在的意义:方便管理内存空间。

4. 常量

  作用:用于记录程序中不可更改的数据。

  C++中有两种定义常量的方式:

  (1) #define 宏常量: #define 常量名 常量值 (#define Day 7)

    通常在文件上方定义,表示一个常量; 

  (2)const 修饰的变量: const 数据类型 变量名 = 常量值  (const int month = 12;)

    通常在变量定义前加关键字const,修饰该变量为常量,不可修改。

5. 关键字

  作用:关键字是C++预先保留的单词。

  在定义变量或常量时候,不要用关键字。

6. 标识符命名规则

  作用:C++规定给标识符(变量、常量)命名时,有一套自己的规则。

  (1)标识符不能是关键字;

  (2)标识符只能由字母、数字、下划线组成;

  (3)第一个字母必须为字母或下划线;

  (4)标识符中字母区分大小写。

二. 数据类型

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

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

2.1 整型

  作用:整型变量表示的是整数类型的数据。

  C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同:

数据类型

占用空间

取值范围

short(短整型)

2字节

(-2^15(-32768) ~ 2^15 - 1(32767) )

int(整型)

4字节

(-2^31 ~ 2^31 - 1 )

long(长整型)

Windows为4字节,Linux为4字节(32位),8字节(64位)

(-2^31 ~ 2^31 - 1 )

long long(长长整型)

8字节

(-2^63 ~ 2^63 - 1 )

2.2 sizeof关键字

  作用:利用sizeof关键字可以统计数据类型所占内存大小。

  语法:sizeof(数据类型 或 变量)

  例: cout << "short类型所占内存空间为: " << sizeof(short) << endl;

  整型大小比较: short < int <= long <= long long

2.3 实型(浮点型)

  作用:用于表示小数。

  浮点型变量分为两种:单精度float、双精度double

  两者的区别在于表示的有效数字范围不同

数据类型

占用空间

有效数字范围

float

4字节

7位有效数字

double

8字节

15~16位有效数字

  例: float f1 = 3.14f; (一般会在float类型后面多加一个f,来告诉编译器这是个float类型单精度的变量)

  默认情况下输出一个小数会显示出6位有效数字。

2.4 字符型

  作用:字符型变量用于显示单个字符。

  语法:char ch = 'a';

  注意:(1)在显示字符型变量时,用单引号将字符括起来,不要用双引号;

     (2)单引号内只能有一个字符,不可以是字符串。

  C和C++中字符型变量只占用1个字节。

  字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元。

  字符型变量对应的ASCII编码:cout << (int)ch<<endl;  (a---97, A --- 65)

2.5 转义字符

  作用:用于表示一些不能显示出来的ASCII字符。

  现阶段我们常用的转义字符有: (换行)、\()、 (8个位置,用于整齐输出数据)

2.6 字符串型

  作用:用于表示一串字符。

  两种风格:(1)C风格字符串: char 变量名[] = "字符串值”;(注:C风格的字符串要用双引号括起来)

          例:char str[] = "hello world";

            cout << str << endl;

       (2)C++风格字符串:string 变量名 = “字符串值”;(注:头文件要添加 #include<string>)

          例:string str2 = "hello world";

2.7 布尔类型bool

  作用:布尔数据类型代表真或假的值。

  bool类型只有两个值:true---真(本质是1);false---假(本质是0)。

  bool类型占1个字节大小。

  创建bool数据类型:

  例:bool flag = true;

    cout << flag << endl; (输出为1)

2.8 数据的输入

  作用:用于从键盘获取数据。

  关键字:cin

  语法:cin >> 变量

三. 运算符

  作用:用于执行代码的运算。 

运算符类型

作用

算术运算符

用于处理四则运算

赋值运算符

用于将表达式的值赋给变量

比较运算符

用于表达式的比较,并返回一直真值或假值

逻辑运算符

用于根据表达式的值返回真值或假值

3.1 算术运算符

  作用:用于处理四则运算。

      / 两个整数相除,结果仍然是整数,将小数部分去除。

  % 取模(取余) (两个小数不能做取模运算)

  递增递减: 前置递增 ++a  (先让变量+1,然后进行表达式运算)

        后置递增 a++   (先进行表达式运算,后让变量+1)

3.2 赋值运算符

  作用:用于将表达式的值赋给变量。(=、+=、-=、/=、%=)

3.3 比较运算符

  作用:用于表示式的比较,并返回一个真值或假值。(==、!=、<、>、<=、>=)

3.4 逻辑运算符

  作用:用于根据表示的值返回真值或假值。

  在C++中,除了0 都为真

  逻辑运算符有以下符号:!(非)、&&(与)(同真为真,其余为假)、||(或)(同假为假,其余为真)

四、程序流程结构

  C/C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构。

  顺序结构:程序按顺序执行,不发生跳转

  选择结构:依据条件是否满足,有选择的执行相应功能。

  循环结构:依据条件是否满足,循环多次执行某段代码。

4.1 选择结构

4.1.1 if语句

  作用:执行满足条件的语句。

  if语句的三种形式:单行格式if语句、多行格式if语句、多条件的if语句。

  if (){} (注:if语句后面不要加分号)

4.1.2 三目运算符

  作用:通过三目运算符实现简单的判断。

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

  解释:如果表达式1的值为真,执行表达式2,并返回表达式2的结果;

       如果表达式1的值为假,执行表达式3,并返回表达式3的结果。

  例:c = (a > b ? a : b);

  在C++中,三目运算符返回的是变量,可以继续赋值。

  例:(a > b ? a : b) = 100;

4.1.3 switch语句

  作用:执行多条件分支语句

  语法:

switch(表达式)
{
    case 结果1: 执行语句; break; //退出当前分支
    case 结果2: 执行语句; break;
    ...
    default: 执行语句;break;
}

  注:(1)switch语句中表达式类型只能是整型或者字符型

    (2)case里如果没有break,那么程序会一直向下执行

    (3)与if语句相比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间。

  switch缺点:判断时候只能是整型或者字符型,不可以是一个区间。

  switch优点:结构清晰,执行效率高。

 4.2 循环结构

4.2.1 while循环语句

  作用:满足循环条件,执行循环语句。

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

  解释:只要循环条件的结果为真,就执行循环语句。

  例:系统生成随机数 int num = rand()%100+1; // 生成1~100的随机数

  可以用break来退出当前循环。

  srand((unsigned int)time(NULL)); //添加随机数种子,作用:利用当前系统时间生成随机数,防止每次随机数都一样。还需添加头文件 #include<ctime>。

4.2.2 do...while循环语句

  作用:满足循环条件,执行循环语句。

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

  注:与while的区别在于do...while会先执行一次循环语句,再判断循环条件。

4.2.3 for循环语句

  作用:满足循环条件,执行循环语句

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

  例:for(int i = 0; i<10; i++)

4.2.4 嵌套循环

  作用:在循环体中再嵌套一层循环,解决一些实际问题。

4.3 跳转语句

4.3.1 break语句

  作用:用于跳出选择结构或者循环结构

  break使用的时机:

  (1)出现在switch条件语句中,作用是终止case并跳出switch;

  (2)出现在循环语句中,作用是跳出当前的循环语句;

  (3)出现在嵌套循环中,跳出最近的内层循环语句。

4.3.2 continue语句

  作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环。

  注:continue并没有使整个循环终止,而break会跳出循环。

4.3.3 goto语句

  作用:可以无条件跳转语句。

  解释:如果标记的名称存在,执行到goto语句时,会跳转到标记的位置。

  注:在程序中不建议使用goto语句,以免造成程序流程混乱。

五、数组

5.1 概述

  所谓数组,就是一个集合,里面存放了相同类型的数据元素。

  特点1:数组中的每个数据元素都是相同的数据类型

  特点2:数组是由连续的内存位置组成的。

5.2 数组

5.2.1 一维数组定义方式

  一维数组定义的三种方式:

  (1)数据类型 数组名[ 数组长度 ];

  (2)数据类型 数组名[ 数组长度 ] = { 值1, 值2, ...};

  (3)数据类型 数组名[ ] =  { 值1, 值2, ...};

  数组元素下标从0开始索引的;如果在初始化数据时候,没有全部填写完,会用0来填补剩余数据。

  注:数组名的命名规范与变量名命名规范一致,不要和变量重名。

5.2.2 一维数组数组名

  一维数组名称的用途:

  (1)可以统计整个数组在内存中的长度;  (sizeof(arr)、sizeof(arr[0]))

  (2)可以获取数组在内存中的首地址。 (cout << arr << endl;)

    数组中第一个元素地址为: cout << (int)&arr[0] << endl;

  (3)数组名是常量,不可以进行赋值操作。

元素逆序代码:

#include<iostream>
using namespace std;

#define Day 10

int main()
{    
    //1.创建数组
    int arr[5] = { 1,3,2,5,4 };
    cout << "数组逆置前: " << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << arr[i] << endl;
    }
    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--;
    }
    cout << "数组元素逆置后:" << endl;
    for (int i = 0; i<5; i++)
    {
        cout << arr[i] << endl;
    }
    system("pause");
    return 0;
}

5.2.3 冒泡排序

#include<iostream>
using namespace std;

#define Day 10

int main()
{    
    // 利用冒泡排序实现升序排列
    int arr[9] = { 4,2,8,0,5,7,1,3,9 };
    cout << "排序前: " << endl;
    for (int i = 0; i < 9; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
    // 开始冒泡排序
    // 总共排序轮数为 元素个数 - 1
    for (int i = 0; i < 9-1; i++)
    {
        // 内层循环对比次数 = 元素个数 - 当前轮数 - 1
        for (int j = 0; j < 9 - i - 1; j++)
        {
            // 如果第一个数组比第二个数字大,交换两个数字
            if (arr[j] > arr[j + 1])
            {
                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] << " ";
    }
    system("pause");
    return 0;
}

5.3  二维数组

  二维数组就是在一维数组上,多加一个维度。

5.3.1 二维数组定义方式

  二维数组定义的四种方式:

  (1)数据类型 数组名[ 行数 ][ 列数 ];

  (2)数据类型 数组名[ 行数 ][ 列数 ] = { {数据1, 数据2},  {数据3, 数据4} };

  例: 第1行:arr[0]

int arr2[2][3] = 
{
    {1,2,3},
    {4,5,6}   
};

5.3.2 二维数组数组名

  (1)查看二维数组所占内存空间 ;(2)获取二维数组首地址

  查看元素的地址: &arr[0][0]

  (3)数据类型 数组名[ 行数 ][ 列数 ] = { 数据1, 数据2,  数据3, 数据4 };

  (4)数据类型 数组名[  ][ 列数 ] = { 数据1, 数据2,  数据3, 数据4 };

  建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性

六、 函数

6.1 概述

  作用:将一段经常使用的代码封装起来,减少重复代码。

  一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。

6.2 函数的定义

  函数的定义一般有5个步骤:

  (1)返回值类型;

  (2)函数名;

  (3)参数列表;

  (4)函数体语句;

  (5)return 表达式。

语法:

返回值类型 函数名 (参数列表)
{
    函数体语句
    return 表达式
}

6.3 函数的调用

  功能:使用定义好的函数

  语法:函数名 (参数)

  总结:函数定义里小括号内称为形参,函数调用时传入的参数称为实参。

6.4 值传递

  值传递:函数调用时实参将数值传入形参;

  值传递时,如果形参发生,并不会影响实参。

  返回值不需要的时候,可以不写return.

6.5 函数的常见样式

  常见的函数样式有4种:

  (1)无参无返

  (2)有参无返

  (3)无参有返

  (4)有参有返

6.6 函数的声明

  作用:告诉编译器函数名称以及如何调用函数,函数的实际主体可以单独定义。

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

  例:int max( int a, int b);

6.7 函数的分文件编写

  作用:让代码结构更加清晰。

  函数分文件编写一般有4个步骤:

  (1)创建后缀名为.h的头文件;

  (2)创建后缀名为.cpp的源文件;

  (3)在头文件中写函数的声明;

  (4)在源文件中写函数的定义。

  在源文件中添加头文件的.h名,例:#include "swap.h "

七、指针

7.1 指针的基本概念

  指针的作用:可以通过指针间接访问内存。

  内存编号是从0开始记录的,一般用十六进制数字表示。

  可以利用指针变量保存地址。

7.2 指针变量的定义和使用

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

#include<iostream>
using namespace std;

int main()
{
    // 定义指针 
    int a = 10;
    // 定义指针的语法:数据类型 * 指针变量名;
    int *p;
    // 让指针记录变量a的地址
    p = &a;
    cout << "a的地址为: " << &a << endl;
    cout << "指针p为: " << p << endl;

    // 使用指针
    *p = 1000;
    cout << "a = " << a << endl;
    cout << "*p = " << *p << endl;

    system("pause");
    return 0;
}

7.3 指针所占的内存空间

#include<iostream>
using namespace std;

int main()
{
    // 指针多占内存空间
    int a = 10;
    // int * p;
    // p = &a;
    int *p = &a;

    // 在32位操作系统下,指针是占4个字节空间大小,不管是什么数据类型
    // 在64位操作系统下,指针是占8个字节空间大小
    cout << "sizeof(int *) = " << sizeof(int *) << endl;       //4
    cout << "sizeof(float *) = " << sizeof(float *) << endl;   //4
    cout << "sizeof(double *) = " << sizeof(double *) << endl; //4
    cout << "sizeof(char *) = " << sizeof(char *) << endl;     //4

    system("pause");
    return 0;
}

7.4 空指针和野指针

  空指针:指针变量指向内存中编号为0的空间。

  用途:初始化指针变量。

  注意:空指针指向的内存是不可以访问的。

#include<iostream>
using namespace std;

int main()
{
    // 空指针
    // 1. 空指针用于给指针变量进行初始化
    int * p = NULL;

    // 2. 空指针是不可以进行访问的
    // 0~255之间的内存编号是系统占用的,因此不可以访问
    *p = 100; // 会报错

    // 野指针
    // 在程序中,尽量避免出现野指针
    int * p2 = (int *)0x1100; 
    cout << *p << endl;

    system("pause");
    return 0;
}

  野指针:指针变量指向非法的内存空间。

  总结:空指针和野指针都不是我们申请的空间,因此不要访问。

7.5 const修饰指针

  const修饰指针有三种情况:

  (1)const修饰指针 --- 常量指针 (指针的指向可以改,指针指向的值不可以改。) 例:const int * p = &a;

  (2)const修饰常量 --- 指针常量 (指针的指向不可以改,指针指向的值可以改。) 例:int * const p = &a;

  (3)const既修饰指针,又修饰常量。(指针的指向和指针指向的值都不可以改。) 例:const int * const p = &a;

#include<iostream>
using namespace std;

int main()
{
    // 1. const修饰指针 常量指针
    int a = 10;
    int b = 10;

    const int * p = &a;
    // 指针指向的值不可以改,指针的指向可以改
    // *p = 20; 错误
    p = &b; //正确

    // 2. const修饰常量  指针常量
    // 指针的指向不可以改,指针指向的值可以改
    int * const p2 = &a;
    *p2 = 100; //正确
    // p2 = &b; 错误

    // 3. const修饰指针和常量
    // 指针的指向和指针指向的值都不可以改
    const int * const p3 = &a;
    // p3 = &b; 错误
    // *p3 = 100; 错误

    system("pause");
    return 0;
}

  注:看const右侧紧跟的是指针还是常量,是指针就是常量指针,是常量就是指针常量。

7.6 指针和数组

  作用:利用指针访问数组中元素

#include<iostream>
using namespace std;

int main()
{
    // 指针和数组
    // 利用指针访问数组中的元素
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    cout << "第一个元素为:" << arr[0] << endl;
    int * p = arr; // arr是数组首地址
    cout << "利用指针访问第一个元素: " << *p << endl;
    p++; // 让指针向后偏移4个字节
    cout << "利用指针访问第二个元素: " << *p << endl;

    int * p2 = arr;
    for (int i = 0; i<10; i++)
    {
        // 利用指针遍历数组
        cout << *p << endl;
        p2++;
    }
    system("pause");
    return 0;
}

7.7 指针和函数

  作用:利用指针作函数参数,可以修改实参的值。

using namespace std;

// 实现两个数字进行交换
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 *p1, int *p2)
{
    int temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
int main()
{
    // 值传递
    int a = 10;
    int b = 20;
    swap01(a, b);
    cout << "a = " << a << endl;  // 10
    cout << "b = " << b << endl;  // 20

    // 地址传递
    // 如果是地址传递,可以修饰实参
    swap02(&a, &b);
    cout << "a = " << a << endl;  // 20
    cout << "b = " << b << endl;  // 10
    system("pause");
    return 0;
}

  总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递。

7.8 指针、数组、函数

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

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

#include<iostream>
using namespace std;

// 冒泡排序函数 参数1 数组的首地址 参数2 数组长度
void bubbleSort(int * arr, int len)
{
    for(int i = 0; i < len - 1; i++)
    {
        for(int j = 0; j<len-1-i; j++)
        {
            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] << " ";
    }
    cout << endl;
}
int main()
{
    // 1. 先创建数组
    int arr[10] = {4,3,6,9,1,2,10, 8,7,5 };

    // 数组长度
    int len = sizeof(arr) / sizeof(arr[0]);
    // 2. 创建函数,实现冒泡排序
    bubbleSort(arr, len);
    // 3. 打印排序后的数组
    printArray(arr, len);
    system("pause");
    return 0;
}

八、结构体

8.1 结构体基本概念

  结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。

8.2 结构体定义和使用

  语法: struct 结构体名 { 结构体成员列表 };

  通过结构体创建变量的方式有三种:

  (1)struct 结构体名 变量名

  (2)struct 结构体名 变量名 = { 成员1值, 成员2值...}

  (3)定义结构体时顺便创建变量

#include<iostream>
#include<string>
using namespace std;

// 1. 创建学生数据类型: 学生包括(姓名、年龄、分数)
// 自定义数据类型,一些类型集合组成的一个类型
// 语法 struct 类型名称 { 成员列表 }
struct Student
{
    // 成员列表
    // 姓名
    string name;
    // 年龄
    int age;
    // 分数
    int score;
}s3; // 顺便创建结构体变量

int main()
{
    // 2. 通过学生类型创建具体学生
    // 2.1 struct Student s1 (结构体创建的时候struct关键字可以省略,但是在定义的时候不行)
    struct Student s1;
    // 给s1属性赋值,通过访问结构体变量中的属性
    s1.name = "张三";
    s1.age = 18;
    s1.score = 100;
    cout << "姓名: " << s1.name << " 年龄: " << s1.age << " 分数: " << s1.score << endl;

    // 2.2 struct Student s2 = {... }
    struct Student s2 = { "李四", 19, 80};

    // 2.3 自定义结构体时顺便创建结构体变量
    s3.name = "王五";
    s3.age = 20;
    s3.score = 90;

    system("pause");
    return 0;
}

  总结: (1)定义结构体时的关键字是struct,不可省略;

     (2)创建结构体变量时,关键字struct可以省略;

     (3)结构体变量利用操作符“.”访问成员。

8.3 结构体数组

  作用:将自定义的结构体放入到数组中方便维护

  语法: struct 结构体名 数组名{ 元素个数 } = { {}, {}, ...,{} };

#include<iostream>
#include<string>
using namespace std;

struct Student
{
    // 成员列表
    string name;  // 姓名
    int age;  // 年龄
    int score;  // 分数
}; 

int main()
{
    // 创建结构体数组
    struct Student stuArray[3] =
    {
        {"张三", 18, 90},
        {"李四", 18, 59},
        {"王五", 18, 100}
    };
    // 给结构体数组中的元素赋值
    stuArray[2].name = "赵六";
    stuArray[2].age = 20;

    // 遍历结构体数组
    for (int i = 0; i < 3; i++)
    {
        cout << "姓名: " << stuArray[i].name << " ";
    }

    system("pause");
    return 0;
}

8.4 结构体指针

  作用:通过指针访问结构体中的成员

  利用操作符 ->可以通过结构体指针访问结构体属性

#include<iostream>
#include<string>
using namespace std;

struct Student
{
    // 成员列表
    string name;  // 姓名
    int age;  // 年龄
    int score;  // 分数
}; 

int main()
{
    // 创建学生结构体变量
    struct Student s = {"张三", 18, 100};

    // 通过指针指向结构体变量
    Student * p = &s;

    // 通过指针访问结构体变量中的数据
    // 通过结构体指针 访问结构体中的属性,需要利用'->'
    cout << "姓名:" << p -> name << endl;

    system("pause");
    return 0;
}

8.5 结构体嵌套结构体

  作用:结构体中的成员可以是另一个结构体

#include<iostream>
#include<string>
using namespace std;

// 定义学生结构体
struct Student
{
    // 成员列表
    string name;  // 姓名
    int age;  // 年龄
    int score;  // 分数
}; 

// 定义老师结构体
struct Teacher
{
    // 成员列表
    int id;  // 教师编号
    string name;  // 教师姓名
    int age;  // 年龄
    struct Student stu; // 辅导的学生
}; 

int main()
{
    // 结构体嵌套结构体
    // 创建老师
    Teacher t;
    t.id = 1000;
    t.name = "老王";
    t.age = 50;
    t.stu.name = "小王";
    t.stu.age = 20;
    t.stu.score = 60;

    system("pause");
    return 0;
}

  总结:在结构体中可以定义另一个结构体作为成员。

8.6 结构体做函数参数

  作用:将结构体作为参数向函数中传递。

  传递方式有两种:值传递、地址传递。

#include<iostream>
#include<string>
using namespace std;

struct student
{
    // 成员列表
    string name;  // 姓名
    int age;  // 年龄
    int score;  // 分数
}; 

// 打印学生信息函数
//1、值传递
void printStudent1(struct student s)
{
    cout << "子函数中 姓名: " << s.name << endl;
}
// 2、地址传递
void printStudent2(struct student *p)
{
    cout << "子函数2中 姓名: " << p -> name << endl;
}
int main()
{
    // 结构体做函数参数
    // 将学生传入到一个参数中,打印学生身上的所有信息
    struct student s;
    s.name = "小王";
    s.age = 20;
    s.score = 60;

    printStudent1(s);
    printStudent2(&s);

    system("pause");
    return 0;
}

  总结:如果不想修改主函数中的数据,用值传递,反之用地址传递。

8.7 结构体中const使用场景

  作用:用const来防止误操作

#include<iostream>
#include<string>
using namespace std;

struct student
{
    // 成员列表
    string name;  // 姓名
    int age;  // 年龄
    int score;  // 分数
}; 

// 打印学生信息函数
// 将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
void printStudents(const student *s)
{
    //加入const之后,一旦有修改的操作就会报错,可以防止我们的误操作
    cout << "子函数中 姓名: " << s->name << endl;
}

int main()
{
    // const使用场景
    // 创建结构体变量
    struct student s = {"张三", 15, 70};
    // 通过函数打印结构体变量信息
    printStudents(&s);
    // 将学生传入到一个参数中,打印学生身上的所有信息
    
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/xiaotongtt/p/10741587.html