c++ 精学笔记记录Ⅰ

1.程序编译基础知识

1.源文件&目标文件

创建一个firstcpp的项目打开其源文件路径如下图:

path = C:\Users\Excub\workspace\VisualStudioProject\firstcpp

1.代码文件:.h 和 .cpp。其中.h是用来做引用的,每个.cpp是单独编译的

2.项目配置:

(1)项目配置文件:.vcxproj

(2)解决方案配置文件:.sln

3.项目中的特殊配置文件:.filters

4.特定的设置(例:调试的路径):.user

解决方案配置文件是可以配置多个项目的配置,项目的配置文件是配置单独项目的。一个项目对应一个解决方案,一个解决方案可以有多个项目。

c++文件经过代码编译后执行的,所以我们也需要知道目标文件

(1).obj文件:每个.cpp代码执行文件运行后会生成一个obj文件。

(2).exe文件:多个obj文件会合并成一个.exe的执行文件,双击可以运行。

obj 文件路径:path\firstcpp\x64\Debug\firstcpp.obj

exe文件路径:path\x64\Debug\firstcpp.exe

补充:调试文件:path\x64\Debug\firstcpp.pdb


2.程序编译的过程

c++编译的过程:

预处理->编译->汇编->链接->执行

1.预处理:#include 主要将.h文件复制过来,输出为.cpp。

(找不到文件的错误)

2.编译:把cpp代码转化目标机器系统的汇编代码,输出为.s即汇编码(注意:每个cpp文件是单独编译的)

3.汇编:代码编译为机器指令,输出为.obj的文件/其他系统.o文件

(语法错误会在此编译和汇编阶段发生)

4.链接:将多个.obj文件合并,设置程序入口,输出为.exe。

(多个cpp中有重复定义的问题可能会在此阶段报错,因为cpp是单独编译的,在此阶段报错)

5.执行:加载.exe中程序和依赖的动态库,机器指令代码到内存。

(动态库的加载,内存溢出等问题在此阶段才会报错)


2.变量的一生

变量的本质:变量名+值的类型+修改算法。

1.变量名决定了变量的名称->指向特定类型的内存空间。

2.变量值的类型决定了变量在内存中占据多大空间。

3.修改算法决定了变量的修改方式。


1.变量的基本属性

基础数据类型所占内存大小,一格代表1个字节。

我们通常使用不占用性能开销的sizeof来查看数据类型所占内存大小。

我们可以通过&变量名 ->得到其内存地址。

#include <iostream>

//命名空间输出简化
using namespace std;

int main()
{
    std::cout << "Hello World!\n";

    //定义一个int类型的变量x
    int x{ 100 };
    cout << "x=" << x << endl;
    cout << "变量x的原本内存地址" << &x << endl;
    //简单的类型转换
    cout << "变量x的内存地址" 
        << (long long) & x 
        << endl;

    int c{ 200 };
    cout << "变量z的内存地址" 
        << (long long)&c
        << endl;

    //sizeof()获取变量所占内存中的内存大小
    cout << "x的内存大小"
        << sizeof(x) << "字节"
        << endl;

    long long bigint{ 0 };
    cout << "bigint的内存大小"
        << sizeof(bigint)<<"字节"
        << endl;

}


2.变量的算数运算

变量:可修改的容器。

字面量:直接写在代码中的固定值,固定不变的数据本身。


C++计算的注意点:

1.基础算数运算c++都支持,运算的遵循先乘除后加减,复合运算建议用括号进行囊括计算。

2.+=、-=、/=、*=和其他语言计算一样,支持简化版加减乘除。

3.除法的特殊性:分母不能为0。

4.现代版C++学习中自增,自减。 z++(先取值再++)和++z(先++再取值)。现代编程用++z来进行自增自减,(算法层面)目前是节省内存,减少一个临时变量。


3.cpp浮点数的计算与转换

注意点:

1.变量在进行除法计算时,需进行除数不为0的算前验证判断,否则就会导致编译程序不报错,但是运行时,程序出错。

2.c++中将浮点数转为整数是不会进行四舍五入的,而是直接截取保留整数部分。注意变量之间的计算结果可能精度上有误差。

3.c++中整数计算,如果想要结果是浮点数,则必须对计算的整数其中之一转化为浮点数参与计算才可以,直接对结果类型转换无效。

//整数相除会丢失小数位

	int x1{ 1 };
	int x2{ 2 };

	float f1{ 0 };
	f1 = x1 / x2;
	cout << "f1 = " << f1 << endl;   //f1=0

    //解决方法,计算的两个数之间有一个数是浮点数则结果就是浮点数
	cout << "1 / 2. = "  << 1/2. << endl;  

    //那么上述f1的计算经过数据类型转换后如下
	f1 = x1 / (float)x2;
	cout << "转换后的f1=" << f1 << endl;    //f1=0


4.变量的作用域和生命周期

作用域:定义了一个变量后,在哪里可以使用。

生命周期:变量对应的这块内存空间什么时候占用,什么时候释放,从定义的那一行代码开始暂用内存,出了大括号后释放。

局部变量:在一对大括号里面定义的变量,定义后即申请内存,在出了大括号之后就释放内存。

全局变量:在main函数(入口函数)的外部申请内存,在main结束之后才释放。

注意:子作用域中可以访问父作用域的变量,父作用域不可以访问子作用域的变量。子和父作用域的变量可以重名,调用时遵循就近原则


3.常量

本质:相对于变量,是不允许变化的量。

//常量的定义和分类

//运行时常量定义    (普通常量)
const int x{ 0 };
//编译时常量定义    (表达式常量)
constexpr int cx{ 1 };

运行时常量:顾名思义,在运行时才知道的常量。

编译时常量:顾名思义,在编译的时候就已经确定的常量。

运行时常量特性:可能编译的时候值是无法确定的,可能由外部传入,计算完之后才不可更改。

⭐(常用)编译时常量特性:不能通过运行时产生的变量来对其进行赋值,因为其在编译阶段已经确定好值了。

⭐大部分时候用编译时常量(constexpr),涉及到参数传递赋值的时候选用运行时常量(const)

	//运行时常量
	const int cx{ 100 };
	cout << "cx = " << cx << endl;
	int t1 = 10;
	const int cx2{ t1 + 10 };
	cout << "运行时常量cx2 = " << cx2 << endl;

	//编译时常量
	constexpr int cex{ 300 };
	cout << "cex = " << cex << endl;
	//直接报错,无法用变量初始化编译时常量
	//constexpr int cx3{ t1 + 10 };

4.auto的使用

auto的作用:能根据实际情况自动推导变量类型,提高代码简洁性。

1.auto 确保变量被初始化

2.代码更加简洁、后面的泛型变成用的多

3.简化代码,比如迭代器代码简化,并替换容器后代码可以不变

4.从初始化器推导类型

⭐常用定义变量:变量类型计算更改,则变量定义处不用变。

auto ax = 1;

⭐常用接受函数返回值时,返回值类型变化后引用是用auto定义的,所以其后续使用不用变,减少维护成本。

//auto的基础使用

#include <iostream>
using namespace std;

int main() {
    // 1. 基础数值类型推导
    auto num = 10;        // 推导为 int(字面量10是int)
    auto pi = 3.14159;    // 推导为 double(默认浮点是double)
    auto f = 5.0f;        // 推导为 float(加f后缀)
    auto c = 'A';         // 推导为 char
    auto ptr = &num;      // 推导为 int*(指针类型)

    cout << "num类型推导为int:" << num << endl;
    cout << "ptr类型推导为int*:" << *ptr << endl;

    return 0;
}

常量推导

  • auto推导const变量时,默认丢掉 “顶层 const”(变成普通变量);
  • const auto/constexpr auto才能得到常量。
