C++---命名空間

目錄

  • c語言中的問題
  • 命名空間的定義
  • 注意事項
    • 第一點:同名命名空間
    • 第二點:命名空間中的全局變量與局部變量
  • 命名空間的使用
    • 第一種使用方法
    • 第二種使用方法
    • 第三種使用方法
  • 注意事項
    • 第一點:沒有名字的命名空間
    • 第二點:局部優先原則
    • 第三點:命名空間和結構體

c語言中的問題

大家在學習c語言的時候有沒有發現一個問題,就是我們在創建變量的時候,如果兩個變量的名字是一樣的話就會報出變量重定義的問題,比如說下面的代碼:

#include<stdio.h>
int main()
{int num = 10;int num = 10;return 0;
}

我們將此代碼運行一下就可以發現我們這里會報出一個錯誤:
在這里插入圖片描述
但是我們在編寫一個大的項目的時候會創建許許多多的變量出來,而且一個大型的項目一般都是分給多個人來完成,每個人負責編寫一些文件,最后再通過#include" 文件名" 將不同程序員寫的不同的文件合并到一起,但是這樣我們就會出現一個問題就是,我們這里不同的人會創建出不同的變量,這些變量有著不同的作用和功能,但是他們可能會有同樣的名字,因為程序員在寫的時候他是不知道其他程序員是怎么想的,比如說一號程序員在寫的時候為了記錄一個函數的返回值他就創建了一個整型的變量并且將其取名為:ret,而另一個程序員在編寫程序的時候為了得到另一個函數的返回值也創建一個名為ret的整型變量,這樣的話我們將這兩個程序員寫的文件合并到一起去的時候是不是就可能出現這個問題啊,比如說下面的代碼:

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

這段代碼創建了一個全局變量rand,然后我們想在main函數里面打印一下這個rand的值,但是我們這里引入stdlib.h這個文件,在這個文件里面也使用了rand這個名字,如果我們不知道有這件事并且運行這段代碼的話,我們就會發現這里就會報出許多錯誤出來:
在這里插入圖片描述
而且一個大型的項目所需要的變量和函數是非常的多的,而這就會大大的增加因名字相同而出現問題的概率,那么為了解決這個問題我們c++就增加了一個新的內容叫命名空間。分析了c語言出現的問題原因,不同的程序創建出來的不同的變量可能會有取同樣的名字,這樣在匯總的時候就會導致出現重定義的問題,那么c++就對此給出了一個解決方法:對這些變量再加上一層包裝,并且程序員還要對這些包裝取一個名字,在這個包裝里面程序員可以添加自己想要創建的變量,定義的函數,以及結構體等等。比如說一號程序員創建了一個命名空間名為one,二號程序員創建了一個命名空間名為two,這樣兩個程序員即使在命名空間中使用了相同的變量名也不會出現錯誤。

命名空間的定義

要想使用命名空間我們就得先來認識關鍵字:namespace,他的使用模板就如下:
在這里插入圖片描述
首先寫一個namespace,然后在后面寫上這個命名空間的名字,然后在下面加一個大括號,這個大括號里面放的就是你們想創建的變量或者結構體或者函數等等,比如我們下面的代碼:

#include<stdio.h>
namespace ycf
{int a = 10;struct student{int age;char name[20];char sex[10];};int add(int x, int y){return x + y;}
}
int main()
{return 0;
}

這里就創建了一個命名空間,給命名空間取名為ycf在命名空間中創建整型變量a將其初始化為10,定義了一個add函數創建一個結構體,那么這就是ycf命令空間里面的內容,當然我們這里可以創建多個命名空間不止這一個。那么這就是我們定義命名空間的全部內容,當然這里還有一些注意事項希望大家注意一下。

注意事項

第一點:同名命名空間

如果有多個名字相同的命名空間,那么我們的編譯器就會自動地將這些命名空間進行合并,合并成同一個名字的命名空間,比如說下面的代碼:

#include<stdio.h>
namespace a
{int b = 10;int c = 20;
}
namespace a
{double e = 1.0;double f = 2.0;
}
int main()
{return 0;
}

