第一个C++程序
1 2 3 4 5 6
| #include <iostream>
int main (){ std::cout << "Hello World!" << std::endl; return 0; }
|
变量
变量存在的意义:方便我们管理内存空间
变量创建的语法:
1 2 3
| 数据类型 变量名 = 变量初始值;
int a = 10;
|
常量
作用:用于记录程序中不可更改的数据
C++定义常量的两种方式
- #define 宏常量:
#define 常量名 常量值
- 通常在文件上方定义
- const 修饰的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
#define Day 7 int main (){ std::cout << "一周总共有:" << Day << "天" << std::endl; return 0; }
int main (){ const int month = 12;
std::cout << "一年总共有:" << month << "月" << std::endl; return 0; }
|
标识符
- 标识符不能是关键字
- 标识符只能由字母、数字、下划线组成
- 标识符第一个字符只能是字母或下划线
- 标识符区分大小写
函数的声明
作用:告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义
函数的声明可以写多次,但是定义只能写一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int get_max(int a ,int b);
int main () { int num1 = 10; int num2 = 2; cout << get_max(num1, num2) << endl; return 0; }
int get_max(int a ,int b){ return a > b ? a : b; };
|
函数的分文件编写
作用:让代码结构更加清晰
函数分文件编写一把有4个步骤
- 创建后缀名为.h的头文件
- 穿件后缀名为.cpp的源文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
swap.h
1 2 3 4
| #include <iostream> using namespace std;
void swap(int a, int b);
|
swap.cpp
1 2 3 4 5 6 7 8 9 10 11
| #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.cpp
1 2 3 4 5 6 7
| #include "swap.h"
int main () { swap(1,2); return 0; }
|
CMakeLists.tst
1 2 3 4 5 6
| cmake_minimum_required(VERSION 3.22) project(demo)
set(CMAKE_CXX_STANDARD 14)
add_executable(demo main.cpp swap.cpp)
|
指针
指针的基本概念
指针的作用:可以通过指针间接访问内存
如何定义一个指针
指针定义的语法:数据类型 * 指针变量名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int main () { int a = 10; int * p; p = &a; cout << "a的地址为:" << &a << endl; cout << "指针p为:" << p << endl; return 0; }
|
如何使用指针
1 2 3 4 5 6 7 8 9 10
|
*p = 1000; cout << "a = " << a << endl; cout << "*p = " << *p << endl;
|
指针所占内存空间
在32位操作系统下:占用4个字节空间
在64位操作系统下:占用8个字节空间
1 2 3 4 5 6 7 8 9 10 11 12 13
| int main () { int a = 10; int * p = &a; cout << "指针p大小为:" << sizeof (int *) << endl; cout << "指针p大小为:" << sizeof (p) << endl; return 0; }
|
空指针和野指针
空指针
指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的
1 2 3 4 5 6 7 8 9 10 11
| int main () { int * p = NULL;
*p = 100; return 0; }
|
野指针
指针变量指向非法的内存空间
1 2 3 4 5 6 7 8 9
| int main () { int * p = (int *)0x11000000; cout << *p << endl; return 0; }
|
const修饰指针
const修饰指针有三种情况
const修饰指针:常量指针
const int * p = &a;
特点:指针的指向可以修改,单是指针指向的值不可以改
const修饰常量:指针常量
int * const p = &a;
特点:指针的指向不可以改,指针指向的值可以改
const既修饰指针,又修饰常量
const int * const p = &a;
特点:指针的指向和指针指向的值都不可以改
指针和数组
作用:利用指针访问数组中的元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int main () { int arr[10] ={1,2,3,4,5,6,7,8,9,10};
int * p = arr;
cout << "第一个元素:" << arr[0] << endl; cout << "指针访问第一个元素:" << *p << endl;
for (int i = 0; i < 10; ++i) { cout << *p << endl; p++; } }
|
指针和函数
作用:利用指针作为函数的参数,可以修改实参的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void swap(int *a,int *b){ int temp = *a; *a = *b; *b = temp; }
int main () { int a = 10; int b = 20; swap(&a,&b); cout << "a = " << a << endl; cout << "b = " << b << endl; }
|
个人理解:
int *a
这里需要传递的是一个地址,* 的意义不是单纯的指针 而是通过地址的取值符号。
也就是说,*a 的完整意思是在地址a中保存的值,单个a就表示一个地址
int temp = *a;
的意思不是地址给到temp,而是 **通过地址取值这个组合 **给temp
也就是概念意义上的把地址传递了
指针、数组、函数
案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| void bubbleSort(int * arr,int len) { for (int i = 0; i < len - 1; ++i) { for (int j = 0; j < len - i - 1; ++j) { if(arr[j] > arr[j + 1]){ int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }
int main () { int arr[10] = { 4,3,6,9,1,2,10,8,7,5}; int len = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr,len);
for (int i = 0; i < len; ++i) { cout << arr[i] << endl; } }
|
结构体
结构体的基本概念
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
结构体定义和使用
语法:struct 结构体名{结构体成员列表}
通过结构体创建变量的方式有三种:
- struct 结构体名 变量名
- struct 结构体名 变量名 = {成员1值, 成员2值…}
- 定义结构体时顺便创建变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
struct Student { string name; int age; int score; } s4;
int main () { struct Student s1 ; s1.name = "张三"; s1.age = 20; s1.score = 100; struct Student s2 = { .name = "李四", .age = 18, .score = 98 }; struct Student s3 = {"王五",22,23}; s4.name = "赵六"; s4.age = 66; s4.score = 55;
cout << "姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl; cout << "姓名:" << s2.name << " 年龄:" << s2.age << " 分数:" << s2.score << endl; cout << "姓名:" << s3.name << " 年龄:" << s3.age << " 分数:" << s3.score << endl; cout << "姓名:" << s4.name << " 年龄:" << s4.age << " 分数:" << s4.score << endl; }
|
结构体数组
作用:将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[元素个数] = { {},{}, ... {} }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
struct Student { string name; int age; int score; };
int main () { Student stuArray[3] = { {"张三", 18, 100}, {"李四", 28, 99}, {"王五", 38, 66} }; stuArray[2].name = "赵六"; stuArray[2].age = 80; stuArray[2].score = 60;
for (int i = 0; i < 3; ++i) { cout << "姓名:" << stuArray[i].name << "年龄:" << stuArray[i].age << "分数:" << stuArray[i].score << endl; } return 0; }
|
结构体指针
作用:通过指针访问结构体中的成员
利用操作符号->
可以通过结构体指针访问结构体属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| struct Student { string name; int age; int score; };
int main () { struct Student stu = {"张三", 18, 100};
struct Student *p = &stu;
cout << "姓名:" << p->name << " 年龄:" << p->age << " 分数:" << p->score << endl;
return 0; }
|
结构体嵌套结构体
作用:结构体中的成员可以是另一个结构体
例如:每个老师辅导一个学院,一个老师的结构体中,记录一个学生的结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| 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 = 10000; t.name = "老王"; t.age = 50; t.stu.name = "小王"; t.stu.age = 20; t.stu.score = 60;
cout << "老师编号:" << t.id << " 老师姓名:" << t.name << " 老师年龄:" << t.age << endl << "学生姓名:" << t.stu.name << " 学生年龄:" << t.stu.age << " 学生分数:" << t.stu.score << endl;
return 0; }
|
总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题
结构题做函数参数
作用:将结构体作为参数向函数中传递
传递方式有两种:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| struct Student { string name; int age; int score; };
void printStudent1(struct Student s){ s.name = "王五"; cout << "姓名:" << s.name << " 年龄:" << s.age << " 分数:" << s.score << endl; }
void printStudent2(struct Student *s){ s -> name = "李四"; cout << "姓名:" << s -> name << " 年龄:" << s -> age << " 分数:" << s -> score << endl; }
int main () {
struct Student s; s.name = "张三"; s.age = 20; s.score = 85; cout << "姓名:" << s.name << " 年龄:" << s.age << " 分数:" << s.score << endl; printStudent1(s); printStudent2(&s); cout << "姓名:" << s.name << " 年龄:" << s.age << " 分数:" << s.score << endl; return 0; }
|
结构体中const使用场景
作用:用const来防止误操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| struct Student { string name; int age; int score; };
void printStudents(const struct Student *s){ cout << "(printStudents)姓名:" << s->name << " 年龄:" << s->age << " 分数:" << s->score << endl; }
int main () {
struct Student s = {"张三", 15, 70};
printStudents(&s); cout << "(main)姓名:" << s.name << " 年龄:" << s.age << " 分数:" << s.score << endl;
return 0; }
|
结构体案例
案例1
案例描述:
学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下
设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员
学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值
最终打印出老师数据以及所带的学生数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| struct Student { string name; int score; }; struct Teacher { string name; struct Student students[5]; };
void allocateSpace(struct Teacher teacher[],int len) { string nameSeed = "ABCDE"; for (int i = 0; i < len; ++i) { teacher[i].name = "Teacher_"; teacher[i].name += nameSeed[i]; for (int j = 0; j < 5; ++j) { teacher[i].students[j].name = "Student_"; teacher[i].students[j].name += nameSeed[j]; teacher[i].students[j].score = rand() % 61 + 40; } }
} int main () { srand((unsigned int) time(NULL));
struct Teacher teachers[3]; int len = sizeof(teachers) / sizeof(teachers[0]); allocateSpace(teachers,3);
for (int i = 0; i < len; ++i) { cout << "教师姓名:" << teachers[i].name << endl; for (int j = 0; j < 5; ++j) { cout << "\t学生姓名:" << teachers[i].students[j].name << " 分数:" << teachers[i].students[j].score << endl; } } return 0; }
|
案例2
案例描述:
设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。
通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排列,最终打印排序后的结果。
五名英雄信息如下:
1 2 3 4 5
| {"刘备",23,"男"}, {"关羽",22,"男"}, {"张飞",20,"男"}, {"赵云",21,"男"}, {"貂蝉",19,"女"}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| struct Hero { string name; int age; string sex; };
void bubbleSortHero(struct Hero heroArray[],int len) { for (int i = 0; i < len; ++i) { for (int j = 0; j < len - i - 1; ++j) { if (heroArray[j].age > heroArray[j + 1].age){ struct Hero tempHero = heroArray[j]; heroArray[j] = heroArray[j + 1]; heroArray[j + 1] = tempHero; } } } }
void printHero(struct Hero heroArray[], int len) { for (int i = 0; i < len; ++i) { cout << "姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age << " 性别:" << heroArray[i].sex << endl; } }
int main () { struct Hero heroArray[5] = { {"刘备",23,"男"}, {"关羽",22,"男"}, {"张飞",20,"男"}, {"赵云",21,"男"}, {"貂蝉",19,"女"}, }; int len = sizeof(heroArray) / sizeof(heroArray[0]); bubbleSortHero(heroArray,len);
printHero(heroArray,len);
return 0; }
|