初識c++(命名空間,缺省參數,函數重載)

一、命名空間

1、namespace的意義

在C/C++中,變量、函數和后面要學到的類都是大量存在的,這些變量、函數和類的名稱將都存在于全

局作用域中,可能會導致很多沖突。使用命名空間的目的是對標識符的名稱進行本地化,以避免命名

沖突或名字污染,namespac關鍵字的出現就是針對這種問題的。

c語言項目類似下面程序這樣的命名沖突是普遍存在的問題,C++引入namespac就是為了更好的解決

這樣的問題:(因為我們設置的變量rand和stdlib.h中的rand函數沖突所以報錯)

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{// 編譯報錯:error C2365: “rand”: 重定義;以前的定義是“函數”printf("%d\n", rand);return 0;
}

2、namespace的定義

1、定義命名空間,需要使用法到namespace關鍵字,后面跟命名空間的名字,然后接?對{}即可,{}中

即為命名空間的成員。命名空間中可以定義變量/函數/類型等。(注意{}后不跟“;”)

2、namespace本質是定義出?個域,這個域跟全局域各自獨立,不同的域可以定義同名變量,所以下

面的rand不在沖突了。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int rand = 0;
}
int main()
{printf("%d\n", rand);return 0;
}

3、C++中域有函數局部域,全局域,命名空間域,類域;域影響的是編譯時語法查找?個變量/函數/

類型出處(聲明或定義)的邏輯,所有有了域隔離,名字沖突就解決了。局部域和全局域除了會影響

編譯查找邏輯,還會影響變量的聲明周期,命名空間域和類域不影響變量聲明周期。

4、namespace只能定義在全局,當然他還可以嵌套定義。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int rand = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}}
int main()
{printf("%d\n", rand);return 0;
}

5、項目工程中多文件中定義的同名namespace會認為是?個namespace,不會沖突。

test.c文件

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include"test.h"
namespace tmp
{int rand = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}}
int main()
{printf("%d\n", tmp::d);return 0;
}

test.h文件

#pragma once
namespace tmp
{int d = 0;
}

可以發現在.c文件中可以使用tmp空間中的d變量 。

6、C++標準庫都放在?個叫std(standard)的命名空間中。

7、如果想使用全局域中的變量我們可以這么操作:

int a = 3;
int main()
{int a = 0;printf("%d\n", ::a);return 0;
}

這樣printf先打印的是3。

3、命名空間的使用

編譯查找?個變量的聲明/定義時,默認只會在局部或者全局查找,不會到命名空間里面去查找。所以

下面程序會編譯報錯。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
int main()
{int a = 0;printf("%d\n", d);//未定義標識符dreturn 0;
}

所以我們要使用命名空間中定義的變量/函數,有三種方式:

1、指定命名空間訪問,項目中推薦這種方式。

tmp::d

2、using將命名空間中某個成員展開,項目中經常訪問的不存在沖突的成員推薦這種方式。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using tmp::d;
int main()
{int a = 0;printf("%d\n", d);//未定義標識符dreturn 0;
}

3、展開命名空間中全部成員,項目不推薦,沖突風險很大,日常小練習程序為了方便推薦使用。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using namespace tmp;
int main()
{int a = 0;printf("%d\n", d);//未定義標識符dreturn 0;
}

二、輸入和輸出

1、 是 Input Output Stream 的縮寫,是標準的輸入、輸出流庫,定義了標準的輸入、輸

出對象。

2、std::cin 是 istream 類的對象,它主要面向窄字符(narrow characters (of type char))的標準輸

入流。

3、std::cout 是 ostream 類的對象,它主要面向窄字符的標準輸出流。

4、std::endl 是?個函數,流插入輸出時,相當于插入?個換行字符加刷新緩沖區。

5、<<是流插入運算符,>>是流提取運算符。(C語言還用這兩個運算符做位運算左移/右移)

6、使用C++輸入輸出更方便,不需要像printf/scanf輸入輸出時那樣,需要手動指定格式,C**++的輸入**

輸出可以自動識別變量類型(本質是通過函數重載實現的),其實最重要的是C++的流能更好的支持自定義