這里創建了兩個命名空間,但是他們的名字是一樣的,那么編譯器就會將這兩個命名空間合并成一個,也就變成了這樣:

#include<stdio.h>
namespace a
{int b = 10;int c = 20;double e = 1.0;double f = 2.0;
}int main()
{return 0;
}

第二點:命名空間中的全局變量與局部變量

命名空間中定義的變量是全局變量,只有定義在函數里的變量才是局部變量。

namespace ycf
{int ret=10;int add(){int a=10;int b=10;return a+b;}
}
int main()
{return 0;
}

這段代碼中ret變量雖然在命名空間當中但是他是屬于全局變量的,在程序運行的過程中就已經創建成功了,而函數中的變量a b則是只有在調用函數add的時候才會進行創建屬于局部變量。

命名空間的使用

第一種使用方法

第一種方法使用限定符::來訪問命名空間中的變量。使用方法就是左邊放置命名空間的名稱右邊放置你想要使用的命名變量,可以通過下面的例子來學習·:

#include<stdio.h>
namespace a
{int b = 10;int c = 20;double e = 1.0;double f = 2.0;
}int main()
{printf("%d\n", a::b);printf("%f\n", a::e);return 0;
}

我們這里想打印命名空間里面的變量b和e的值,那么我們這里就用printf函數,在限定符::的左邊填入命名空間的名字,右邊填入該命名空間中你想使用的變量或者類型的名字。

第二種使用方法

第二種方法需要使用using將命名空間中某個成員引入。我們上面講過命名空間相當于是一個包裝,將不同或者相同的變量或者類型裝在一起,我們要想使用這些變量的話就得用限定符,但是有時候命名空間里面的變量我們會經常用到,不斷使用第一種方法必定會讓我們感到煩躁所以第二種方法就是直接使用,將命名空間中的特定變量解放出來,那么這里的方法就是這樣:using 命名空間 具體對象名比如下面的代碼:

#include<stdio.h>
namespace a
{int b = 10;int c = 20;double e = 1.0;double f = 2.0;int add(int x, int y){return x + y;}
}
using a::c;
using a::f;
int main()
{printf("%d\n", c);printf("%f\n", f);return 0;
}

通過這個代碼大家應該就可以發現:我們將c和f釋放之后,我們再使用命名空間里面的c和f的時就可以跟正常的變量一模一樣了,但是這個方法大家要注意的一點就是我們這里將常用的東西進行展開之后我們在自己定義變量的時候就得避免重名。

第三種使用方法

第三種方法就是將命名空間全部釋放,使用using namespace和該命名空間的名字便可以完成全部解放比如下面的代碼:

#include<stdio.h>
namespace a
{int b = 10;int c = 20;double e = 1.0;double f = 2.0;int add(int x, int y){return x + y;}
}
using namespace a;
int main()
{printf("%d\n", c);printf("%f\n", f);printf("%d\n", add(10, 20));return 0;
}

這樣我們在使用該命名空間里面的所有東西的時候都無需使用該限定符,但是這里大家要注意的一點就是:我們平時寫代碼做一些小的項目的時候可以這么使用,但是以后進入公司寫一些大項目的時候就不要這么寫了。

注意事項

第一點:沒有名字的命名空間

大家可能會看到有關限定符的這種寫法就是在限定符的左邊什么都沒有,比如說這樣:printf("%d", ::a);我們知道限定符的左邊填入的是命名空間的名字,那如果我們這里不填入呢?那他表示的意思就是我們要引入一個命名空間里面的一個變量或者類型,但是這個命名空間的名字為空,那大家這里想想,什么樣的命名空間沒有名字呢?那是不是就只能是全局變量了,所以當::左邊為空的時候,右邊的那些變量就表示的是沒有被封裝到命名空間里面的全局變量,比如說下面的代碼:

#include<stdio.h>
namespace n1
{int a = 10;
}
namespace n2
{int a = 20;
}namespace n3
{int a = 30;
}namespace n4
{int a = 40;
}
int a = 50;
int main()
{int a = 60;printf("%d", ::a);return 0;
}

