【番外篇】C++语法学习笔记

学习目标:C++的一些高级操作

根据C++菜鸟教程自学的笔记,大家有想学习C++的话可以根据这个网站进行学习。这个推荐有一定基础的再去进行自学。新手的话还是建议直接看一些视频跟着学


学习内容:

1. 运算符重载

说到C++中的运算符重载,首先要明确平时使用的加、减、乘、除、与、或、非、输入、输出、赋值、自增自减等这些运算符其实就是运算符重载的特殊情况。这些特殊情况只能对C++中的基础数据类型进行操作,如:"int"、"double"等。 而如果是用户自己定义的类型呢?比如自己定义的类的对象进行运算,想让这些自定义类型也进行加、减、乘、除这些操作,就只能进行运算符重载。

(1).重载运算符的定义

c++ 复制代码
Box是声明的一个类:
      Box operator+(const Box& b)
      {
         Box box;
         box.length = this->length + b.length;
         box.breadth = this->breadth + b.breadth;
         box.height = this->height + b.height;
         return box;
      }

2.文件读取和写入

定义数据类型:#include

写文件:
ofstream outfile;
outfile.open("file.dat", ios::out | ios::trunc );
关闭文件outfile.close();

读文件
ifstream  afile;
afile.open("file.dat", ios::out | ios::in );
关闭文件infile.close();

3. 常量

const关键字的定义:
const int A = 1;
此时a为常量,是不可以修改的

#define 预处理器
#define PI 3.1415926

宏定义的边际错误

c++ 复制代码
#include <iostream>
using namespace std;

#define cyy 10+1 

int main()
{
	int area;
	const int a = 1;
	area = cyy * cyy;
	cout << area<<endl;//
	/
	cout << cyy;//cyy的值为11
	return 0;
}

理想情况上面的代码输出的area值,应该为1111=121,但结果却为21
原因是宏定义的编辑效应产生的错误,代码将area = cyy
cyy看成了area = 10+1*10+1

在定义常量或宏定义时,应用大写字母表示常量,这是很好的编程方式

4. 变量的作用域

全局变量:所有函数和代码块之外声明的变量,可以被任何代码中的函数访问,程序开始时创建,程序		结束时销毁。

局部变量:局部变量是在函数内部定义的量


块变量:块变量是在if,while中定义的

使用外部链接的函数或全局变量,使用extern函数
extern关键字,是在多个文件使用同一个变量时的声明方式
c++ 复制代码
#include <iostream>
int a = 1;
void func()
{
    int a = 10;
    {
        int a = 20;  // 块作用域变量
        std::cout << "块变量: " << a << std::endl;
    }
    std::cout << "局部变量: " << a << std::endl;
}
int main() {
    func();
    std::cout << "全局变量: " << a << std::endl;
    return 0;
}

输出结果:
块变量: 20
局部变量: 10
全局变量: 1

5.存储类的关键字

存储类主要的作用是在定义变量或函数的范围和生命周期。c++的程序中的存储类有:

(1)register

用于定义存储在寄存器而不是RAM中的变量,以便更快访问

(2)static

  1. 限制变量的作用域在当前文件中,该变量只能在定义他的文件中使用
  2. static声明完静态变量后,在程序的整个执行期间都会一直存在,即使超出的声明他的函数的作用域

(3) extern

用于声明其他文件中定义的全局变量,也就是在B文件中使用A文件声明的全局变量

6.字符串的使用

C++中,有很多用于操作字符串的函数,这里记录一下

在使用这些函数前,需声明一下:

c++ 复制代码
#include <string>
函数 作用
strcpy(s1,s2) 复制字符串S2到S1中
strcat(s1,s2) 将S2链接到S1的末尾
strlen(s1) 返回字符串s1的长度
strcmp(s1,s2) 判断字符串s1和s2是否相同,相同返回0,s1<s2返回值小于0,s1>s2返回值大于0
strchr(s1,ch) 返回一个指针,指向ch第一次出现在字符串s1的位置
strstr(s1,s2) 返回一个指针,指向字符串s1中,第一次出现字符串s2的位置

7. 引用

我在之前的学习引用的时候有一处一直搞不用,就是引用作为函数的参数,今天问了chatgpt一个问题后,豁然开朗

问题:void swap(int& x, int& y);和void swap(int x, int y)的区别

回答:

  1. 参数传递方式:第一个函数 void swap(int& x, int& y); 使用引用作为参数,而第二个函数 void swap(int x, int y); 使用值传递。
  2. 修改原变量:当调用 void swap(int& x, int& y); 函数时,函数内部可以直接修改传入的变量 x 和 y 的值。因为引用传递的是变量的地址,所以修改引用的值会影响到原变量。而当调用 void swap(int x, int y); 函数时,函数内部只能修改传入的副本变量 x 和 y 的值,不会影响原变量。
  3. 性能开销:使用引用传递可以避免对变量进行拷贝操作,提高代码的执行效率。而使用值传递需要进行值的拷贝,可能会产生较大的开销。