類型對象輸入和輸出。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int a = 0;double b = 0.0;char c = '0';namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using namespace tmp;
using namespace std;
int main()
{cin >> a >> b >> c;cout << a << b << c;return 0;
}

7、cout/cin/endl等都屬于C++標準庫,C++標準庫都放在?個叫std(standard)的命名空間中,所以要

通過命名空間的使用方式去用他們。

8、?般日常練習中我們可以using namespace std,實際項目開發中不建議using namespace std。

三、 缺省參數

1、缺省參數的定義以及規定

缺省參數是聲明或定義函數時為函數的參數指定?個缺省值。在調用該函數時,如果沒有指定實參

則采用該形參的缺省值,否則使用指定的實參,缺省參數分為全缺省和半缺省參數。(有些地方把

缺省參數也叫默認參數)。

全缺省就是全部形參給缺省值,半缺省就是部分形參給缺省值。C++規定半缺省參數必須從右往左

依次連續缺省,不能間隔跳躍給缺省值。

帶缺省參數的函數調用,C++規定必須從左到右依次給實參,不能跳躍給實參。

函數聲明和定義分離時,缺省參數不能在函數聲明和定義中同時出現,規定必須函數聲明給缺省

值。

#include <iostream>
using namespace std;
void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func(); // 沒有傳參時,使?參數的默認值Func(10); // 傳參時,使?指定的實參return 0;
}

在這里插入圖片描述

2、全缺省和半缺省