大家看看這段代碼,我們這里要打印::a的值,但是我們左邊沒有給他的命名空間的名字,所以他這里就會在跑到我們的全局變量去找這里的a,因為我們這里在全局變量中定義了一個a,并將其值初始化為50,所以我們這里打印的值就是50在這里插入圖片描述
但是大家有沒有想過一個問題,為什么這里打印的為什么不是60呢?如果大家有這樣的疑問的話就得把文章往上翻看到這么一句話:命名空間中定義的變量是全局變量,只有定義在函數里的變量才是局部變量。而這個::限定符他的作用就是訪問命名空間里面的內容的,而命名空間里面的內容又全部都是全局變量不可能是局部變量,所以我們這里訪問的值都是全局變量,所以當我們不給他要訪問的命名空間的名字的時候,他要訪問也是訪問全局變量,所以這里打印的就是50,如果我們將這個全局變量的a去掉的話我們來看看會發生什么?在這里插入圖片描述
我們發現他這里就直接報錯了,所以這里大家要注意一下這種使用的情況。

第二點:局部優先原則

局部優先原則,我們在使用一個變量的時候,編譯器會先在局部中查找這個變量,如果局部沒有找到的話他就會在全局中查找這個變量比如說下面的這個代碼:

#include<stdio.h>
int a = 10;
int main()
{int a = 20;printf("%d", a);return 0;
}

這段代碼的運行結果就是20,因為在局部中定義了該名字的變量并將其值賦值為20,那么在c++中如果你想使用某個命名空間中的變量或者內容,但是該空間沒有的話他是不會在其他地方尋找的比如說下面的代碼:

#include<stdio.h>
namespace N
{int a = 10;
}
int b = 10;
int main()
{int b = 10;printf("%d", N::b);return 0;
}

我們在全局和局部中都定義了一個名為b的局部變量,但是我們在命名空間N中卻沒有定義該變量,那么我們下面要使用N中的變量b時,他就只會去命名空間N中查找該變量,如果沒找到他也不會去其他的地方進行查找,而是直接報錯,那么我們來看看這里代碼的運行結果:
在這里插入圖片描述
同樣的道理我們再來看看下面的代碼:

#include<stdio.h>
namespace N
{int a = 10;
}
int main()
{int a = 10;printf("%d", ::a);return 0;
}

我們這段代碼是在命名空間N和局部中定義了一個變量a,但是沒有在全局變量中定義一個變量a,那這時我們要打印全局變量中的變量a的話就只會在全局變量中查找,如果全局找不到也不會去局部和命名空間中查找而是直接報錯,那么我們將這段代碼運行之后就會報錯:
在這里插入圖片描述

第三點:命名空間和結構體

我們可以在命名空間里面定義一個結構體,就好比這樣:

#include<stdio.h>
namespace N
{struct student{				int age;			char name[20];char sex[10];	};
}
int main()
{return 0;
}

但是我們在使用這個結構體的時候就得這樣:先寫struct +命名空間名+限定符+定義的結構體的類型名+結構體的名字,就好比如下這樣:

#include<stdio.h>
namespace N
{struct student{				int age;			char name[20];char sex[10];	};
}
int main()
{struct N::student ycf = { 0 };return 0;
}

我們來看看這個能不能編譯成功:
在這里插入圖片描述
那么我們這里就是編譯成功的,如果我們對這個結構體加上typedef進行重命名的話我們這里就得做出一些改變我們就可以將這里的struct去掉,將后面的定義的結構體的類型名改成新的名字即可,比如下面的代碼:

#include<stdio.h>
namespace N
{typedef struct student{int age;char name[20];char sex[10];}student;
}
int main()
{N::student ycf = { 0 };return 0;
}

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

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

相關文章

Prompt逆向工程:如何“騙“大模型吐露其Prompt?