代码案例

  1. 函数使用引用
c++ 复制代码
#include <iostream>
using namespace std;
int x = 10;
int y = 20;
void swap(int &x, int& y) {
	int temp = x;
	x = y;
	y = temp;
}
int main() {
	cout << "x:" << x << endl;
	cout << "y:" << y << endl;
	swap(x, y);
	cout << "new_x:" << x << endl;
	cout << "new_y:" << y << endl;
}
输出结果://x和y的值做了交换
x:10
y:20
new_x:20
new_y:10
  1. 函数不使用引用
c++ 复制代码
#include <iostream>
using namespace std;
int x = 10;
int y = 20;
void swap(int x, int y) {
	int temp = x;
	x = y;
	y = temp;
}
int main() {
	cout << "x:" << x << endl;
	cout << "y:" << y << endl;
	swap(x, y);
	cout << "new_x:" << x << endl;
	cout << "new_y:" << y << endl;
}
输出结果://x和y的值没做交换
x:10
y:20
new_x:10
new_y:20

总结:也就是说,当你想值使用传入变量的值时,使用值传递即可。但是当你想要修改传入变量的值时,使用引用传递,同时如果传入的参数过大,避免拷贝占用内存,使用引用传递也是很好的。

8.结构

C++中用户可以自定义可用的数据类型,这个叫结构体。

定义结构,使用的是struct语句,其结构如下:

c++ 复制代码
struct Books{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;


可以对结构体进行声明和赋值
Books Book1
strcpy(Book1.title,"C++教程");
Book1.bool_id = 1;

9.抽象类和纯虚函数

纯虚函数和抽象类之间是紧密关联的,抽象类是包含至少一个纯虚函数的类。纯虚函数没有具体的实现,只是提供了函数的接口。抽象类不能被实例化,只能用作其他类的基类来派生新的类。

抽象类是一种特殊的类,不能被实例化,实例化抽象类将会报错。

抽象类的定义:定义抽象类,需要抽象类中至少要有一个纯虚函数

纯虚函数的定义: 纯虚函数通过在函数末尾使用=0来定义 virtual void pureVirtualFunction() = 0;

一个纯虚函数的和抽象类的使用方法

c++ 复制代码
class Base {
public:
    virtual void pureVirtualFunction() = 0; // 纯虚函数声明

    void normalFunction() {
        // 普通函数实现
        // ...
    }
};

class Derived : public Base {
public:
    void pureVirtualFunction() override {
        // 派生类中重写纯虚函数,提供具体实现
        // ...
    }
};

10. 虚函数和纯虚函数的区别

虚函数 纯虚函数
声明 函数前要加virtual关键字 使用virtual 和"=0"声明
派生类中是否需要重写 随意 必须重写

11. 命名空间

当你自定义的函数如zzy(),与另外一个函数库也有一个zzy()函数,编译器就无法判断你使用的时哪一个zzy()函数

引入命名空间专门为了解决这个问题

定义命名空间

命名空间是需要定义的,这个目前我没有设计到,但其实就时把对应的函数放到命名空间这个大括号中即可

namespace namespace_name{

void func(){

具体函数实现

}

}

命名空间的使用

using namespace std; 这个是最常见的命名空间

如果不使用这个命令的话,很对c++的内置函数使用时就需要用"std::函数"的形式来使用

12.模板

13.lambda函数

lambda函数是在C++ 11中新增的功能,广泛定义于需要定义短小的函数对象、算法和容器操作

lambda的定义

c++ 复制代码
	[capture](parameters) -> return_type { body }
    auto sum = [](int a, int b) -> int {
    return a + b;
    };
capture 是一个可选的捕获列表,用于在lambda函数内部访问外部变量。

parameters 是参数列表,用于传递给lambda函数的参数。

return_type 是返回类型,指定lambda函数的返回值类型。

body 是函数体,包含lambda函数的具体实现逻辑。
相关推荐
机智的叉烧25 分钟前
前沿重器[57] | sigir24:大模型推荐系统的文本ID对齐学习
人工智能·学习·机器学习
量子-Alex1 小时前
【多模态聚类】用于无标记视频自监督学习的多模态聚类网络
学习·音视频·聚类
吉大一菜鸡1 小时前
FPGA学习(基于小梅哥Xilinx FPGA)学习笔记
笔记·学习·fpga开发
CCSBRIDGE4 小时前
Magento2项目部署笔记
笔记
爱吃西瓜的小菜鸡4 小时前
【C语言】判断回文
c语言·学习·算法
别NULL4 小时前
机试题——疯长的草
数据结构·c++·算法
小A1594 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
亦枫Leonlew5 小时前
微积分复习笔记 Calculus Volume 2 - 5.1 Sequences
笔记·数学·微积分
岁岁岁平安5 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA5 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计