📝前言:
本文章適合有一定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. 輸出
- 2.2. 輸入
- 3. 格式化輸出
- 3.1. 使用流操縱符
- 3.2. 控制進制
- 4. 文件輸入和輸出
- 4.1. 文件輸出
- 4.2. 文件輸入
- 5 提升IO效率
- 三,缺省參數
- 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); //輸出 20printf("%d", b); //輸出 30return 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); //輸出20return 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); // 輸出30return 0;
}
2.2.2. 展開單個變量
語法:using 命名空間名稱::變量名稱
int a = 10;
namespace tr {int b = 20;int c = 30;
}
using tr::b;
int main() {printf("%d", b); // 輸出20return 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. 輸出
-
使用
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
會跳過空白字符(如空格、制表符、換行符)。
cin
和cout
自動判斷類型
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 的函數操作,否則會導致輸入輸出順序混亂
第二,三句:解除cin
和cout
的綁定。在默認情況下,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,非官方,按頭文件分類:https://legacy.cplusplus.com/reference/
2,官方中文:https://zh.cppreference.com/w/cpp
3,官方英文:https://en.cppreference.com/w/
🌈我的分享也就到此結束啦🌈
要是我的分享也能對你的學習起到幫助,那簡直是太酷啦!
若有不足,還請大家多多指正,我們一起學習交流!
📢公主,王子:點贊👍→收藏?→關注🔍
感謝大家的觀看和支持!祝大家都能得償所愿,天天開心!!!