提示詞的“逆向工程”&#xff0c;讓AI大語言模型幫你反推提示詞 一、前言 在日常生活中&#xff0c;我們不時會遇到一些令人驚艷的文本&#xff0c;不論是一篇精彩絕倫的小說、一篇深入淺出的科普文章&#xff0c;還是一篇充滿熱情的音樂推薦&#xff0c;它們都能在我們的心…

Android studio常量表達式的錯誤

case R.id.openSerial485: 異常 在Android Studio中遇到“錯誤: 需要常量表達式”通常是因為在需要編譯時常量的地方使用了變量。以下是常見場景及解決方法&#xff1a; 1. switch 語句中的 case 標簽 Java要求case標簽必須是常量表達式&#xff08;如字面量或final常量&…

【UI設計】可視化大屏原型設計

文章目錄 一、墨刀中的幾個可視化大屏框架原型 一、墨刀中的幾個可視化大屏框架原型

【推理llm論文精度】DeepSeek-R1:強化學習驅動LLM推理能力飛躍

最近deepseek R1模型大火&#xff0c;正好復習一下他家的技驚四座的論文https://arxiv.org/pdf/2501.12948 近年來&#xff0c;大型語言模型&#xff08;LLM&#xff09;在推理能力上取得了顯著進展&#xff0c;但如何進一步有效提升仍然是研究熱點。DeepSeek-AI發布了 DeepS…

啟明星辰發布MAF大模型應用防火墻產品,提升DeepSeek類企業用戶安全

2月7日&#xff0c;啟明星辰面向DeepSeek等企業級大模型業務服務者提供的安全防護產品——天清MAF&#xff08;Model Application Firewall&#xff09;大模型應用防火墻產品正式發布。 一個新賽道將被開啟…… DeepSeek的低成本引爆賽道規模 隨著DeepSeek成為當前最熱的現象級…

conda將python低版本環境升級到高版本

conda將python低版本環境3.7.16升級到高版本3.8 1. 激活你的Conda環境2. 升級Python版本3. 驗證升級4. 處理依賴問題5. 測試環境注意事項 可以將Conda環境中的Python版本從3.7.16升級到3.8。以下是具體步驟&#xff1a; 1. 激活你的Conda環境 首先&#xff0c;你需要激活你想要…

day10-字符串

目錄 字符串1、API 和 API 幫助文檔2、String概述3、String構造方法代碼實現 和 內存分析3.1 創建String對象的兩種方式3.2 Java的內存模型 4、字符串的比較4.1 號的作用4.2 equals方法的作用 練習5、用戶登錄6、遍歷字符串和統計字符個數7、字符串拼接和翻轉8、較難練習-金額轉…

互聯網協議套件中的服務類型(RFC 1349)技術解析與總結

1. 背景與核心目標 RFC 1349 是對 IP 協議頭部 服務類型&#xff08;Type of Service, TOS&#xff09;字段語義的更新與澄清文檔&#xff0c;發布于 1992 年。其主要目標包括&#xff1a; 重新定義 TOS 字段的用途&#xff1a;明確 TOS 字段的語義&#xff0c;解決歷史標準中的…

使用git commit時‘“node“‘ 不是內部或外部命令,也不是可運行的程序

第一種&#xff1a; 使用git commit -m "xxx"時會報錯&#xff0c;我看網上的方法是在命令行后面添加--no-verify&#xff1a;git commit -m "主題更新" --no-verify&#xff0c;但是不可能每次都添加。 最后解決辦法是&#xff1a;使用git config --lis…

DeepSeek從入門到精通:全面掌握AI大模型的核心能力

文章目錄 一、DeepSeek是什么&#xff1f;性能對齊OpenAI-o1正式版 二、Deepseek可以做什么&#xff1f;能力圖譜文本生成自然語言理解與分析編程與代碼相關常規繪圖 三、如何使用DeepSeek&#xff1f;四、DeepSeek從入門到精通推理模型推理大模型非推理大模型 快思慢想&#x…

洛谷P3397 地毯(二維差分加暴力法)

