快速从C过度C++(一):namespace,C++的输入和输出,缺省参数,函数重载
📝前言:
本文章适合有一定C语言编程基础的读者浏览,主要介绍从C语言到C++过度,我们首先要掌握的一些基础知识,以便于我们快速进入C++的学习,为后面的学习打下基础。
这篇文章的主要内容有:
1,命名空间namespace
2,C++的输入和输出
3,缺省参数
4,函数重载
🎬个人简介:努力学习ing
📋个人专栏:C++学习笔记
🎀CSDN主页 愚润求学
🌄其他专栏:C语言入门基础,python入门基础,python刷题专栏
快速从C过度C++(一)
- 一,namespace
- 1. namespace的定义
- 1.1. 作用域
- 1.2. namespace定义
- 2. namespace的使用
- 2.1. 指定namespace
- 2.2. 展开namespace
- 2.2.1. 展开整个namespace
- 2.2.2. 展开单个变量
- 2.3. 使用注意事项
- 二,C++的输入和输出
- 1. 核心概念
- 1.1. 流(Stream)
- 1.2. 标准流对象
- 2. 基本输入和输出操作
- 2.1. 输出(Output)
- 2.2. 输入(Input)
- 3. 格式化输出
- 3.1. 使用流操纵符
- 3.2. 控制进制
- 4. 文件输入和输出
- 4.1. 文件输出
- 4.2. 文件输入
- 三,缺省参数
- 1. 缺省参数的基本用法
- 1.1. 语法
- 2.2. 示例
- 2. 缺省参数的规则
- 2.1. 从右向左设置缺省参数
- 2.2. 函数声明和定义
- 2.3. 调用时的参数匹配
- 2.4. 默认值必须是常量或全局变量
- 四,函数重载
- 1. 函数重载的基本规则
- 1.1. 参数列表必须不同
- 1.2. 示例
- 1.3. 避免歧义调用
一,namespace
1. namespace的定义
1.1. 作用域
在学习namespace前,我们先了解域的概念。
在C语言中,我们学习过全局变量和局部变量,看下面这段代码:
#include<stdio.h>
int a = 10;
int b = 30;
int main() {
int a = 20;
printf("%d\n", a); //输出 20
printf("%d", b); //输出 30
return 0;
}
全局变量的作用域是全局,局部变量的作用域是函数内,且局部变量的优先级高于全局变量。除了这两个域,C++中还有命名空间域,类域。域影响的是编译时语法查找一个变量/函数/类型的出处的逻辑,在同一个域中出现同名,就会冲突,如:
int a = 10;
int a = 30;
为了解决这个问题,C++引入了namespace
,目的是对标识符的名称进行本地化,以避免冲突。
全局域和局部域还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。
1.2. namespace定义
基本语法:
namespace
关键字 + 空间名称 + {}
(注意{}后不需要跟;
),如:
namespace tr
{
// 命名课件内可定义 变量/函数/类
int a = 10;
int sub(int a, int b) {
return a - b;
}
struct Node {
struct Node* next;
int val;
};
}
2. namespace的使用
2.1. 指定namespace
语法:名称::变量名
::
是作用域解析符,用来指定要使用的明明空间中的成员
int a = 10;
namespace tr {
int a = 20;
}
int main() {
printf("%d", tr::a); //输出20
return 0;
}
2.2. 展开namespace
2.2.1. 展开整个namespace
语法:using namespace 命名空间名称
using
指令会将命名空间中的所有名称引入到当前作用域(注意若有与当前作用域同名的变量,就会冲突),如:
int a = 10;
namespace tr {
int a = 20;
}
using namespace tr; //因为全局已经有一个a,会冲突,正确可以使用tr::a来访问a
因此,展开全部成员的这种方法并不推荐,冲突风险很大
正确用法:
int a = 10;
namespace tr {
int b = 20;
int c = 30;
}
using namespace tr;
int main() {
printf("%d", c); // 输出30
return 0;
}
2.2.2. 展开单个变量
语法:using 命名空间名称::变量名称
int a = 10;
namespace tr {
int b = 20;
int c = 30;
}
using tr::b;
int main() {
printf("%d", b); // 输出20
return 0;
}
2.3. 使用注意事项
namespace
的本质是一个域,与全局域和局部域各自独立,不同的域可以定义同名变量namespace
只能定义在全局,可以嵌套定义。- 一个文件中通常不可以有同名的
namespace
,如果有,编译器会合并,视作一个 - 不同文件可以有同名的
namespace
,链接时,编译器会合并同名的 namespace
未被展开或者指定时,默认在局部和全局里面找变量- 将
namespace
用using
展开后,查找顺序为:局部域→命名空间域→全局域
二,C++的输入和输出
在C++中,输入和输出(I/O)主要通过标准库中的<iostream>
头文件提供的流(stream)机制来实现。C++的I/O流库提供了灵活且类型安全的方式来处理输入和输出操作。
1. 核心概念
1.1. 流(Stream)
- 流是数据在源和目标之间流动的抽象。
- 输入流(Input Stream):从外部设备(如键盘、文件)读取数据。
- 输出流(Output Stream):向外部设备(如屏幕、文件)写入数据。
1.2. 标准流对象
C++预定义了以下标准流对象:
std::cin
:标准输入流,通常与键盘输入关联。std::cout
:标准输出流,通常与屏幕输出关联。std::cerr
:标准错误流,用于输出错误信息(无缓冲)。std::clog
:标准日志流,用于输出日志信息(有缓冲)。
主要了解前两个
2. 基本输入和输出操作
2.1. 输出(Output)
-
使用
std::cout
和插入运算符<<
将数据输出到屏幕。 -
示例:
#include <iostream> int main() { int num = 42; std::cout << "Hello, World!" << std::endl; // 输出字符串并换行 std::cout << "The number is: " << num << std::endl; // 输出变量 // 都是以字符串的形式输出,相当于把 << 中间的字符串合并后输出,一个<< <<之间只能放一个变量 return 0; }
-
std::endl
:插入一个换行符并刷新输出缓冲区
2.2. 输入(Input)
- 使用
std::cin
和提取运算符>>
从键盘读取数据。 - 示例:
#include <iostream> int main() { int age; std::cout << "Enter your age: "; std::cin >> age; // 从键盘读取输入并存储到变量 age,多个变量输入时,可用空格,换行符等符号间隔 std::cout << "You are " << age << " years old." << std::endl; return 0; }
- 注意:
std::cin
会跳过空白字符(如空格、制表符、换行符)。
3. 格式化输出
虽然C++提供了多种方式格式化输出,但是我们任然可以继续使用C语言的格式化输出方式,因为C++兼容C语言
下面介绍C++的格式化输出:
3.1. 使用流操纵符
std::setw(n)
:设置输出宽度为n
。std::setprecision(n)
:设置浮点数精度为n
。std::fixed
:以固定小数格式输出浮点数。std::scientific
:以科学计数法输出浮点数。- 示例:
#include <iostream> #include <iomanip> // 包含流操纵符 int main() { double pi = 3.141592653589793; std::cout << std::fixed << std::setprecision(2) << "Pi: " << pi << std::endl; return 0; }
3.2. 控制进制
std::dec
:十进制(默认)。std::hex
:十六进制。std::oct
:八进制。- 示例:
int num = 255; std::cout << std::hex << "Hex: " << num << std::endl; // 输出 ff
4. 文件输入和输出
C++通过<fstream>
头文件支持文件操作:
4.1. 文件输出
- 使用
std::ofstream
将数据写入文件。 - 示例:
#include <iostream> #include <fstream> int main() { std::ofstream outFile("output.txt"); if (outFile.is_open()) { outFile << "Hello, File!" << std::endl; outFile.close(); } else { std::cerr << "Failed to open file!" << std::endl; } return 0; }
4.2. 文件输入
- 使用
std::ifstream
从文件读取数据。 - 示例:
#include <iostream> #include <fstream> #include <string> int main() { std::ifstream inFile("input.txt"); std::string line; if (inFile.is_open()) { while (std::getline(inFile, line)) { std::cout << line << std::endl; } inFile.close(); } else { std::cerr << "Failed to open file!" << std::endl; // 若文件未打开使用 std::cerr 输出错误信息。 } return 0; }
三,缺省参数
缺省参数(Default Arguments)允许函数在定义时为某些参数指定默认值。如果调用函数时没有为这些参数提供实参,则使用默认值。
1. 缺省参数的基本用法
1.1. 语法
返回值类型 函数名(参数类型 参数名 = 默认值);
2.2. 示例
#include <iostream>
// 函数声明,带有缺省参数
void printMessage(std::string message = "Hello, World!");
int main() {
printMessage(); // 使用默认参数,输出: Hello, World!
printMessage("Hi!"); // 提供自定义参数,输出:Hi!
return 0;
}
// 函数定义
void printMessage(std::string message) {
std::cout << message << std::endl;
}
2. 缺省参数的规则
2.1. 从右向左设置缺省参数
- 缺省参数必须从右向左依次设置,不能跳过中间的参数。
- 示例:
void func(int a, int b = 10, int c = 20); // 正确 void func(int a = 5, int b, int c = 20); // 错误:b 没有默认值
2.2. 函数声明和定义
- 如果函数在声明时指定了缺省参数,定义时不能再重复指定。
- 示例:
// 声明时指定缺省参数 void printNumber(int num = 42); // 定义时不能重复指定,即: 这里不能再写int num = 30 void printNumber(int num) { std::cout << num << std::endl; }
2.3. 调用时的参数匹配
- 如果提供了实参,则使用实参;否则使用默认值。
- 必须从左到右依次给实参,不能跳跃给实参
- 示例:
void printSum(int a, int b = 10, int c = 20) { std::cout << "Sum: " << a + b + c << std::endl; } int main() { printSum(1); // 输出:Sum: 31 (1 + 10 + 20) printSum(1, 2); // 输出:Sum: 23 (1 + 2 + 20) printSum(1, 2, 3); // 输出:Sum: 6 (1 + 2 + 3) return 0; }
2.4. 默认值必须是常量或全局变量
- 默认值不能是局部变量或动态计算的值。
- 示例:
int defaultValue = 10; void func(int a = defaultValue); // 正确 void func(int a = rand()); // 错误:默认值不能是动态计算的值
四,函数重载
函数重载(Function Overloading) 是C++中的一种特性,允许在同一个作用域内定义多个同名函数,但这些函数的参数列表必须不同(参数的类型、数量或顺序不同)。
1. 函数重载的基本规则
1.1. 参数列表必须不同
- 函数重载的核心是参数列表的不同。参数列表的不同可以体现在:
- 参数的类型不同。
- 参数的数量不同。
- 参数的顺序不同(如果类型不同)。
- 注意:返回值类型不同不能作为函数重载的依据。
1.2. 示例
下面共五个重载
#include <iostream>
void print(int a) {
std::cout << "Printing int: " << a << std::endl;
}
void print(double a) { // 类型不同
std::cout << "Printing double: " << a << std::endl;
}
void print(int a, int b) { // 数量不同
std::cout << "Printing two ints: " << a << ", " << b << std::endl;
}
// 下面两者为顺序不同
void print(int a, char c) {
std::cout << "Printing int: " << a << ' ' << "Printing char: " << c << std::endl;
}
void print(char c, int a) {
std::cout << "Printing int: " << a << ' '<< "Printing char: " << c << std::endl;
}
int main() {
print(10); // 调用 void print(int a)
print(3.14); // 调用 void print(double a)
print(10, 20); // 调用 void print(int a, int b)
print(10, 'c'); // 调用 void print(int a, char c)
print('d', 10); // 调用 void print(char c, int a)
return 0;
}
输出:
Printing int: 10
Printing double: 3.14
Printing two ints: 10, 20
Printing int: 10 Printing char: c
Printing int: 10 Printing char: d
1.3. 避免歧义调用
- 示例:
void func(int a, double b = 3.14); void func(int a); func(10); // 错误:调用歧义,无法确定调用哪个函数
最后推荐几个个C++参考文档
1,非官方,按头文件分类:https://legacy.cplusplus.com/reference/
2,官方中文:https://zh.cppreference.com/w/cpp
3,官方英文:https://en.cppreference.com/w/
🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!