#include <iostream>
using namespace std;

int main() {
    int a = 20;
    const int b = 30;

    // 1. 普通auto:忽略顶层const(b是const int,但auto推导为int)
    auto x = b;       
    x = 40; // 可以修改,因为x是普通int

    // 2. const auto:运行时常量(只读,不可修改)
    const auto y = a; 
    // y = 50; // 报错!const auto是只读变量

    // 3. constexpr auto:编译时常量(编译期确定值,可用于编译期上下文)
    constexpr auto z = 100; 
    int arr[z] = {1,2,3}; // 编译期常量可用于数组大小

    cout << "const auto y(运行时常量):" << y << endl;
    cout << "constexpr auto z(编译时常量):" << z << endl;

    return 0;
}

5.案例分析:

#YUV和RGB互相转换,MP4视频播放常见格式就是YUV

YUV:Y亮度,U 蓝色差,V红色差。

RGB:红绿蓝。

#代码实现互转
#include <iostream>
#include <algorithm>  // 用于std::clamp(C++17及以上)
using namespace std;

// 数值范围提示(可选,增强友好性)
constexpr int RGB_MIN = 0;
constexpr int RGB_MAX = 255;

int main() {
    int choice{};
    cout << "===== 颜色空间转换工具 =====" << endl;
    cout << "1. YUV → RGB" << endl;
    cout << "2. RGB → YUV" << endl;
    cout << "请输入转换选项(1/2):";
    cin >> choice;

    // 处理YUV转RGB
    if (choice == 1) {
        double Y, U, V;
        cout << "\n请输入YUV分量(Y范围:0~255,U/V范围:0~255):" << endl;
        cout << "Y = "; cin >> Y;
        cout << "U = "; cin >> U;
        cout << "V = "; cin >> V;

        // YUV转RGB公式(BT.601标准)
        double R = Y + 1.13983 * (V - 128);
        double G = Y - 0.39465 * (U - 128) - 0.58060 * (V - 128);
        double B = Y + 2.03211 * (U - 128);

        // 限制RGB范围在0~255(使用std::clamp简化逻辑)
        R = clamp(R, (double)RGB_MIN, (double)RGB_MAX);
        G = clamp(G, (double)RGB_MIN, (double)RGB_MAX);
        B = clamp(B, (double)RGB_MIN, (double)RGB_MAX);

        cout << "\n转换结果(RGB):" << endl;
        cout << "R = " << R << endl;
        cout << "G = " << G << endl;
        cout << "B = " << B << endl;
    }
    // 处理RGB转YUV
    else if (choice == 2) {
        int R, G, B;
        cout << "\n请输入RGB分量(范围:0~255):" << endl;
        cout << "R = "; cin >> R;
        cout << "G = "; cin >> G;
        cout << "B = "; cin >> B;

        // 校验RGB输入合法性
        if (R < RGB_MIN || R > RGB_MAX || G < RGB_MIN || G > RGB_MAX || B < RGB_MIN || B > RGB_MAX) {
            cout << "错误:RGB值必须在0~255之间!" << endl;
            return 1;
        }

        // RGB转YUV公式(BT.601标准)
        double Y = 0.299 * R + 0.587 * G + 0.114 * B;
        double U = -0.14713 * R - 0.28886 * G + 0.436 * B + 128;  // 偏移128到0~255范围
        double V = 0.615 * R - 0.51498 * G - 0.10002 * B + 128;  // 修正原公式符号(原公式V计算有误)

        cout << "\n转换结果(YUV):" << endl;
        cout << "Y = " << Y << endl;
        cout << "U = " << U << endl;
        cout << "V = " << V << endl;
    }
    // 处理无效选项
    else {
        cout << "错误:无效的选项!请输入1或2。" << endl;
        return 1;
    }

    return 0;
}

6.总结

本章节是笔者记录C++学习的时候的精讲部分笔记,用于自己学习和记录。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值