C++入门

发布时间:2024年01月03日

C++入门学习

目录预览

1. 变量和数据类型

  • 了解变量的概念和声明。
  • 掌握基本的数据类型:整数(int、short、long)、浮点数(float、double)、字符(char)、布尔(bool)等。
  • 理解常量的概念和使用。

2. 运算符

  • 学习算术运算符、关系运算符、逻辑运算符等基本运算符。
  • 了解位运算符、赋值运算符、条件运算符等高级运算符。

3. 控制流

  • 熟悉条件语句:if、else if、else。
  • 学习switch语句的使用。
  • 掌握循环语句:while、do-while、for。

4. 函数

  • 理解函数的定义和声明。
  • 学习函数的调用方式。
  • 掌握函数的返回值和参数。
  • 了解函数的重载和默认参数。

5. 参数传递

  • 了解参数的传递方式:值传递、引用传递、指针传递。
  • 学习函数中的常量参数和引用参数。

6. 数组

  • 学习数组的定义和初始化。
  • 了解一维和多维数组的使用。
  • 掌握数组的遍历和操作。

7. 字符串

  • 了解字符串的基本概念。
  • 学习C-style字符串和C++中的string类的使用。
  • 掌握字符串的常见操作:拼接、查找、替换等。

8. 类型转换

  • 学习隐式类型转换和显式类型转换(强制类型转换)的概念。
  • 了解C++中的类型转换运算符和相关函数。

9. 运算符重载

  • 了解运算符重载的概念和作用。
  • 学习如何重载一些常见的运算符。

10. 命名空间

  • 学习命名空间的概念,如何使用命名空间。

变量和数据类型

1.1 变量的概念和声明

变量的概念: 变量是存储数据的内存位置,通过变量名访问这些数据。在C++中,使用关键字 intfloatdoublecharbool 等来声明变量。

// 变量声明
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
1.2 基本的数据类型

整数类型:

  • 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;
1.3 常量的概念和使用

常量的概念: 常量是其值在程序执行期间不能被修改的标识符。在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,并赋值为换行符

注意: 常量一旦被赋值就不能再修改。它提高了程序的可读性和维护性,同时帮助编译器进行优化。

2.1 算术运算符

常见的算术运算符包括:

  • +:加法
  • -:减法
  • *:乘法
  • /:除法
  • %:取余数
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
2.2 关系运算符

关系运算符用于比较两个值的关系,返回布尔值(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
2.3 逻辑运算符

逻辑运算符用于连接两个或多个布尔表达式,返回布尔值:

  • &&:逻辑与(AND)
  • ||:逻辑或(OR)
  • !:逻辑非(NOT)
bool condition1 = true, condition2 = false;
bool resultAND = (condition1 && condition2); // false
bool resultOR = (condition1 || condition2);  // true
bool resultNOT = !condition1;                 // false
2.4 位运算符

位运算符用于对二进制位进行操作:

  • &:按位与
  • |:按位或
  • ^:按位异或
  • ~:按位取反
  • <<:左移
  • >>:右移
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位)
2.5 赋值运算符

赋值运算符用于给变量赋值:

  • =:赋值
  • +=:加等于
  • -=:减等于
  • *=:乘等于
  • /=:除等于
  • %=:取余等于
int num = 10;
num += 5; // num 现在为 15
num -= 3; // num 现在为 12
num *= 2; // num 现在为 24
num /= 4; // num 现在为 6
num %= 2; // num 现在为 0
2.6 条件运算符

条件运算符(三元运算符)用于根据条件选择值:

  • condition ? expression1 : expression2
int a = 5, b = 10;
int maxNumber = (a > b) ? a : b; // maxNumber 等于 10
3.1 条件语句(if、else if、else)

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;
}
3.2 switch语句

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。

3.3 循环语句

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
4.1 函数的定义和声明

函数的定义: 函数是一段完成特定任务的代码块。它可以接受输入(参数),执行操作,然后返回输出。

// 函数的定义
int add(int a, int b) {
    return a + b;
}

