C++中的一些困惑
这是个人笔记,记录一些学习过程中没有理解以及容易肴杂的问题与解答
1. using std::具体命名与using namespace std;
在C++中,使用 using 和 using namespace 都是用来简化代码中命名空间的写法,但它们有差别的影响和使用场景,各有优劣:
- using std::具体命名
- 优势:精确导入了命名空间中的特定名称,可以避免命名冲突,提高代码的可读性和可维护性。
- 劣势:需要逐个导入每个需要使用的名称,可能会显得冗长,尤其是当需要导入多个名称时。
- cppCopy codeusing std::vector;
- using std::cout;
- using std::endl;
- int main()
- {
- vector<int> nums = {1, 2, 3};
- cout << "Hello, world!" << endl;
- return 0;
- }
复制代码
- using namespace std;
- 优势:一次性导入了整个 std 命名空间中的所有名称,可以方便地使用标准库中的各种功能,节流了代码中重复写命名空间的时间和空间。
- 劣势:可能会引入命名冲突,尤其是当在代码中使用了其他命名空间或自界说了相同名称的变量或函数时,容易导致代码紊乱和不可猜测的行为。
- cppCopy codeusing namespace std;
- int main()
- {
- vector<int> nums = {1, 2, 3};
- cout << "Hello, world!" << endl;
- return 0;
- }
复制代码 总体来说:推荐使用 using std::具体的类型 的方式来导入特定的名称,因为它可以明白指定要导入的内容,避免了潜在的命名冲突问题,同时保持了代码的清晰性和可维护性。而在大型项目或者有多个命名空间交织的环境下,最好避免使用 using namespace std; 这样的全局命名空间导入方式,以免引起不须要的麻烦。
2. 【int *p[10] 】与 【int (*p)[10]】
- int *p[10]
- 这表示 p 是一个数组,包含了 10 个元素。
- 每个元素都是一个指向 int 类型的指针。
- 可以直接通过索引来访问数组中的指针,如 p[0] 表示数组的第一个指针。
- int *p[10]; // p 是一个数组,包含了 10 个指向 int 的指针
复制代码
- int (*p)[10]
- 这表示 p 是一个指针,指向一个包含 10 个整数的数组。
- p 指向的整个数组是一个单独的对象,而不是一个指向指针的数组。
- 需要通过解引用来访问指针指向的数组元素,如 (*p)[0] 表示指针 p 所指向数组的第一个元素。
- int (*p)[10]; // p 是一个指针,指向一个包含 10 个整数的数组
复制代码 举个例子来比力两者的使用:
- int main()
- {
- int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- int *p1[10]; // 数组,包含 10 个指向 int 的指针
- p1[0] = arr; // 将数组 arr 的首地址赋给 p1 的第一个指针
- int (*p2)[10]; // 指针,指向包含 10 个整数的数组
- p2 = &arr; // 将数组 arr 的地址赋给 p2
- // 使用 p1 访问数组元素
- for (int i = 0; i < 10; ++i) {
- std::cout << *(p1[0] + i) << " "; // 输出数组元素
- }
- std::cout << std::endl;
- // 使用 p2 访问数组元素
- for (int i = 0; i < 10; ++i) {
- std::cout << (*p2)[i] << " "; // 输出数组元素
- }
- return 0;
- }
复制代码 在上面的例子中,p1 是一个数组,包含了 10 个指向 int 的指针,而 p2 是一个指针,指向一个包含 10 个整数的数组。这两者的使用方式略有差别,因为 p1 中的每个元素都是指针,而 p2 指向的是整个数组对象。
3. main()函数可带参,参从何来?
在 C++ 中,main 函数可以具有带参数的情势,这些参数通常用于接收下令行参数。这些参数是由操作系统在步伐启动时传递给步伐的,并且可以在 main 函数的参数列表中接收到。
标准的 main 函数的声明有两种情势:
或者
- int main(int argc, char* argv[])
复制代码 第一种情势是不带参数的,步伐启动时不会接收任何下令行参数。第二种情势是带参数的,此中 argc 表示下令行参数的数目,argv 是一个指向字符指针数组的指针,每个指针指向一个下令行参数的字符串。
- argc(argument count)表示下令行参数的数目,包罗步伐名称在内。
- argv(argument vector)是一个指针数组,每个元素指向一个下令行参数的字符串,此中 argv[0] 通常是步伐的名称,argv[1]、argv[2] 等依次是传递给步伐的其他下令行参数。
例如,以下是一个简朴的示例:
- #include <iostream>#include <string>// 编写一个带实参的main函数并运行int main(int argc, char* argv[])
- { // 确保有足够的实参 if (argc != 3) { std::cerr << "Usage: " << argv[0] << " <arg1> <arg2>" << std::endl; return 1; // 返回非零值表示错误退出 } // 将实参毗连成一个字符串 std::string result = std::string(argv[1]) + " " + std::string(argv[2]); // 输出毗连后的字符串 std::cout << "Concatenated string: " << result << std::endl; return 0;}
复制代码 在VS code中编译运行:
- 打开Terminal,使用下令行编译源文件
- g++ -o 生成的程序名(如:myprogram) 源文件.cpp
复制代码 - 编译器会生成一个名为myprogram的可执行文件
- 在终端运行步伐并传参
执行过程及结果:
4. constexpr函数的返回值可不为常量,那这时constexpr关键字作用是什么?
虽然constexpr函数的返回值并非总是常量,但使用constexpr关键字可以告诉编译器,希望在可能的环境下在编译期间举行求值和优化。这样可以使代码更加灵活并提高性能,特别是在一些需要举行编译期间盘算的场景下,constexpr函数非常有用。
进一步表明:
- 某些场景下,函数的返回值仍旧可以再编译期间确定。(通常是因为函数的输入参数是常量表达式,或者函数内部只包含了可以在编译期间盘算的操作),如:
- #include <iostream>// constexpr函数,参数是常量表达式constexpr int add(int a, int b) { return a + b;}int main()
- { // 在编译期间就可以盘算出结果 // 因为输入参数是常量表达式 constexpr int result = add(10, 20); std::cout << "Result: " << result << std::endl; return 0;}
复制代码 5.为什么C++ STL不提供任何“树”容器?
一个讨论:https://www.codenong.com/205945/
6. 函数参数后面的const
是常量成员函数,即在函数内部不会修改对象的成员变量。
endl;
return 0;
}
- ## 5.为什么C++ STL不提供任何“树”容器?
- 一个讨论:https://www.codenong.com/205945/
- ## 6. 函数参数后面的`const`
- ```cpp
- void func() const {};
复制代码 是常量成员函数,即在函数内部不会修改对象的成员变量。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |