欢迎光临
我们一直在努力

C++基础入门--函数、指针、结构体详解

C++基础入门(三)

1 函数

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

1.1 函数的定义

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

  • 返回值类型
  • 函数名
  • 参数列表
  • 函数体语句
  • return表达式
  • 语法:

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

    return表达式
    }

    在这里插入图片描述

    1.2 函数的调用

    功能:使用定义好的函数

    语法:函数名(参数)

    1.3 值传递

    所谓值传递,就是函数调用时实参将数值传入给形参

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

    在这里插入图片描述

    1.4 函数的常见样式

    常见的函数样式有种

  • 无参无返
  • 有参无返
  • 无参有返
  • 有参有返
  • #include<iostream>
    using namespace std;

    //函数常见样式

    //1、无参无返
    void test01() {
    cout << "this is test01" << endl;

    }
    //2、有参无返
    void test02(int a) {
    cout << "this is test 02 a=" <<a<< endl;//100
    }

    //3、无参有返
    int test03() {
    cout << "this is test03" << endl;//1000
    return 1000;
    }
    //4、有参有返
    int test04(int a) {
    cout << "this is test04 a=" << a << endl;//10000
    return a;

    }

    int main() {

    //无参无返的函数调用
    test01();
    //有参无返的函数调用
    test02(100);
    //无参有返的函数调用
    int num1 = test03();
    cout << "num1=" << num1 << endl;//1000
    //有参有返函数调用
    int num2 = test04(10000);//10000
    cout << "num2=" << num2 << endl;

    system("pause");
    return 0;
    }

    输出的结果为:

    在这里插入图片描述

    1.5 函数的声明

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

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

    #include<iostream>
    using namespace std;

    //函数的声明
    //比较函数,实现两个整型数字进行比较,返回较大的值

    //提前告诉编译器函数的存在,可以利用函数的声明
    //函数的声明,告诉编译器这个东西存在
    //声明可以写多次,但是定义只能有一次
    int max(int a, int b);
    int max(int a, int b);
    int max(int a, int b);
    int main9() {

    int a = 10;
    int b = 20;
    cout << max(a,b) << endl;//20

    system("pause");
    return 0;
    }
    //定义 有声明写在main函数后面
    int max(int a, int b) {
    return a > b ? a : b;
    };

    1.6 函数的分文件编写

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

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

  • 创建后缀名为.h的头文件
  • 创建后缀名为.cpp的源文件
  • 在头文件中写函数的声明
  • 在源文件中写函数的定义
  • #include<iostream>
    using namespace std;
    #include"swap.h"
    //函数的分文件编写
    //实现两个数字进行交换的函数

    //函数的声明
    //void swap(int a, int b);
    //函数的定义
    //void swap(int a, int b) {
    //int temp = a;
    //a = b;
    //b = temp;
    //cout << "a=" << a << endl;
    //cout << "b=" << b << endl;
    //
    //}
    //1、创建.h后缀名的头文件

    //2、创建.cpp后缀名的源文件

    //3、在头文件中写函数的声明

    //4、在源文件中写函数的定义

    int main() {
    int a = 10;
    int b = 20;
    swap(a, b);
    system("pause");
    return 0;
    }

    //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;

    }

    2 指针

    作用:可以通过指针间接访问内存,通过指针来保存一个地址

    • 内存编号是从0开始记录的,一般用十六进制数字表示
    • 可以利用指针变量保存地址
    2.1 指针变量的定义和使用

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

    #include<iostream>
    using namespace std;
    int main() {

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

    //2、使用指针
    //可以通过解引用的方式来找到指针指向的内容
    //指针前加*代表解引用,找到指针指向的内存中的数据
    *p = 1000;
    cout << "a=" << a << endl;
    cout << "p=" << *p<< endl;
    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    2.2 指针所占内存空间

    #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;
    //cout << "sizeof(int*)=" << sizeof(p) << endl;
    cout << "sizeof(int*)=" << sizeof(float*) << endl;
    cout << "sizeof(int*)=" << sizeof(double*) << endl;
    cout << "sizeof(int*)=" << sizeof(char*) << endl;

    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    2.3 空指针和野指针

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

    用途:初始化指针变量

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

    #include<iostream>
    using namespace std;
    int main() {

    //空指针
    //空指针用于给指针变量初始化
    int* p = NULL;

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

    system("pause");
    return 0;
    }

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

    #include<iostream>
    using namespace std;
    int main() {

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

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

    system("pause");
    return 0;
    }

    2.4 const修饰指针

    const修饰指针有三种情况:

  • const修饰指针—常量指针
  • const修饰常量—指针常量
  • const既修饰指针,又修饰常量
  • 在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    #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= 20;//正确
    //p2 = &b;报错

    //3、const修饰指针和出来那个
    const int* const p3 = &a;
    //指针的指向和指针指向的值都不可以改
    //*p3 = 20;报错
    //p3 = &b;报错
    system("pause");
    return 0;
    }

    2.5 指针和数组

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

    #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;

    cout << "利用指针来遍历数组" << endl;
    int* p2 = arr;
    for (int i = 0; i < 10; i++) {

    //cout << arr[i] << endl;
    cout << *p2 << endl;
    p2++;
    }

    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    2.6 指针和函数

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

    在这里插入图片描述

    #include<iostream>
    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() {
    //指针和函数

    //1、值传递,不会改变实参
    int a = 10;
    int b = 20;
    //swap01(a, b);

    //2、地址传递
    //如果是地址传递,可以改变实参
    swap02(&a, &b);
    cout << "a=" << a << endl;
    cout << "b=" << b << endl;

    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    2.7 指针、数组、函数

    思考题:封装一个函数,利用冒泡排序,实现对整型数组的升序排列

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

    #include<iostream>
    using namespace std;
    //冒泡排序函数 参数1:数组的首地址 参数2:数组的长度
    void bubbleSort(int* arr, int len) {
    //i:排序总轮数=元素个数-1
    for (int i = 0; i < len – 1; i++) {
    //j:每轮对比次数=元素个数-排序轮数-1
    for (int j = 0; j < len – i – 1; 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() {

    //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、打印排序后的1数组
    printArray(arr, len);

    system("pause");
    return 0;
    }

    3 结构体

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

    3.1 结构体定义和使用

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

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

    • struct 结构体名 变量名
    • struct 结构体名 变量名={成员1值,成员2值…}
    • 定义结构体时顺便创建变量

    #include<iostream>
    using namespace std;
    #include<string>
    int main() {

    //1、创建学生数据类型:学生包括(姓名,年龄,分数)
    //自定义数据类型,一些类型的集合组成的一个类型
    //语法 struct 类型名称 {成员列表}
    struct Student {
    //成员列表

    //姓名
    string name;
    //年龄
    int age;
    //分数
    int score;
    }s3;//顺便创建结构体变量

    //2、通过学生类型创建具体的学生

    //2.1 struct Student s1;

    //struct 结构体变量创建时关键字可以省略,定义时不能省略
    struct Student s1;
    //给s1属性赋值,通过访问结构体变量中的属性
    s1.name = "张三";
    s1.age = 18;
    s1.score =99;
    cout << "姓名:" << s1.name << "年龄:" << s1.age << "分数:" << s1.score << endl;

    //2.2 struct Student s2={…}
    struct Student s2{"李四",19,88};
    cout << "姓名:" << s2.name << "年龄:" << s2.age << "分数:" << s2.score << endl;
    //2.3 在定义结构体时顺便创建结构变量
    s3.name = "王五";
    s3.age = 20;
    s3.score = 79;
    cout << "姓名:" << s3.name << "年龄:" << s3.age << "分数:" << s3.score << endl;
    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    3.2 结构体数组

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

    语法:struct 结构体名 数组名[元素个数]={{},…,{}}

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

    //结构体数组 如何创建?如何访问?
    //1、定义结构体
    struct Student {
    //姓名
    string name;
    //年龄
    int age;
    //分数
    int score;

    };

    int main() {

    //2、创建结构体数组
    struct Student stuArray[3] = {
    {"张三",18,99},{"李四",33,55},{"王五",45,90}
    };

    //3、给结构体数组中的元素赋值
    stuArray[2].name = "赵六";//改王五
    stuArray[2].age = 10;
    stuArray[2].score =66;

    //4、遍历结构体数组
    for (int i = 0; i < 3; i++) {
    cout << "姓名:" << stuArray[i].name
    << "年龄:" << stuArray[i].age
    << "分数:" << stuArray[i].score<<endl;
    }

    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    3.3 结构体指针

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

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

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

    //结构体指针
    //定义学生的结构体
    struct student {
    string name;
    int age;
    int score;

    };
    int main() {
    //1、创建学生结构体变量
    struct student s = { "张三",18,100 };
    //2、通过指针指向结构体变量
    struct student* p = &s;

    //3、通过指针访问结构体变量中的数据
    //通过结构体指针,访问结构体中的属性,需要利用‘->’
    cout << "姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;

    system("pause");
    return 0;
    }

    输出的结果为:

    在这里插入图片描述

    3.4 结构体嵌套结构体

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

    #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() {
    //结构体嵌套结构体
    //创建老师
    struct teacher t;
    t.id = 1000;
    t.name = "老王";
    t.age = 78;
    t.stu.name = "小明";
    t.stu.age = 18;
    t.stu.score = 99;

    cout << "老师姓名:" << t.name << "老师id:" << t.id << "老师年龄:" << t.age
    << "老师辅导的学生姓名:" << t.stu.name << "老师辅导的学生年龄:" << t.stu.age
    << "老师辅导的学生分数:" << t.stu.score << endl;

    system("pause");
    return 0;
    }

    输出的结果为:

    在这里插入图片描述

    3.5 结构体做函数参数

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

    传递方式有两种:

  • 值传递
  • 地址传递
  • #include<iostream>
    #include<string>
    using namespace std;

    //定义学生结构体
    struct student {
    string name;
    int age;
    int score;
    };

    //打印学生信息函数
    //1、值传递
    void printStudent1(struct student s){
    s.age = 99;
    cout << "在子函数中 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
    }

    //2、地址传递
    void printStudent2(struct student*p){
    p->age = 200;
    cout << "子函数2中 姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;
    }

    int main() {
    //结构体做函数参数
    //将学生传入到一个参数中,打印学生身上的所有信息
    //创建结构体变量
    struct student s;
    s.name = "张三";
    s.age = 18;
    s.score = 99;

    printStudent1(s);
    //printStudent2(&s);

    cout << "main函数中打印 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;

    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    3.6 结构体中const使用场景

    作用:用const防止误操作

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

    struct student {
    string name;
    int age;
    int score;
    };

    //将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
    //const的使用场景
    void printStudents(const struct student *s) {
    //s->age = 99;加入const之后,一旦有修改的操作就会报错,可以防止我们的误操作
    cout << "姓名:" << s->name << "年龄:" << s->age << "分数:" << s->score << endl;
    }

    int main() {
    //创建结构体变量
    struct student s = {"张三",18,99};

    //通过函数打印结构体变量信息
    printStudents(&s);
    cout << "main中张三的年龄:" << s.age << endl;

    system("pause");
    return 0;
    }

    输出的结果为:

    在这里插入图片描述

    3.7 结构体案例

    在这里插入图片描述

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

    //学生的结构体
    struct student {
    string sName;
    int score;
    };

    //老师的结构体定义
    struct Teacher {
    string tName;
    struct student sArray[5];
    };
    //给老师和学生赋值的函数
    void allocateSpace(struct Teacher tArray[],int len) {
    string nameSeed = "ABCDE";
    //给老师开始赋值
    for (int i = 0; i < len; i++) {
    tArray[i].tName = "Teacher_";
    tArray[i].tName += nameSeed[i];

    //通过循环给每名老师所带的学生赋值
    for (int j = 0; j < 5; j++) {
    tArray[i].sArray[j].sName = "Student_";
    tArray[i].sArray[j].sName += nameSeed[j];

    int random = rand() % 61+40;//40~100
    tArray[i].sArray[j].score = random;
    }
    }
    }
    //打印所有信息
    void printInfo(struct Teacher tArray[],int len) {
    for (int i = 0; i < len; i++) {
    cout << "老师姓名:" << tArray[i].tName << endl;
    for (int j = 0; j < 5; j++) {
    cout << "\\t学生姓名:" << tArray[i].sArray[j].sName
    <<" 考试分数:"<<tArray[i].sArray[j].score<<endl;
    }
    }
    }
    int main() {
    //随机数种子
    srand((unsigned int)time(NULL));
    //1、创建3名老师的数组
    struct Teacher tArray[3];

    //2、通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
    int len = sizeof(tArray) / sizeof(tArray[0]);
    allocateSpace(tArray,len);
    //3、打印所有老师及所带学生信息
    printInfo(tArray,len);

    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    在这里插入图片描述

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

    //1、设计英雄结构体
    struct Hero{
    string name;
    int age;
    string sex;
    };
    //冒泡排序,实现年龄升序排列
    void bubbleSort(struct Hero heroArray[], int len) {
    for (int i = 0; i < len – 1; i++) {
    for (int j = 0; j < len – i – 1; j++) {
    if (heroArray[j].age > heroArray[j + 1].age) {
    struct Hero temp = heroArray[j];
    heroArray[j]= heroArray[j + 1];
    heroArray[j + 1] = temp;
    }
    };
    };
    };
    //打印排序后数组的信息
    void printHero(struct Hero heroArray[], int len) {
    cout << "排序后打印" << endl;
    for (int i = 0; i < len; i++) {
    cout << "姓名:" << heroArray[i].name << "年龄:" << heroArray[i].age
    << "性别:" << heroArray[i].sex << endl;
    }
    }

    int main() {
    //2、创建数组存放五名英雄
    struct Hero heroArray[5] = {
    {"刘备",23,"男"},
    {"关羽",22,"男"},
    {"张飞",20,"男"},
    {"赵云",21,"男"},
    {"貂蝉",19,"女"}
    };
    int len = sizeof(heroArray) / sizeof(heroArray[0]);
    cout << "排序前打印" << endl;
    for (int i = 0; i < len; i++) {
    cout << "姓名:" << heroArray[i].name << "年龄:" << heroArray[i].age<< "性别:" << heroArray[i].sex << endl;
    }

    //3、对数组进行排序,按照年龄进行升序排列
    bubbleSort(heroArray, len);
    //4、将排序后的结果打印输出
    printHero(heroArray, len);

    system("pause");
    return 0;
    }

    输出结果为:

    在这里插入图片描述

    赞(0)
    未经允许不得转载:171主机测评 » C++基础入门--函数、指针、结构体详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址