目录

快速从C过度C一namespace,C的输入和输出,缺省参数,函数重载

快速从C过度C++(一):namespace,C++的输入和输出,缺省参数,函数重载

📝前言:

本文章适合有一定C语言编程基础的读者浏览,主要介绍从C语言到C++过度,我们首先要掌握的一些基础知识,以便于我们快速进入C++的学习,为后面的学习打下基础。

这篇文章的主要内容有:

1,命名空间 namespace

2,C++的输入和输出

3,缺省参数

4,函数重载

🎬个人简介:努力学习ing

📋个人专栏:

🎀CSDN主页

🌄其他专栏: , ,



一,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;

https://i-blog.csdnimg.cn/direct/78c45ac905374cd49a63ea164ab4162d.png

为了解决这个问题,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 未被展开或者指定时,默认在局部和全局里面找变量
  • namespaceusing 展开后,查找顺序为:局部域→命名空间域→全局域

二,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. 输出

  • 使用 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. 输入

  • 使用 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 会跳过空白字符(如空格、制表符、换行符)。

**cincout

自动判断类型**

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;
    }

5 提升IO效率

ios_base::sync_with_stdio(false);
cin.tie(nullptr); 
cout.tie(nullptr);

第一句:解除 iostream 与 C 标准库的同步。但要注意,一旦解除同步,就不能再混合使用 C++ 的流操作和 C 的函数操作,否则会导致输入输出顺序混乱

第二,三句:解除 cincout 的绑定。在默认情况下, cin 是和 cout 绑定在一起的,即:在执行 cin 操作之前,会先刷新 cout 的缓冲区,以确保输出的内容都被显示出来。


三,缺省参数

缺省参数(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);  // 错误:调用歧义,无法确定调用哪个函数
    
  • 示例二:

void func(int a = 3, double b = 3.14);
void func(int a, double b, int c);

func(10); // 歧义:因为第一个func可接受参数数量:[0,2],第二个func可接受参数数量 3 编译器无法判断是错误的调用了第二个还是正确的调用了第一个
func(); // 会调用第一个,因为没参数,编译器可判断
func(10, 2.1, 5); // 会调用第二个,因为传入了三个参数

尽量避免写容易歧义的函数重载,在调用时也要判断重载的函数是否有歧义。

最后推荐几个个C++参考文档

1,非官方,按头文件分类:

2,官方中文:

3,官方英文:


🌈我的分享也就到此结束啦🌈

要是我的分享也能对你的学习起到帮助,那简直是太酷啦!

若有不足,还请大家多多指正,我们一起学习交流!

📢公主,王子:点赞👍→收藏⭐→关注🔍

感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!