#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
int main()
{Func1();Func1(1);Func1(1, 2);Func1(1, 2, 3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}

半缺省不能這么寫:

void Func2(int a = 10, int b, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
//或者
void Func2(int a = 10, int b, int c)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}

必須嚴格遵守:

半缺省參數必須從右往左依次連續缺省,不能間隔跳躍給缺省值。

3、缺省參數的實際應用

我們在沒有學c++之前我們實現棧的初始化以及插人時我們是這么寫的:

typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
// 棧頂
void STInit(ST* ps, int n)
{assert(ps);ps->a = (STDataType*)malloc(n * sizeof(STDataType));ps->top = 0;ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{assert(ps);// 滿了, 擴容if (ps->top == ps->capacity){printf("擴容\n");int newcapacity = ps->capacity == 0 ? 4 : ps->capacity* 2;STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}

如果我們要插入100個數據則就需要不斷的擴容,有效率的損耗,但是我們在學習了缺省參數后我們可以這么寫:

// 棧頂
void STInit(ST* ps, int n = 4)
{assert(ps);ps->a = (STDataType*)malloc(n * sizeof(STDataType));ps->top = 0;ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{assert(ps);// 滿了, 擴容if (ps->top == ps->capacity){printf("擴容\n");int newcapacity = ps->capacity == 0 ? 4 : ps->capacity* 2;STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}
int main()
{ST a;STInit(&a, 100);//這里不傳100也可以,因為規定必須從左到右依次給實參,不能跳躍給實參。剛好和缺省參數確定位置互補for (int i = 0; i < 100; i++){STPush(&a, i);}return 0;
}

這樣就有效避免了重復開辟空間的問題。

四、函數重載

C++支持持在同?作用域中出現同名函數,但是要求這些同名函數的形參不同,可以是參數個數不同或者

類型不同。這樣C++函數調用就表現出了多態行為,使用更靈活。(但是返回值不同不能作為重載條件,

因為調用時也無法區分,如果返回值和參數類型或者個數同時變化則也為重載條件)。

1、參數類型不同

#include<iostream>
using namespace std;
// 1、參數類型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}

2、參數個數不同

// 2、參數個數不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}

特別的如果上面的用缺省參數那么在不傳參數調用時就會報錯,編譯器不知道調用誰

// 下?兩個函數構成重載
// f()但是調?時,會報錯,存在歧義,編譯器不知道調?誰
void f1()
{cout << "f()" << endl;
}
void f1(int a = 10)
{cout << "f(int a)" << endl;
}

3、參數順序不同(實際上就是參數類型不同)

// 3、參數類型順序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
#include<iostream>
using namespace std;
// 1、參數類型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、參數個數不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}
`#include<iostream>
using namespace std;
// 1、參數類型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、參數個數不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}``

結果:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42002.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42002.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42002.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GEE代碼實例教程詳解:MODIS土地覆蓋分類與面積計算

簡介 在本篇博客中&#xff0c;我們將使用Google Earth Engine (GEE) 對MODIS土地覆蓋數據進行分析。通過MODIS/061/MCD12Q1數據集&#xff0c;我們可以識別不同的土地覆蓋類型&#xff0c;并計算每種類型的總面積。 背景知識 MODIS MCD12Q1數據集 MODIS/061/MCD12Q1是NASA…

每天一個數據分析題(四百十五)- 線性回歸模型

線性回歸模型中誤差項的數學期望為 A. 0 B. 1 C. 2 D. 3 數據分析認證考試介紹&#xff1a;點擊進入 題目來源于CDA模擬題庫 點擊此處獲取答案 數據分析專項練習題庫 內容涵蓋Python&#xff0c;SQL&#xff0c;統計學&#xff0c;數據分析理論&#xff0c;深度學習&am…

世界商用飛機機型大全-使用Java抓取FlightAware后的答案

目錄 前言 一、數據說明 1、實時航班飛機機型數據 2、網頁結構分析 二、使用Java進行信息抓取 1、定義頁面PageVO對象 2、爬取屬性定義 3、啟動信息抓取組件 三、成果分析 1、商業飛行的飛機機型的種類 2、飛機種類排名前十名 3、航班數排名后十名 4、看中國國產大飛…

【網絡安全】一文帶你了解什么是【網絡劫持】

網絡劫持&#xff08;Network Hijacking&#xff09;是一種網絡攻擊&#xff0c;攻擊者通過非法手段劫持網絡通信&#xff0c;導致合法用戶的數據流被攔截、篡改或重定向到攻擊者控制的系統。這種攻擊可以在各種網絡層面上進行&#xff0c;包括域名系統&#xff08;DNS&#xf…

你真的會信息收集嘛,4k字滲透測試信息收集10大技巧

前言 在滲透測試中&#xff0c;信息收集是非常關鍵的一步&#xff0c;它為后續的漏洞發現和利用提供了重要的基礎。以下是非常詳細的信息收集方式&#xff1a; 一、被動信息收集 被動信息收集是指在不與目標系統直接交互的情況下&#xff0c;通過公開渠道獲取目標系統的相關…

基于51單片機的四路搶答器Protues仿真設計

一、設計背景 近年來隨著科技的飛速發展&#xff0c;單片機的應用正在不斷的走向深入。本文闡述了基于51單片機的八路搶答器設計。本設計中&#xff0c;51單片機充當了核心控制器的角色&#xff0c;通過IO口與各個功能模塊相連接。按鍵模塊負責檢測參與者的搶答動作&#xff0c…

線程交互現象

線程交互現象 小明對自家的狗子有個規定,就是在狗狗還沒吃完的時候,可以繼續給他加飯 不好的解決方式 狗狗感覺一千年沒吃飯了,狼吞虎咽起來,最后飯只剩下最后一點點,吃飯線程中使用while循環判斷是否是1,如果是1那么就一直循環,知道加飯又重新回到了起點,這雖然是狗狗…

GEE代碼實例教程詳解:湖泊面積分析

GEE代碼實例教程詳解&#xff1a;湖泊面積分析 完整代碼 // 定義研究區域的坐標點 var coordinates [[42.000552219688586, 38.18969302118053],[43.868228000938586, 38.18969302118053],[43.868228000938586, 39.209978258633186],[42.000552219688586, 39.20997825863318…

C++ --> 類和對象(一)

歡迎來到我的Blog&#xff0c;點擊關注哦&#x1f495; 前言 前面講到了C的入門需要學習的知識&#xff0c;是為了后面更好的學習。學習是不斷深入的&#xff0c;內容是不斷復雜的。篤定信心。 一、面向對象編程(OOP)和面向過程編程(POP)的認識 面向過程編程&#xff08;Proc…

力扣-貪心算法4

406.根據身高重建隊列 406. 根據身高重建隊列 題目 假設有打亂順序的一群人站成一個隊列&#xff0c;數組 people 表示隊列中一些人的屬性&#xff08;不一定按順序&#xff09;。每個 people[i] [hi, ki] 表示第 i 個人的身高為 hi &#xff0c;前面 正好 有 ki 個身高大于或…

MyBatis的簡介與使用

Mybatis JDBC操作數據庫的缺點 存在大量的冗余代碼。手工創建 Connection、Statement 等&#xff0c;效率低下。手工將結果集封裝成實體對象。查詢效率低&#xff0c;沒有對數據訪問進行優化。 Mybatis框架 簡介 MyBatis 本是 apache 的一個開源項目 iBatis, 2010年這個項目由…

imx6ull/linux應用編程學習(14) MQTT基礎知識

什么是mqtt&#xff1f; 與HTTP 協議一樣&#xff0c; MQTT 協議也是應用層協議&#xff0c;工作在 TCP/IP 四層模型中的最上層&#xff08;應用層&#xff09;&#xff0c;構建于 TCP/IP協議上。 MQTT 最大優點在于&#xff0c;可以以極少的代碼和有限的帶寬&#xff0c;為連接…

網絡資源模板--Android Studio 外賣點餐App

目錄 一、項目演示 二、項目測試環境 三、項目詳情 四、完整的項目源碼 原創外賣點餐&#xff1a;基于Android studio 實現外賣(點)訂餐系統 非原創奶茶點餐&#xff1a;網絡資源模板--基于 Android Studio 實現的奶茶點餐App報告 一、項目演示 網絡資源模板--基于Android …

在AvaotaA1全志T527開發板上使用AvaotaOS 部署 Docker 服務

Docker 是一個開源的應用容器引擎&#xff0c;讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中&#xff0c;然后發布到任何流行的 Linux或Windows操作系統的機器上&#xff0c;也可以實現虛擬化。容器是完全使用沙箱機制&#xff0c;相互之間不會有任何接口。 準備…

dolphinscheduler-springboot集成

springboot集成dolphinscheduler 說明 為了避免對DolphinScheduler產生過度依賴&#xff0c;實踐中通常不會全面采用其內置的所有任務節點類型。相反&#xff0c;會選擇性地利用DolphinScheduler的HTTP任務節點功能&#xff0c;以此作為工作流執行管理的橋梁&#xff0c;對接…

信息技術課上的紀律秘訣:營造有序學習環境

信息技術課是學生們探索數字世界的樂園&#xff0c;但同時也是課堂紀律管理的挑戰場。電腦、網絡、游戲等元素可能分散學生的注意力&#xff0c;影響學習效果。本文將分享一些有效的策略&#xff0c;幫助教師在信息技術課上維持課堂紀律&#xff0c;確保教學活動順利進行。 制…

幾何建模基礎-樣條曲線和樣條曲面介紹

1.概念介紹 1.1 樣條曲線的來源 樣條的英語單詞spline來源于可變形的樣條工具&#xff0c;那是一種在造船和工程制圖時用來畫出光滑形狀的工具&#xff1a;富有彈性的均勻細木條/金屬條/有機玻璃條&#xff0c;它圍繞著按指定位置放置的重物或者壓鐵做彈性彎曲&#xff0c;以…

JS實現一個簡單的模糊匹配

1、示例數據如下&#xff1a; // 示例數據 const data [ { name: ‘Alice’, age: 25 }, { name: ‘Bob’, age: 30 }, { name: ‘Charlie’, age: 35 }, { name: ‘David’, age: 40 }, { name: ‘Eve’, age: 45 } ]; 2、模糊匹配函數 // 模糊匹配函數 function fuzzyMatch(…

基于LangChain的RAG開發教程(二)

v1.0官方文檔&#xff1a;https://python.langchain.com/v0.1/docs/get_started/introduction/ 最新文檔&#xff1a;https://python.langchain.com/v0.2/docs/introduction/ LangChain是一個能夠利用大語言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;能…

植物大戰僵尸融合嫁接版 MAC 版本下載安裝詳細教程

繼植物大戰僵尸雜交版火了之后&#xff0c;PVZ改版可謂是百花齊放&#xff0c;最近又有一個非常好玩的模式被開發出來了&#xff0c;他們稱為《植物大戰僵尸融合嫁接版》 該版本并沒有對植物卡牌做改動&#xff0c;而是可以將任意兩種植物疊放到一起進行融合&#xff0c;產生新…