文章目录 1. Cpp可执行文件的生成过程(003) 1.1. 可执行程序的生成过程 1.1.1 预处理 1.1.2 编译 1.1.3 汇编 1.1.4 链接 1.2. 细节补充 2. 查看变量地址以及变量大小(090) 3. 变量声明 and 字面量数据类型 and 运算符(010) 4. 除法运算,如何保留浮点结果(011) 5. 常量(013) 6. auto类型(014) 7. bool类型(017) 8. 逻辑运算短路特性 9. string的基本用法(025)
1. Cpp可执行文件的生成过程(003)
1.1. 可执行程序的生成过程
1.1.1 预处理
输入 : .cpp
源文件、.h
头文件输出 : 经过预处理的 .cpp
文件GCC/Clang : g++ -E main.cpp -o main.i
常见报错 :No such file or directory
1.1.2 编译
输入 : 经过预处理的 .cpp
文件 (或 .i
文件)输出 : 汇编代码文件 (.s
或 .asm
)GCC/Clang : g++ -S main.i -o main.s
(如果直接从 .cpp 文件开始,通常是 g++ -S main.cpp -o main.s
)常见报错 : Syntax error
(语法错误)、Type mismatch
(类型不匹配)、Undeclared identifier
(未声明的标识符)等Undeclared identifier
的补充: 使用了一个变量、函数或类名,但在当前编译单元
(.cpp 文件及其包含的头文件)中没有找到它的声明
。
1.1.3 汇编
输入 : 汇编代码文件 (.s
或 .asm
)输出 : 机器码文件(目标文件,.o
或 .obj
(Windows))GCC/Clang : g++ -c main.s -o main.o
(通常直接从 .cpp 到 .o:g++ -c main.cpp -o main.o
)
1.1.4 链接
输入 : 一个或多个目标文件 (.o
或 .obj
)、静态库 (.a
或 .lib
)、动态库 (.so
或 .dll
)输出 : 可执行文件(Linux下无后缀
,Windows 下.exe
)GCC/Clang : g++ main.o func.o -o my_program
(或 g++ main.cpp func.cpp -o my_program
直接从源文件链接)常见报错 : Undefined reference to 'function_name'
(未定义的引用)、Multiple definition of 'symbol_name'
(符号重复定义)、Name Mangling
(符号名不匹配)Name Mangling
的补充:当 G++ 遇到 C++ 名称修饰不匹配(C++ 代码尝试链接一个没有 extern "C" 声明的 C 函数
)时,它通常会报错为 undefined reference,但错误信息中的函数名会显示为经过 C++ 名称修饰后的形式。例如undefined reference to _Z12c_functionv
1.2. 细节补充
每个 .cpp
文件是单独编译的: 这意味着编译器在处理一个 .cpp
文件时,只知道该文件内部以及通过 #include
引入的头文件中声明的内容。它并不知道其他 .cpp
文件中定义了什么,除非这些定义通过头文件暴露出来。 这种独立编译的机制
使得大型项目可以并行编译
,提高效率。
2. 查看变量地址以及变量大小(090)
# include <iostream> int main ( )
{ int a = 0 ; std:: cout << "a的16进制地址" << & a << std:: endl; std:: cout << "a的10进制地址" << ( long long ) & a << std:: endl; std:: cout << "a占有的字节数" << sizeof ( a) << std:: endl; return 0 ;
}
a的16进制地址000000D60C2FF6C4
a的10进制地址919327471300
a占有的字节数4
3. 变量声明 and 字面量数据类型 and 运算符(010)
# include <iostream> int main ( )
{ int x1{ 1 } ; int x2{ 1.6 } std:: cout << "long long占有的字节数" << sizeof ( 123LL ) << std:: endl; ++ x1; -- x1; return 0 ;
}
long long占有的字节数8
4. 除法运算,如何保留浮点结果(011)
# include <iostream> int main ( )
{ int x1{ 5 } ; int x2{ 2 } ; float y1{ 0 } ; std:: cout << "x1 / x2 = " << x1 / x2 << std:: endl; y1 = x1 / x2; std:: cout << "x1 / x2 = " << y1 << std:: endl; std:: cout << "x1 / x2 = " << float ( x1 / x2) << std:: endl; std:: cout << "x1 / x2 = " << float ( x1) / x2 << std:: endl; std:: cout << "x1 / x2 = " << 5. / 2 << std:: endl; return 0 ;
}
x1 / x2 = 2
x1 / x2 = 2
x1 / x2 = 2
x1 / x2 = 2.5
x1 / x2 = 2.5
5. 常量(013)
# include <iostream> int main ( )
{ int x1{ 1 } ; int x2{ 2 } ; constexpr int cx1{ 1 } ; const int cx2{ x1 + x2 } ; return 0 ;
}
6. auto类型(014)
# include <iostream> int main ( )
{ constexpr int cx1{ 1 } ; const int cx2{ 2 } ; auto x1 = cx1; auto x2 = cx2; constexpr auto x1 = cx1; const auto x2 = cx2; return 0 ;
}
7. bool类型(017)
bool占的字节数
有可能不一定=1,即
# include <iostream> int main ( )
{ bool x1{ 0 } ; std:: cout << sizeof ( x1) << std:: endl; return 0 ;
}
8. 逻辑运算短路特性
# include <iostream> int main ( )
{ int x1{ 0 } ; if ( ( ++ x1) or ( ( ++ x1) ) ) { std:: cout << "x1=" << x1 << std:: endl; } int x2{ 0 } ; if ( ( ++ x2) | ( ( ++ x2) ) ) { std:: cout << "x2=" << x2 << std:: endl; } return 0 ;
}
x1 = 1
x2 = 2
9. string的基本用法(025)
# include <iostream>
# include <string> using namespace std; int main ( )
{ string x1{ "test" } ; cout << "拼接\t" << x1 + "ing" << endl; string key = "es" ; auto pos = x1. find ( key) ; if ( pos != string:: npos) { cout << "查找\t" << pos << endl; } x1. replace ( pos, key. size ( ) , "" ) ; cout << "替换或删除\t" << x1 << endl; x1. insert ( pos, key) ; cout << "插入\t" << x1 << endl; cout << "子串\t" << x1. substr ( pos, key. size ( ) ) << endl; return 0 ;
}
拼接 testing
查找 1
替换或删除 tt
插入 test
子串 es