嵌入式Qt开发C++基础编程
文章目录
- 嵌入式Qt开发C++基础编程
-
- 1、初识C++
- 2、数据类型、运算符和表达式
- 3、控制结构
- 4、数组、指针、引用和结构体
- 5、函数
-
- [1. 函数定义和调用](#1. 函数定义和调用)
- [2. 函数参数](#2. 函数参数)
- [3. 函数的返回值](#3. 函数的返回值)
- [4. 函数指针](#4. 函数指针)
- 5.函数传参
-
- [1. 值传递(Pass by Value)](#1. 值传递(Pass by Value))
- [2. 地址传递(Pass by Reference)](#2. 地址传递(Pass by Reference))
1、初识C++
c++标准输出 cout ,endl 换行。
c++
#include "iostream"
using namespace std;
/*
* 主函数:程序的入口点
* 参数:无
* 返回值:int类型,表示程序的退出状态
*/
int main()
{
// 输出"c++"到标准输出流
cout<<"c++"<<endl;
// 程序正常退出,返回0
return 0;
}
2、数据类型、运算符和表达式
C++ 是一种强类型的编程语言,它支持多种数据类型、运算符和表达式。下面是对这些主题的简要概述:
数据类型
C++ 中的数据类型可以分为几大类:
- 基本数据类型:
- 整数类型:
int
,short
,long
,long long
(以及它们的无符号版本,如unsigned int
)- 浮点数类型:
float
,double
,long double
- 字符类型:
char
(可以是有符号的或无符号的,具体取决于编译器)- 宽字符类型:
wchar_t
(用于存储宽字符,如 Unicode 字符)- 布尔类型:
bool
(只能取true
或false
)
- 复合数据类型:
- 数组:存储相同类型元素的固定大小序列。
- 结构体(
struct
):允许你将多个不同类型的变量组合成一个单一的类型。- 联合体(
union
):一种特殊的数据结构,允许你在相同的内存位置存储不同的数据类型。- 类(
class
):面向对象编程的基础,用于创建自定义的数据类型。- 枚举(
enum
):一种用户定义的数据类型,它包含一组命名的整数值。
- 指针类型 :指针是一个变量,其值为另一个变量的地址。所有指针类型的通用形式是
type*
,其中type
是指针所指向的变量的数据类型。- 引用类型:引用是变量的别名,它允许你使用不同的名称来访问同一个变量。引用必须在声明时初始化,并且之后不能重新绑定到另一个变量。
- 空类型 :
void
表示无类型。它经常用于不返回任何值的函数或指向任意类型的指针。运算符
C++ 中的运算符用于执行各种操作,如算术运算、比较、逻辑运算、位运算等。以下是一些主要的运算符类别:
- 算术运算符 :
+
,-
,*
,/
,%
(取模)- 关系运算符 :
==
,!=
,>
,<
,>=
,<=
- 逻辑运算符 :
&&
(逻辑与)、||
(逻辑或)、!
(逻辑非)- 位运算符 :
&
(按位与)、|
(按位或)、^
(按位异或)、~
(按位取反)、<<
(左移)、>>
(右移)- 赋值运算符 :
=
(简单赋值)、+=
、-=
、*=
、/=
等(复合赋值)- 条件运算符 (三元运算符):
? :
- 指针和引用运算符 :
&
(取地址)、*
(解引用)- 范围解析运算符 (作用域解析运算符):
::
- 成员访问运算符 :
.
(成员访问)、->
(通过指针访问成员)- 递增和递减运算符 :
++
(递增)、--
(递减)- 类型转换运算符 :
static_cast
,dynamic_cast
,const_cast
,reinterpret_cast
(这些是 C++ 特有的类型转换运算符)表达式
表达式是由运算符和操作数组成的语句,用于计算一个值。例如,
x + y
是一个表达式,其中+
是运算符,x
和y
是操作数。表达式的结果取决于其组成部分的类型和值,以及所使用的运算符。在 C++ 中,表达式的计算遵循特定的优先级和结合性规则。例如,乘法和除法的优先级高于加法和减法,而括号可以用来改变默认的优先级。此外,赋值运算符的结合性是从右到左的,这意味着在链式赋值表达式中(如
a = b = c
),右侧的赋值会首先执行。
cin 标准输入
c++
#include "iostream"
using namespace std;
int main()
{
string name;
int age;
float high;
cout << "请输入您的姓名:";
cin >> name;
cout << "请输入您的身高:";
cin >> high;
cout << "请输入您的年龄:";
cin >> age;
cout << "---------" << endl;
cout << "信息输入完成,您的信息如下:" << endl;
cout << "姓名:" << name << endl;
cout << "身高:" << high <<endl;
cout << "年龄:" << age << endl;
}
字面常量
c++
#include "iostream"
using namespace std;
int main()
{
//整型
//21;
//实型(小数)
// 173.3;
//字符型
//'a';
//字符串型
//"hello!";
cout << 21 << endl;
cout << 173.3 << endl;
cout << 'a' << endl;
cout << "hello!" << endl;
return 0;
}
变量的基本类型
c++
#include "iostream"
#include "windows.h"
using namespace std;
int main()
{
SetConsoleOutputCP(CP_UTF8);
int age = 21 , lav = 56; //整型
float hi = 180.5; //实型
char fu_1 = ','; //字符型
char fu_2 = '.'; //字符串型
string name = "李华";
cout << "我是" << name << fu_1 << "今年" << age << "岁" << fu_2 <<endl;
cout << "身高" << hi << "cm" << "体重" << lav << "KG" << endl;
return 0;
}
比较运算符和字符串的比较运算
c++
#include "iostream"
#include "cstring"
using namespace std;
int main()
{
int num1 = 3, num2 = 5;
bool r1 = num1 == num2; //假为0 ; 真为1
cout << r1 << endl;
//C语言型字符串char *str = "hello" char arr[] = "hello"
char *str = "hello";
char arr[] = "hello";
// 两者都为C语言型字符串时,不能用比较运算符 只有一个为C++类型才可以
// 0表示相等 -1 str < arr 1:str > arr;
cout << strcmp(str,arr) << endl;
//C++类型字符串
string str1 = "hello";
cout << (str == str1) << endl;
return 0;
}
三元运算符
c++
// 主函数:根据两次输入的成绩判断是否购买糖果。
//
// 无参数输入。
// 无返回值。
//
#include "iostream"
using namespace std;
int main()
{
// 定义变量以存储两次成绩
int grade , grade1;
// 输入第一次成绩
cout << "输入第一次成绩:";
cin >> grade;
// 输入第二次成绩
cout << "请输入第二次成绩:";
cin >> grade1;
// 根据两次成绩的比较结果,决定是否购买糖果
string result = grade > grade1 ? "不买糖" : "买糖";
// 输出决定结果
cout << result << endl;
return 0;
}
字符串的拼接 使用运算符更新
c++
#include "iostream"
using namespace std;
//输入一个字符串,输出字符串的拼接
int main(){
string arr = "123456789";
string arr2 = "abcdefgh";
int arr1 = 15;
string arr3 = arr + arr2 + to_string(arr1);
cout << arr3 << endl;
return 0;
}
3、控制结构
C++的控制结构用于控制程序的执行流程,包括条件语句、循环语句和跳转语句。以下是这些控制结构的详细用法:
1. 条件语句
if-else
- 基本语法:
cpp
if (condition) {
// 如果条件为真,执行这里的代码块
} else {
// 如果条件为假,执行这里的代码块
}
- 实例:
cpp
#include <iostream>
int main() {
int num = 5;
if (num > 0) {
std::cout << "Number is positive." << std::endl;
} else {
std::cout << "Number is non-positive." << std::endl;
}
return 0;
}
switch
- 基本语法:
cpp
switch (expression) {
case value1:
// 如果expression的值等于value1,执行这里的代码块
break;
case value2:
// 如果expression的值等于value2,执行这里的代码块
break;
// ... 其他情况
default:
// 如果expression的值不匹配任何case,执行这里的代码块
break;
}
- 实例:
cpp
#include <iostream>
int main() {
int day = 3;
switch (day) {
case 1:
std::cout << "Monday" << std::endl;
break;
case 2:
std::cout << "Tuesday" << std::endl;
break;
case 3:
std::cout << "Wednesday" << std::endl;
break;
default:
std::cout << "Invalid day" << std::endl;
}
return 0;
}
2. 循环语句
for
- 基本语法:
cpp
for (initialization; condition; increment/decrement) {
// 循环体代码
}
- 实例:
cpp
#include <iostream>
int main() {
for (int i = 0; i < 10; ++i) {
std::cout << i << std::endl;
}
return 0;
}
while
- 基本语法:
cpp
while (condition) {
// 循环体代码
}
- 实例:
cpp
#include <iostream>
int main() {
int i = 0;
while (i < 10) {
std::cout << i << std::endl;
++i;
}
return 0;
}
do-while
- 基本语法:
cpp
do {
// 循环体代码
} while (condition);
- 实例:
cpp
#include <iostream>
int main() {
int i = 0;
do {
std::cout << i << std::endl;
++i;
} while (i < 10);
return 0;
}
3. 跳转语句
break
-
用途 :用于终止最近的
while
、do-while
、for
或switch
语句。 -
实例 (与
for
循环结合使用):
cpp
#include <iostream>
int main() {
for (int i = 0; i < 10; ++i) {
if (i == 5) {
break; // 当 i 等于 5 时,终止循环
}
std::cout << i << std::endl;
}
return 0;
}
continue
-
用途:用于跳过循环体中的剩余部分,并立即开始下一次迭代。
-
实例 (与
for
循环结合使用):
cpp
#include <iostream>
int main() {
for (int i = 0; i < 10; ++i) {
if (i == 5) {
continue; // 当 i 等于 5 时,跳过本次循环的剩余部分
}
std::cout << i << std::endl;
}
return 0;
}
goto(不推荐使用)
由于 goto 语句可能导致代码难以理解和维护,因此现代编程中通常不推荐使用它。但在某些特殊情况下,它仍然可能存在。
cpp
#include <iostream>
int main() {
int i = 0;
if (i == 0) {
goto skip; // 跳转到标签 "skip"
}
std::cout << "This will not be printed." << std::endl;
skip: // 标签 "skip"
std::cout << "This will be printed." << std::endl;
return 0;
}
4、数组、指针、引用和结构体
1.数组
在C++中,数组是用于存储固定数量相同类型元素的集合。这些元素在内存中连续存储,这意味着数组的地址是连续的,并可以通过索引来访问。数组在C++中是一个基本的数据结构,广泛应用于各种编程任务中。
1.声明数组
在C++中,可以使用以下语法来声明数组:
cpp
dataType arrayName[arraySize];
其中,dataType
是数组中元素的类型(如 int
, float
, char
等),arrayName
是数组的名称,arraySize
是一个常量表达式,表示数组中元素的数量。
下面是个数组定义实例
cpp
#include "iostream"
#include "random"
using namespace std;
//定义指定范围的随机数
int random(int min, int max) {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<int> dis(min, max);
return dis(gen);
}
int GuessArr[10];
int main() {
int num = random(1, 10);
int count = 0;
for (int i = 0; i <10 ; ++i) {
cout << "请输入第" << i + 1 << "个数字:";
cin >> GuessArr[i];
}
for (int j : GuessArr) {
cout << j << "\t";
}
for (int k : GuessArr) {
if (k == num)
{
count++;
}
}
cout << "猜对了" << count << "个" << endl;
return 0;
}
数组的名称实质上数组第一个元素的地址。
除此之外,数组还有一维数组,二维数组以及多维数组。
cpp
int arrname[2][2] = {{1 , 2},{3 , 4}};
可以理解拆分为了两个一维数组的嵌套,这两个一维数组都是两个元素。
2.初始化数组
在声明数组时,可以为其指定初始值。这可以在声明时通过花括号 {}
来完成。
cpp
int myArray[5] = {1, 2, 3, 4, 5};
如果初始化时提供的元素数量少于数组的大小,那么剩余的元素将被初始化为该类型的默认值(对于内置类型,通常是0或空字符)。
cpp
int anotherArray[10] = {1, 2, 3}; // 其他元素将被初始化为0
3.访问数组元素
可以通过索引来访问数组中的元素。索引从0开始,到数组大小减1结束。
cpp
std::cout << myArray[0]; // 输出1
std::cout << myArray[4]; // 输出5
std::cout << arrname[0][0] // 输出1
4.数组长度的计算
数组长度可以通过函数进行计算
cpp
sizeof(arr); // 通过sizeof 计算数组的总长度
sizeof(arr[0]); // 计算单个元素的长度
length = sizeof(arr) / sizeof(arr[0]); // 数组元素的个数
6.数组的遍历
数组在遍历的过程中可以通过for循环遍历。
cpp
int arrname[4] = {1 , 2 , 3 , 4};
for(int i = 0;i < 4;i++)
{
cout << arrname[i] << endl;
}
也可以通过C++的新标准进行遍历,如:
cpp
for (int j : GuessArr) {
cout << j << "\t";
} // 这里的GuessArr为数组名
遍历多维数组则需要多个for循环嵌套。
cpp
int arr[2][2] = {{1,2},{3,4}};
for(int i = 0;i < sizeof(arr) / sizeof(arr[0]);i++){
for(int j = 0; j < sizeof(arr[0]) / sizeof(arr[0][0]);j ++){
cout << arr[i][j];
}
}
多维数组遍历就需要多少层的遍历。
7.数组越界
需要注意的是,C++不会自动检查数组索引是否越界。如果尝试访问超出数组范围的元素,将会导致未定义的行为,这通常是严重的错误。因此,在编写代码时,应始终确保索引在有效范围内。
2.结构体
结构体(struct)是一种复合数据类型,它允许你将多个不同类型的变量组合成一个单独的类型。
1.定义结构体
使用struct
关键字来定义结构体。结构体内部可以包含多个不同类型的变量(称为成员)。
cpp
struct 结构体名称 {
数据类型 成员变量1;
数据类型 成员变量2;
// ...
};
2.访问结构体成员
通过结构体变量使用.
操作符来访问结构体中的成员。
cpp
结构体变量.成员变量名;
3.结构体变量的定义和初始化
可以在定义结构体变量的同时初始化其成员。
cpp
struct 结构体名称 变量名 = {初始化值1, 初始化值2, ...};
如果结构体变量在定义时没有初始化,其成员将自动被初始化为0(对于基本类型)或空指针(对于指针类型)。
4.定义结构体
首先定义结构体类型和成员。
cpp
struct Student {
char name[50];
int age;
float score;
};
5.创建结构体变量
使用结构体类型创建变量,并初始化(如果需要)。
cpp
struct Student stu1 = {"Alice", 20, 90.5};
struct Student stu2; // 未初始化
6.访问和修改成员
通过结构体变量来访问和修改其成员。
cpp
printf("Name: %s\n", stu1.name);
stu1.age = 21;
7.结构体数组
可以定义结构体数组,用于存储多个具有相同类型属性的对象。
cpp
struct Student students[3] = {
{"Alice", 20, 90.5},
{"Bob", 21, 85.0},
{"Charlie", 19, 92.0}
};
8.结构体指针
可以使用指针来访问结构体变量,这在处理大型结构体或需要动态分配内存时非常有用。
cpp
struct Student *p = &stu1;
p -> name;// 使用->操作符访问指针指向的结构体成员
9.结构体嵌套
一个结构体的成员可以是另一个结构体类型。
cpp
struct Address {
char street[100];
char city[50];
char country[50];
};
struct Person {
char name[50];
int age;
struct Address address; // 嵌套的结构体成员
};
在C++中,结构体是一种非常有用的工具,它允许你组织和管理相关的数据。通过使用结构体,你可以创建更复杂的数据类型,并编写更易于理解和维护的代码。
3、指针
1.指针的定义
在C++中,指针是一个变量,其值为另一个变量的地址。通过使用指针,你可以直接访问和操作内存中的特定位置。
以下是C++中指针的基本定义方式:
cpp
// 定义一个整数类型的指针变量p
int* p;
// 或者在定义的同时初始化
int x = 10;
int* ptr = &x; // ptr现在指向x的地址
在上面的代码中:
int* p;
定义了一个名为p
的指针变量,它可以存储一个int
类型变量的地址。int* ptr = &x;
定义了一个名为ptr
的指针变量,并立即将其初始化为x
的地址(使用&
运算符获取x
的地址)。
一旦你有了指向某个变量的指针,你就可以使用该指针来访问或修改该变量的值。例如:
cpp
*ptr = 20; // 使用*运算符来访问ptr指向的值,并将其设置为20
std::cout << x; // 输出: 20,因为ptr指向x,我们改变了x的值
需要注意的是,指针操作应该非常小心,因为不正确的指针操作可能导致程序崩溃、数据损坏或其他未定义的行为。确保在使用指针之前已经正确地初始化了它,并且在不再需要它时将其设置为 nullptr
或将其删除(如果是指向动态分配的内存)。
2.指针的运算
指针变量存放的是变量的地址,对变量进行*(解引用)运算,可以获得该地址下变量的值。
cpp
#include "iostream"
using namespace std;
//指针变量存放的是变量的地址,对变量进行*运算,可以获得该地址下变量的值
int main(){
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
char str[10] = {'a','b','c','d','e','f','g','h','i','j'};
int *p = arr;
char *q = str;
for(int i = 0;i < 10;i++){
cout << *p << " " << *q << endl;
p++;
q++;
}
return 0;
}
3.结构体指针
在C++中,结构体(通常被称为类或结构体,但在C++中更常使用"类"这一术语)是一种复合数据类型,它允许你将多个不同类型的变量组合成一个单一的类型。然而,为了与C语言保持一致,C++也支持传统的struct
关键字来定义结构体。
当你使用结构体指针时,你实际上是在指向一个结构体类型的内存地址。这允许你通过指针来访问和修改结构体的成员。
以下是一个使用C++结构体指针的简单示例:
cpp
#include <iostream>
// 定义一个结构体
struct Student {
std::string name;
int age;
float gpa;
};
int main() {
// 在堆上分配一个Student结构体的实例
Student* ptr = new Student;
// 通过指针访问和修改结构体的成员
ptr->name = "Alice";
ptr->age = 20;
ptr->gpa = 3.5f;
// 打印结构体的内容
std::cout << "Name: " << ptr->name << std::endl;
std::cout << "Age: " << ptr->age << std::endl;
std::cout << "GPA: " << ptr->gpa << std::endl;
// 释放分配的内存
delete ptr;
return 0;
}
在这个示例中,我们首先定义了一个名为Student
的结构体,它包含三个成员:一个字符串name
,一个整数age
和一个浮点数gpa
。然后,在main
函数中,我们使用new
操作符在堆上分配了一个Student
结构体的实例,并将返回的指针存储在ptr
中。接下来,我们通过ptr
来访问和修改结构体的成员。最后,我们使用delete
操作符来释放分配的内存。
在访问结构体指针的时要使用->
操作。
4.结构体指针数组
在C++中,可以创建一个结构体指针数组,这意味着数组的每个元素都是一个指向结构体的指针。这种数据结构在需要存储多个结构体实例,但可能不希望在创建时立即分配所有内存的情况下特别有用。
以下是一个使用C++结构体指针数组的示例:
cpp
#include <iostream>
#include <string>
// 定义一个结构体
struct Student {
std::string name;
int age;
float gpa;
};
int main() {
// 创建一个包含5个Student指针的数组
Student* students[5];
// 为数组中的每个元素分配内存并初始化
for (int i = 0; i < 5; ++i) {
students[i] = new Student;
// 假设我们有一些数据
students[i]->name = "Student " + std::to_string(i + 1);
students[i]->age = 20 + i;
students[i]->gpa = 3.0f + (i % 3) * 0.5f; // 为了使GPA不同
}
// 遍历数组并打印每个学生的信息
for (int i = 0; i < 5; ++i) {
std::cout << "Name: " << students[i]->name << std::endl;
std::cout << "Age: " << students[i]->age << std::endl;
std::cout << "GPA: " << students[i]->gpa << std::endl;
std::cout << "-----" << std::endl;
}
// 释放每个结构体实例占用的内存
for (int i = 0; i < 5; ++i) {
delete students[i];
}
return 0;
}
在这个示例中,我们首先定义了一个结构体Student
。在main
函数中,我们创建了一个名为students
的数组,该数组包含5个指向Student
的指针。然后,我们使用一个循环为数组中的每个指针分配内存,并初始化每个结构体的成员。接下来,我们遍历数组并打印每个学生的信息。最后,我们使用另一个循环来释放每个结构体实例占用的内存。
注意,由于我们使用了new
来分配内存,因此必须使用delete
来释放它,以防止内存泄漏。在这个例子中,我们在创建和销毁每个Student
实例时都使用了显式的内存管理。然而,在更复杂的应用程序中,使用智能指针(如std::unique_ptr
或std::shared_ptr
)可能是一个更好的选择,因为它们可以自动管理内存,并减少因忘记释放内存而导致的错误。
cpp
#include "iostream"
using namespace std;
struct Student{
string name;
int age{};
int score{};
};
int main(){
struct Student stu[3] = { {"张三", 18, 100},
{"李四", 19, 99},
{"王五", 20, 98}};
struct Student *p = stu;
// for (int i = 0; i < 3; ++i) {
// cout << p->name << " " << p->age << " " << p->score << endl;
// p++;
// }
for (int i = 0; i < 3; ++i) {
cout << p[i].name << " " << p[i].age << " " << p[i].score << endl;
}
auto *p2 = new struct Student[3] { {"张三", 18, 100},
{"李四", 19, 99},
{"王五", 20, 98}};
for (int i = 0; i < 3; ++i) {
cout << p2[i].name << " " << p2[i].age << " " << p2[i].score << endl;
}
delete []p2;
return 0;
}
在这个示例中,定义了一个指向结构体数组的指针,此时访问时,p[i]
中的元素是结构体,故需要使用.
操作。
5.数组元素的插入
数组元素的插入实质上是将原始数组的元素以及需要添加的元素传入新的数组。
cpp
//
// Created by 86189 on 2024/5/24.
//
#include "iostream"
using namespace std;
int main(){
int *arr = new int[10] {1,2,3,4,5,6,7,8,9,10};
int *NewArr = new int[12];
int offset = 0;
for (int i = 0; i < 12; i++) {
if (i == 1)
{
offset++;
NewArr[i] = 2;
continue;
}
else if (i == 4)
{
offset++;
NewArr[i] = 5;
continue;
}
NewArr[i] = arr[i-offset];
}
for (int i = 0; i < 10; ++i) {
cout << arr[i] << " ";
}
cout << endl;
for (int i = 0; i < 12; ++i) {
cout << NewArr[i] << " ";
}
delete []arr , delete []NewArr;
return 0;
}
实例中定义了中间值offset
来表示数组元素插入过程中插入元素的个数,例如示例中在1位置和4位置插入,则原始数组下标为1的元素则需要填入新数组下标为2的位置。
5.数组元素的删除
移除数组元素本质上仍然是将原始数组减少元素后,传入新的数组。
cpp
#include "iostream"
using namespace std;
int main(){
//定义一个数组,并赋值
int *arr = new int [5] {1,2,3,4,5};
int *NewArr = new int [3];
int offset = 0;
for(int i = 0; i < 5; i++){
if(i == 0 || i == 3){
offset++;
continue;
}
NewArr[i-offset] = arr[i];
}
for(int i = 0; i < 3; i++){
cout << NewArr[i] << " ";
}
delete [] arr , delete [] NewArr;
return 0;
}
4.常量指针
const
用来修饰常量指针。
cpp
#include "iostream"
using namespace std;
int main(){
int num1 = 10 , num2 = 20;
//指向常量的指针 存储值不可变 指向可变
const int *p = &num1;
//*P = 100; 不可更改值
p = &num2;// 可以更改指针指向
cout << *p << endl;
//常量指针
int * const p1 = &num1;
*p1 = 100; // 可以更改值
// p1 = &num2; 不可更改指针指向
cout << *p1 << endl;
//指向常量的常量指针
const int * const p2 = &num1;
//*P2 = 100;值不可变
//p2 = &num2; 指针指向不可变
cout << *p2 << endl;
return 0;
}
5.new运算符
new运算符用来开辟内存空间。但需要自己手动删除。
例如:开辟数组内存空间。
cpp
int *arr = new int [5] {1,2,3,4,5};
int *NewArr = new int [3];
delete [] arr , delete [] NewArr;
开辟指针空间。
cpp
Student* ptr = new Student;
delete ptr;
4、引用
引用不建议作为函数返回值。
引用可以看作为变量取得别名,操作引用变量等同于操作原始变量,由于引用的这种特性,则引用在定义时必须赋值,即初始化。
cpp
#include "iostream"
using namespace std;
//编写应用引用的示例代码
int main(){
int a = 10;
int &b = a;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
b = 20; //改变引用的值,也会改变原始变量a的值
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
5、函数
当涉及到C++的基础函数知识时,以下是一些核心概念和示例:
1. 函数定义和调用
定义:
cpp
// 定义一个函数,计算两个整数的和
int add(int a, int b) {
return a + b;
}
// 主函数
int main() {
// 调用函数
int sum = add(5, 3);
std::cout << "Sum: " << sum << std::endl;
return 0;
}
2. 函数参数
示例:带有参数的函数
cpp
// 定义一个函数,计算两个数的乘积
int multiply(int x, int y) {
return x * y;
}
// 主函数
int main() {
// 调用函数,传递参数
int result = multiply(7, 2);
std::cout << "Result: " << result << std::endl;
return 0;
}
3. 函数的返回值
示例:返回值的函数
cpp
// 定义一个函数,判断一个数是否为偶数
bool isEven(int num) {
return num % 2 == 0;
}
// 主函数
int main() {
// 调用函数,并使用返回值
bool isEvenNumber = isEven(10);
if (isEvenNumber) {
std::cout << "10 is even." << std::endl;
} else {
std::cout << "10 is not even." << std::endl;
}
return 0;
}
4. 函数指针
示例:使用函数指针
cpp
// 定义两个函数
void func1() {
std::cout << "Function 1 called." << std::endl;
}
void func2() {
std::cout << "Function 2 called." << std::endl;
}
// 主函数
int main() {
// 定义函数指针
void (*funcPtr)();
// 分配函数给指针
funcPtr = func1;
funcPtr(); // 输出 "Function 1 called."
funcPtr = func2;
funcPtr(); // 输出 "Function 2 called."
return 0;
}
5.函数传参
1. 值传递(Pass by Value)
值传递形参无法修饰实参,在值传递中,函数接收的是参数值的副本。这意味着在函数内部对参数所做的任何修改都不会影响到传递给函数的原始变量。
示例:
cpp
#include <iostream>
void modifyValue(int num) {
num = num + 10; // 修改的是num的副本,原始变量不受影响
std::cout << "Inside function: " << num << std::endl;
}
int main() {
int x = 5;
std::cout << "Before function call: " << x << std::endl;
modifyValue(x); // 传递x的值给函数
std::cout << "After function call: " << x << std::endl; // x的值仍然是5
return 0;
}
2. 地址传递(Pass by Reference)
在地址传递中,函数接收的是参数的地址(引用),而不是参数值的副本。因此,在函数内部对参数所做的任何修改都会影响到传递给函数的原始变量。
示例:
cpp
#include <iostream>
void modifyReference(int& num) { // 使用&表示引用传递void mod(int * p)
num = num + 10; // 修改的是原始变量
std::cout << "Inside function: " << num << std::endl;
}
int main() {
int x = 5;
std::cout << "Before function call: " << x << std::endl;
modifyReference(x); // 传递x的引用给函数modi(&x)
std::cout << "After function call: " << x << std::endl; // x的值现在是15
return 0;
}
注意事项:
- 引用传递通常用于大型对象或需要修改原始数据的场景,因为它可以避免复制对象,从而提高效率。
- 引用传递时,必须确保传递给函数的引用是有效的,并且引用在函数执行期间不会失效(例如,引用的对象没有被销毁)。
- 引用传递也可以用于常量引用(
const int&
),这样可以在不修改原始数据的情况下传递数据。
常量引用示例:
cpp
#include <iostream>
void printValue(const int& num) { // 使用const表示引用不会修改数据
std::cout << "Inside function: " << num << std::endl;
}
int main() {
int x = 5;
printValue(x); // 传递x的常量引用给函数
return 0;
}
在这个例子中,printValue
函数接收一个常量引用,这意味着它不能修改num
的值。这增加了代码的安全性,因为它防止了函数意外地修改原始数据。