題目難度&#xff1a;普及一 題目傳送門 地毯 題目描述 在 n n n\times n nn 的格子上有 m m m 個地毯。 給出這些地毯的信息&#xff0c;問每個點被多少個地毯覆蓋。 輸入格式 第一行&#xff0c;兩個正整數 n , m n,m n,m。意義如題所述。 接下來 m m m 行&#…

使用OBS推流,大華攝像頭 srs服務器播放

說明&#xff1a; ffmpeg可以推流&#xff0c;但是是命令行方式不太友好&#xff0c;還可以使用主流的OBS開源推流軟件&#xff0c;可從官網Open Broadcaster Software | OBS 下載最新版本&#xff0c;目前很多網絡主播都是用它做直播。該軟件支持本地視頻文件以及攝像頭推流。…

從大規模惡意攻擊 DeepSeek 事件看 AI 創新隱憂:安全可觀測體系建設刻不容緩

作者&#xff1a;羿莉&#xff08;蕭羿&#xff09; 全球出圈的中國大模型 DeepSeek 作為一款革命性的大型語言模型&#xff0c;以其卓越的自然語言處理能力和創新性成本控制引領行業前沿。該模型不僅在性能上媲美 OpenAI-o1&#xff0c;而且在推理模型的成本優化上實現了突破…

mac下dify+deepseek部署,實現私人知識庫

目前deepseek 十分火爆&#xff0c;本地部署實現私有知識庫&#xff0c;幫助自己日常工作&#xff0c;上一篇使用工具cherry studio可以做到私人知識庫。今天學習了一下&#xff0c;使用Dify鏈接deepseek&#xff0c;實現私人知識庫&#xff0c;也非常不錯&#xff0c;這里分享…

C++性能優化—人工底稿版

C以高性能著稱&#xff0c;性能優化是C程序員繞不過去的一個話題&#xff0c;性能優化是一個復雜、全局而又細節的問題&#xff0c;本文總結C性能分析中常用的知識。 性能優化的時機 大部分關于性能優化的文章都強調&#xff1a;不要過早的進行性能優化。 C編碼層面 數據結…

react概覽webpack基礎

react概覽 課程介紹 webpack 構建依賴圖->bundle 首屏渲染&#xff1a; 減少白屏等待時間 數據、結構、樣式都返回。需要服務器的支持 性能優化 ***webpack干的事情 模塊化開發 優勢&#xff1a; 多人團隊協作開發 可復用 單例&#xff1a;全局沖突 閉包 模塊導入的順序 req…

ASP.NET Core SignalR實踐指南

Hub類的生命周期是瞬態的&#xff0c;每次調用集線器的時候都會創建一個新的Hub類實例&#xff0c;因此不要在Hub類中通過屬性、成員變量等方式保存狀態。如果服務器的壓力比較大&#xff0c;建議把ASP.NET Core程序和SignalR服務器端部署到不同服務器上&#xff0c;以免它們互…

常見的九種二極管

常見的九種二極管 文章目錄 常見的九種二極管1、普通二極管2、光電二極管&#xff08;LED&#xff09;3、變容二級管4、發光二極管5、恒流二極管6、快恢復二極管&#xff08;FRD&#xff09;7、肖特基二極管8、瞬態電壓抑制二極管(TVS)9、齊納二極管&#xff08;穩壓&#xff0…

LabVIEW在呼吸機測試氣體容量計算

在呼吸機測試中&#xff0c;精確測量氣體容量變化是評估設備性能的關鍵步驟。通過監測呼吸機氣道內的壓力變化&#xff0c;并結合流阻和肺順應性等參數&#xff0c;可以計算出單位時間內的氣體容量變化。本案例基于LabVIEW實現該計算過程&#xff0c;以確保測試數據的準確性和一…

本地部署DeepSeek R1 + 界面可視化open-webui

本地部署DeepSeek R1 界面可視化open-webui ollama是物理機本地安裝 open-webui是容器啟動 另外&#xff0c;用docker 部署ollama也很方便ollama docker 安裝部署ollama ollama官網 安裝 Linux上安裝: curl -fsSL https://ollama.com/install.sh | sh使用命令行管理 拉…