函数的声明: 函数声明是在使用函数之前提供函数原型的一种方式。

// 函数的声明
int add(int a, int b);

在上述例子中,add 函数接受两个整数参数,并返回它们的和。

4.2 函数的调用方式

调用带参数的函数:

int result = add(5, 3);
cout << "5 + 3 = " << result << endl;

调用无参数的函数:

void showMessage() {
    cout << "Hello, World!" << endl;
}

// 调用无参数的函数
showMessage();
4.3 函数的返回值和参数

函数的返回值: 使用 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;
4.4 函数的重载

函数的重载: 允许定义多个同名函数,但它们的参数类型或数量不同。

// 重载的 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);
4.5 函数的默认参数

函数的默认参数: 允许在调用函数时省略一些参数,这些参数将取默认值。

// 带有默认参数的函数
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);
5.1 参数的传递方式

在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;
}
5.2 函数中的常量参数和引用参数

常量参数: 防止在函数内修改参数的值。

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;
}
6.1 数组的定义和初始化

一维数组的定义:

// 定义一个包含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}
};
6.2 数组的遍历

一维数组的遍历:

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;
}
6.3 数组的操作

修改数组元素的值:

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;
7.1 字符串的基本概念

字符串是由字符组成的一系列字符序列。在C++中,有两种主要的字符串表示方式:C-style字符串(以字符数组形式存在)和C++中的string类。

7.2 C-style字符串的使用

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指向子串的位置
}
7.3 C++中的string类的使用

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是子串在字符串中的位置
}
7.4 字符串的常见操作

字符串的拼接:

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++."
}
8.1 隐式类型转换

隐式类型转换是由编译器自动完成的类型转换,不需要程序员明确指定。在一些情况下,编译器会自动进行类型转换以满足表达式的要求。

int a = 5;
double b = a; // 隐式将整数类型转换为浮点数类型
8.2 显式类型转换(强制类型转换)

显式类型转换是由程序员明确指定的类型转换,用于将一个数据类型的值转换为另一个数据类型。在C++中,有两种主要的显式类型转换方式:C风格的强制类型转换和C++中的新式类型转换。

C风格的强制类型转换:
int a = 10;
double b = (double)a; // 使用强制类型转换将整数转换为浮点数
C++中的新式类型转换:
  • 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);
8.3 类型转换运算符和相关函数

在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;
}
9.1 运算符重载的概念

运算符重载是指通过定义新的含义,使得已有的运算符能够用于用户自定义类型的操作。C++允许对大多数运算符进行重载,包括算术运算符、关系运算符、赋值运算符等。

运算符重载使得用户自定义类型的对象可以像内置类型一样进行运算,提高了代码的可读性和灵活性。

9.2 运算符重载的语法

运算符重载的语法形式如下:

return_type operator op(parameters) {
    // 实现运算符操作的代码
}

其中,op表示要重载的运算符,parameters表示运算符的参数,return_type表示运算符的返回类型。

9.3 重载算术运算符的例子
#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对象可以使用+-进行运算。

9.4 重载关系运算符的例子
#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++中的其他类型进行交互。但要谨慎使用运算符重载,确保其行为与用户的预期一致。

10.1 命名空间的概念

在C++中,命名空间是一种用于组织和管理代码标识符的机制。命名空间提供了一个容器,可以在其中定义变量、函数、类等,以避免命名冲突和提高代码的可维护性。

通过使用命名空间,可以将相关的代码组织在一起,防止命名冲突,提高代码的清晰度和可读性。

10.2 使用命名空间

在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::,可以访问命名空间中的成员。

10.3 命名空间的嵌套

命名空间可以进行嵌套,形成层次结构。这样可以更好地组织代码,防止命名冲突。

#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。通过使用作用域解析运算符 ::,可以访问嵌套的命名空间成员。

10.4 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;,这样就可以直接使用 xdisplay(),而不需要写完整的命名空间限定符。

文章来源:https://blog.csdn.net/2301_79206260/article/details/135328647
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。