变量的概念: 变量是存储数据的内存位置,通过变量名访问这些数据。在C++中,使用关键字 int
、float
、double
、char
、bool
等来声明变量。
// 变量声明
int age; // 声明一个整数变量,变量名为age
float salary; // 声明一个单精度浮点数变量,变量名为salary
char grade; // 声明一个字符变量,变量名为grade
bool isStudent; // 声明一个布尔变量,变量名为isStudent
变量的初始化: 变量可以在声明时进行初始化,也可以稍后在代码中进行初始化。
int age = 25; // 初始化整数变量age为25
float salary = 50000.5; // 初始化单精度浮点数变量salary为50000.5
char grade = 'A'; // 初始化字符变量grade为'A'
bool isStudent = true; // 初始化布尔变量isStudent为true
整数类型:
int
:通常表示32位整数。short
:通常表示16位整数。long
:通常表示32或64位整数。int integerVar = 10;
short shortVar = 32767;
long longVar = 2147483647L;
浮点数类型:
float
:单精度浮点数。double
:双精度浮点数。float floatVar = 3.14f;
double doubleVar = 2.71828;
字符类型:
char
:用于存储单个字符。char charVar = 'A';
布尔类型:
bool
:表示真或假。bool boolVar = true;
常量的概念: 常量是其值在程序执行期间不能被修改的标识符。在C++中,使用关键字 const
来声明常量。
const int MAX_SIZE = 100; // 声明一个整数常量MAX_SIZE,并赋值为100
const float PI = 3.14159; // 声明一个浮点数常量PI,并赋值为3.14159
const char NEW_LINE = '\n'; // 声明一个字符常量NEW_LINE,并赋值为换行符
注意: 常量一旦被赋值就不能再修改。它提高了程序的可读性和维护性,同时帮助编译器进行优化。
常见的算术运算符包括:
+
:加法-
:减法*
:乘法/
:除法%
:取余数int a = 10, b = 3;
int sum = a + b; // 13
int difference = a - b; // 7
int product = a * b; // 30
int quotient = a / b; // 3
int remainder = a % b; // 1
关系运算符用于比较两个值的关系,返回布尔值(true或false):
==
:等于!=
:不等于<
:小于>
:大于<=
:小于等于>=
:大于等于int x = 5, y = 10;
bool isEqual = (x == y); // false
bool isNotEqual = (x != y); // true
bool isLessThan = (x < y); // true
bool isGreaterThan = (x > y); // false
bool isLessOrEqual = (x <= y);// true
bool isGreaterOrEqual = (x >= y); // false
逻辑运算符用于连接两个或多个布尔表达式,返回布尔值:
&&
:逻辑与(AND)||
:逻辑或(OR)!
:逻辑非(NOT)bool condition1 = true, condition2 = false;
bool resultAND = (condition1 && condition2); // false
bool resultOR = (condition1 || condition2); // true
bool resultNOT = !condition1; // false
位运算符用于对二进制位进行操作:
&
:按位与|
:按位或^
:按位异或~
:按位取反<<
:左移>>
:右移int num1 = 5, num2 = 3;
int resultAND = num1 & num2; // 1 (二进制 0101 & 0011)
int resultOR = num1 | num2; // 7 (二进制 0101 | 0011)
int resultXOR = num1 ^ num2; // 6 (二进制 0101 ^ 0011)
int resultNOT = ~num1; // -6 (二进制 ~0101)
int resultLeftShift = num1 << 1; // 10 (二进制 0101 左移1位)
int resultRightShift = num1 >> 1; // 2 (二进制 0101 右移1位)
赋值运算符用于给变量赋值:
=
:赋值+=
:加等于-=
:减等于*=
:乘等于/=
:除等于%=
:取余等于int num = 10;
num += 5; // num 现在为 15
num -= 3; // num 现在为 12
num *= 2; // num 现在为 24
num /= 4; // num 现在为 6
num %= 2; // num 现在为 0
条件运算符(三元运算符)用于根据条件选择值:
condition ? expression1 : expression2
int a = 5, b = 10;
int maxNumber = (a > b) ? a : b; // maxNumber 等于 10
if语句: 用于基于某个条件执行代码块。
int x = 10;
if (x > 0) {
// 条件为真时执行的代码
cout << "x 是正数" << endl;
}
if-else语句: 在条件为假时执行备选代码块。
int y = -5;
if (y > 0) {
cout << "y 是正数" << endl;
} else {
// 条件为假时执行的代码
cout << "y 是负数或零" << endl;
}
else if语句: 在多个条件中选择执行一个代码块。
int z = 0;
if (z > 0) {
cout << "z 是正数" << endl;
} else if (z < 0) {
cout << "z 是负数" << endl;
} else {
cout << "z 是零" << endl;
}
switch语句: 根据表达式的值,选择执行匹配的代码块。
int day = 3;
switch (day) {
case 1:
cout << "星期一" << endl;
break;
case 2:
cout << "星期二" << endl;
break;
case 3:
cout << "星期三" << endl;
break;
// 更多的case语句
default:
cout << "未知的日期" << endl;
}
注意: 在每个case块结束后使用break
语句,否则会继续执行下一个case。
while循环: 在条件为真时执行代码块,然后重复执行。
int i = 0;
while (i < 5) {
// 循环体内的代码
cout << i << " ";
i++;
}
// 输出结果:0 1 2 3 4
do-while循环: 先执行一次代码块,然后在条件为真时重复执行。
int j = 0;
do {
// 循环体内的代码
cout << j << " ";
j++;
} while (j < 5);
// 输出结果:0 1 2 3 4
for循环: 用于指定循环次数的循环结构。
for (int k = 0; k < 5; k++) {
// 循环体内的代码
cout << k << " ";
}
// 输出结果:0 1 2 3 4
函数的定义: 函数是一段完成特定任务的代码块。它可以接受输入(参数),执行操作,然后返回输出。
// 函数的定义
int add(int a, int b) {
return a + b;
}
函数的声明: 函数声明是在使用函数之前提供函数原型的一种方式。
// 函数的声明
int add(int a, int b);
在上述例子中,add
函数接受两个整数参数,并返回它们的和。
调用带参数的函数:
int result = add(5, 3);
cout << "5 + 3 = " << result << endl;
调用无参数的函数:
void showMessage() {
cout << "Hello, World!" << endl;
}
// 调用无参数的函数
showMessage();
函数的返回值: 使用 return
语句返回函数的结果。
int multiply(int x, int y) {
return x * y;
}
int result = multiply(4, 7);
cout << "4 * 7 = " << result << endl;
函数的参数: 函数可以接受多个参数,可以是不同的数据类型。
double calculateAverage(int a, int b, int c) {
return static_cast<double>(a + b + c) / 3;
}
double average = calculateAverage(10, 20, 30);
cout << "平均值:" << average << endl;
函数的重载: 允许定义多个同名函数,但它们的参数类型或数量不同。
// 重载的 add 函数
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
// 调用不同版本的 add 函数
int resultInt = add(5, 3);
double resultDouble = add(2.5, 3.2);
函数的默认参数: 允许在调用函数时省略一些参数,这些参数将取默认值。
// 带有默认参数的函数
int power(int base, int exponent = 2) {
int result = 1;
for (int i = 0; i < exponent; i++) {
result *= base;
}
return result;
}
// 可以省略 exponent 参数,默认为 2
int result1 = power(3);
// 也可以提供 exponent 参数
int result2 = power(3, 4);
在C++中,参数的传递方式主要有三种:值传递、引用传递和指针传递。
值传递: 将参数的值传递给函数。
void modifyValue(int x) {
x = x * 2;
}
int main() {
int num = 10;
modifyValue(num);
// num 的值仍然是 10,因为在 modifyValue 函数中修改的是副本
return 0;
}
引用传递: 将参数的引用传递给函数,通过引用操作原始数据。
void modifyValueByReference(int &x) {
x = x * 2;
}
int main() {
int num = 10;
modifyValueByReference(num);
// num 的值现在变为 20,因为通过引用修改了原始数据
return 0;
}
指针传递: 将参数的地址传递给函数,通过指针操作原始数据。
void modifyValueByPointer(int *x) {
*x = *x * 2;
}
int main() {
int num = 10;
modifyValueByPointer(&num);
// num 的值现在变为 20,因为通过指针修改了原始数据
return 0;
}
常量参数: 防止在函数内修改参数的值。
void displayValue(const int x) {
// 下面的语句将会导致编译错误,因为 x 是常量参数
// x = x * 2;
cout << x << endl;
}
引用参数: 允许在函数内修改参数的值。
void modifyValueByReference(int &x) {
x = x * 2;
}
int main() {
int num = 10;
modifyValueByReference(num);
// num 的值现在变为 20,因为通过引用修改了原始数据
return 0;
}
常量引用参数: 防止在函数内修改参数的值,同时避免复制整个对象。
void displayValue(const int &x) {
// x 是常量引用参数,不能修改其值
// x = x * 2; // 编译错误
cout << x << endl;
}
一维数组的定义:
// 定义一个包含5个整数的一维数组
int numbers[5];
一维数组的初始化:
// 初始化一维数组的元素
int numbers[] = {1, 2, 3, 4, 5};
// 或者指定数组大小
int numbers[5] = {1, 2, 3, 4, 5};
多维数组的定义和初始化:
// 定义一个包含3行2列的二维数组
int matrix[3][2];
// 初始化二维数组的元素
int matrix[3][2] = {
{1, 2},
{3, 4},
{5, 6}
};
一维数组的遍历:
int numbers[] = {1, 2, 3, 4, 5};
// 使用for循环遍历一维数组
for (int i = 0; i < 5; i++) {
cout << numbers[i] << " ";
}
多维数组的遍历:
int matrix[3][2] = {
{1, 2},
{3, 4},
{5, 6}
};
// 使用嵌套的for循环遍历二维数组
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
修改数组元素的值:
int numbers[] = {1, 2, 3, 4, 5};
// 修改数组中的元素
numbers[2] = 10;
使用数组进行数学运算:
int numbers[] = {1, 2, 3, 4, 5};
int sum = 0;
// 计算数组元素的和
for (int i = 0; i < 5; i++) {
sum += numbers[i];
}
cout << "数组元素的和:" << sum << endl;
获取数组的长度:
int numbers[] = {1, 2, 3, 4, 5};
int length = sizeof(numbers) / sizeof(numbers[0]);
cout << "数组的长度:" << length << endl;
字符串是由字符组成的一系列字符序列。在C++中,有两种主要的字符串表示方式:C-style字符串(以字符数组形式存在)和C++中的string类。
C-style字符串的定义和初始化:
// 使用字符数组定义C-style字符串
char greeting[] = "Hello, World!";
C-style字符串的操作:
#include <cstring>
// 获取C-style字符串的长度
int length = strlen(greeting);
// 拼接C-style字符串
char destination[20];
strcpy(destination, greeting); // 复制greeting到destination
// 比较C-style字符串
if (strcmp(greeting, "Hello, World!") == 0) {
// 字符串相等
}
// 查找子串在C-style字符串中的位置
const char *substring = "World";
const char *result = strstr(greeting, substring);
if (result != nullptr) {
// 找到子串,result指向子串的位置
}
string类的定义和初始化:
#include <string>
// 使用string类定义字符串
std::string greeting = "Hello, World!";
string类的操作:
// 获取string的长度
int length = greeting.length();
// 拼接string
std::string anotherString = " How are you?";
std::string combined = greeting + anotherString;
// 比较string
if (greeting == "Hello, World!") {
// 字符串相等
}
// 查找子串在string中的位置
std::size_t found = greeting.find("World");
if (found != std::string::npos) {
// 找到子串,found是子串在字符串中的位置
}
字符串的拼接:
std::string str1 = "Hello";
std::string str2 = "World";
std::string result = str1 + " " + str2; // 结果为 "Hello World"
字符串的查找:
std::string sentence = "This is a sample sentence.";
std::size_t found = sentence.find("sample");
if (found != std::string::npos) {
// 找到子串
std::cout << "子串在位置 " << found << std::endl;
} else {
// 未找到子串
std::cout << "未找到子串" << std::endl;
}
字符串的替换:
std::string phrase = "I like programming in C.";
std::size_t found = phrase.find("C");
if (found != std::string::npos) {
phrase.replace(found, 1, "C++");
// 结果为 "I like programming in C++."
}
隐式类型转换是由编译器自动完成的类型转换,不需要程序员明确指定。在一些情况下,编译器会自动进行类型转换以满足表达式的要求。
int a = 5;
double b = a; // 隐式将整数类型转换为浮点数类型
显式类型转换是由程序员明确指定的类型转换,用于将一个数据类型的值转换为另一个数据类型。在C++中,有两种主要的显式类型转换方式:C风格的强制类型转换和C++中的新式类型转换。
int a = 10;
double b = (double)a; // 使用强制类型转换将整数转换为浮点数
static_cast
: 用于基本类型的转换,以及具有继承关系的指针或引用之间的转换。double x = 3.14;
int y = static_cast<int>(x); // 将浮点数转换为整数
dynamic_cast
: 用于在运行时进行安全的向下转型(仅用于有虚函数的类)。class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {};
Base* basePtr = new Derived;
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
// 安全地进行向下转型
}
const_cast
: 用于添加或删除const性质。const int value = 5;
int& ref = const_cast<int&>(value);
reinterpret_cast
: 用于进行低级别的类型转换,如指针之间的转换。int* ptr = new int;
char* charPtr = reinterpret_cast<char*>(ptr);
在C++中,一些类可以重载类型转换运算符,以便在不同类型之间进行转换。例如,可以在自定义类中重载operator int()
,使得该类的对象能够被隐式或显式地转换为整数类型。
class MyClass {
public:
operator int() const {
return value;
}
private:
int value = 42;
};
MyClass myObject;
int intValue = myObject; // 隐式类型转换
int explicitValue = static_cast<int>(myObject); // 显式类型转换
此外,C++还提供了一些标准库函数来执行类型转换,如std::stoi
(字符串转整数)、std::stod
(字符串转浮点数)等。
#include <iostream>
#include <string>
int main() {
std::string strNumber = "123";
int number = std::stoi(strNumber);
std::cout << "Converted number: " << number << std::endl;
return 0;
}
运算符重载是指通过定义新的含义,使得已有的运算符能够用于用户自定义类型的操作。C++允许对大多数运算符进行重载,包括算术运算符、关系运算符、赋值运算符等。
运算符重载使得用户自定义类型的对象可以像内置类型一样进行运算,提高了代码的可读性和灵活性。
运算符重载的语法形式如下:
return_type operator op(parameters) {
// 实现运算符操作的代码
}
其中,op
表示要重载的运算符,parameters
表示运算符的参数,return_type
表示运算符的返回类型。
#include <iostream>
class Complex {
public:
double real;
double imag;
// 构造函数
Complex(double r, double i) : real(r), imag(i) {}
// 重载加法运算符 +
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
// 重载减法运算符 -
Complex operator-(const Complex& other) const {
return Complex(real - other.real, imag - other.imag);
}
// 重载输出流运算符 <<
friend std::ostream& operator<<(std::ostream& os, const Complex& c) {
os << "(" << c.real << " + " << c.imag << "i)";
return os;
}
};
int main() {
Complex a(1.0, 2.0);
Complex b(2.0, 3.0);
Complex sum = a + b;
Complex difference = a - b;
std::cout << "Sum: " << sum << std::endl;
std::cout << "Difference: " << difference << std::endl;
return 0;
}
在上述例子中,Complex
类重载了加法运算符 +
和减法运算符 -
,使得两个Complex
对象可以使用+
和-
进行运算。
#include <iostream>
class Point {
public:
int x;
int y;
// 构造函数
Point(int xVal, int yVal) : x(xVal), y(yVal) {}
// 重载相等运算符 ==
bool operator==(const Point& other) const {
return (x == other.x && y == other.y);
}
// 重载不等运算符 !=
bool operator!=(const Point& other) const {
return !(*this == other);
}
};
int main() {
Point p1(1, 2);
Point p2(1, 2);
Point p3(3, 4);
if (p1 == p2) {
std::cout << "p1 and p2 are equal." << std::endl;
}
if (p1 != p3) {
std::cout << "p1 and p3 are not equal." << std::endl;
}
return 0;
}
在上述例子中,Point
类重载了相等运算符 ==
和不等运算符 !=
,使得两个Point
对象可以使用 ==
和 !=
进行比较。
运算符重载提供了一种扩展内置类型运算的方式,使得用户自定义类型能够更自然地与C++中的其他类型进行交互。但要谨慎使用运算符重载,确保其行为与用户的预期一致。
在C++中,命名空间是一种用于组织和管理代码标识符的机制。命名空间提供了一个容器,可以在其中定义变量、函数、类等,以避免命名冲突和提高代码的可维护性。
通过使用命名空间,可以将相关的代码组织在一起,防止命名冲突,提高代码的清晰度和可读性。
在C++中,使用namespace
关键字来定义命名空间。命名空间可以包含变量、函数、类等。以下是一个简单的例子:
#include <iostream>
// 定义命名空间
namespace MyNamespace {
int x = 5;
void display() {
std::cout << "Value of x: " << x << std::endl;
}
}
int main() {
// 使用命名空间中的变量和函数
MyNamespace::display();
std::cout << "Value of x: " << MyNamespace::x << std::endl;
return 0;
}
在上述例子中,MyNamespace
是一个命名空间,包含了一个整数变量 x
和一个函数 display()
。通过使用MyNamespace::
,可以访问命名空间中的成员。
命名空间可以进行嵌套,形成层次结构。这样可以更好地组织代码,防止命名冲突。
#include <iostream>
namespace OuterNamespace {
int x = 10;
namespace InnerNamespace {
int y = 20;
}
}
int main() {
// 访问嵌套的命名空间
std::cout << "Value of x: " << OuterNamespace::x << std::endl;
std::cout << "Value of y: " << OuterNamespace::InnerNamespace::y << std::endl;
return 0;
}
在上述例子中,OuterNamespace
中包含了 x
,而InnerNamespace
嵌套在其中,包含了 y
。通过使用作用域解析运算符 ::
,可以访问嵌套的命名空间成员。
using
声明为了简化代码,可以使用using
声明来引入命名空间中的特定成员,而不必每次都使用命名空间限定符。
#include <iostream>
// 定义命名空间
namespace MyNamespace {
int x = 5;
void display() {
std::cout << "Value of x: " << x << std::endl;
}
}
int main() {
// 使用 using 声明引入命名空间成员
using MyNamespace::x;
using MyNamespace::display;
display();
std::cout << "Value of x: " << x << std::endl;
return 0;
}
在上述例子中,使用了 using MyNamespace::x;
和 using MyNamespace::display;
,这样就可以直接使用 x
和 display()
,而不需要写完整的命名空间限定符。