【Linux】環境變量與程序地址空間詳解

前言:歡迎各位光臨本博客,這里小編帶你直接手撕Linux程序地址空間,文章并不復雜,愿諸君耐其心性,忘卻雜塵,道有所長!!!!

解釋_chmod_命令_(3).gif

**🔥個人主頁:IF’Maxue-CSDN博客

🎬作者簡介:C++研發方向學習者

📖**個人專欄:
《C語言》
《C++深度學習》
《Linux》
《數據結構》
《數學建模》
**

??人生格言:生活是默默的堅持,毅力是永久的享受。不破不立,遠方請直行!

文章目錄

    • 一、環境變量:系統的“運行說明書”
      • 1. 為什么系統命令不用“找路”?靠PATH!
      • 2. 環境變量從哪來?bash“讀配置”來的
      • 3. 常用環境變量:記這幾個就夠了
      • 4. 操作環境變量:3個常用命令
      • 5. 代碼里怎么獲取環境變量?3種方法
        • 方法1:main函數的第三個參數envp
        • 方法2:getenv函數(推薦!)
        • 方法3:全局變量environ
    • 二、程序地址空間:不是內存,是“虛擬地圖”
      • 1. C程序的地址空間劃分
      • 2. 關鍵:程序地址空間 ≠ 物理內存

一、環境變量:系統的“運行說明書”

你可以把環境變量理解成Linux系統的“小記事本”——里面記滿了程序運行、系統操作需要的關鍵信息,比如“去哪找你要運行的程序”“現在登錄的是誰”“當前在哪個文件夾”,有了它,系統和程序才知道該“怎么干活”。

1. 為什么系統命令不用“找路”?靠PATH!

你有沒有好奇過:輸入ls“列出文件”、pwd“看當前路徑”時,為什么不用像自己寫的程序那樣輸全路徑(比如/home/xxx/myprogram)?答案就是PATH環境變量

  • PATH的作用:專門記錄“程序存放路徑”的列表。系統執行ls這類命令時,會順著PATH里的路徑挨個找,找到對應的程序文件就運行,找不到就提示“命令不存在”。
  • 怎么看PATH?用echo $PATH(注意$是“調用環境變量”的符號),就像這張圖里展示的:
    image.png
    圖里用echo $PATH輸出的一串路徑,就是系統找程序的“地圖”。
  • 驗證一下:如果把PATH里的路徑清空(比如PATH=),再輸ls就會提示“找不到命令”;再用PATH=$PATH:/bin/binls所在的路徑)加回去,ls又能正常用了,就像這張圖:
    image.png

如果不小心改壞了PATH也別怕——重啟電腦后,系統會重新加載配置,PATH就恢復原樣了。

2. 環境變量從哪來?bash“讀配置”來的

每次你登錄Linux,系統會啟動一個“命令解釋器”——bash(就是你輸命令的窗口)。bash不會憑空生成環境變量,而是去讀兩個關鍵配置文件:bashrcprofile,從里面加載預設的環境變量。

  • 多用戶登錄的情況:如果10個用戶同時登錄Linux,就會啟動10個bash,每個bash都會讀自己的配置文件,所以每個用戶的環境變量可以不一樣,就像這張圖里的調用關系:
    image.png

3. 常用環境變量:記這幾個就夠了

除了PATH,還有幾個常用的環境變量,用echo $變量名就能查看,對應這張圖里的內容:
image.png

環境變量作用(通俗說)例子
USER當前登錄的用戶名echo $USER 輸出 root 或你的用戶名
HISTSIZE保存多少條歷史命令默認存1000條,輸過的命令都在這
HOSTNAME這臺電腦的“名字”echo $HOSTNAME 看電腦名
PWD當前所在的文件夾路徑比如在/home,就輸出/home

比如這張圖里的PWD,就是當前的路徑:
image.png

4. 操作環境變量:3個常用命令

環境變量分兩種:本地變量(只有當前bash能用,子進程用不了)和環境變量(子進程也能繼承),用以下命令切換和操作:

  1. export:把本地變量變成環境變量
    比如先定義一個本地變量a=123,這時候運行子進程(比如自己寫的程序)拿不到a;用export a之后,a就變成環境變量,子進程也能訪問了,就像這張圖:
    image.png

  2. unset:刪除環境變量
    想刪掉某個環境變量,比如a,就輸unset a,之后echo $a就看不到值了,對應這張圖:
    image.png

  3. set:查看所有變量
    set能看到所有本地變量和環境變量,方便排查問題。

5. 代碼里怎么獲取環境變量?3種方法

自己寫C程序時,想拿到系統的環境變量,有3種常用方法:

方法1:main函數的第三個參數envp

main函數其實能接3個參數(不是只有int main()!),第三個參數envp是個字符串數組,每個元素都是一個環境變量(格式是“變量名=值”):

#include <stdio.h>
// argc:參數個數,argv:命令行參數,envp:環境變量列表
int main(int argc, char *argv[], char *envp[]) {// 循環打印所有環境變量int i = 0;while (envp[i] != NULL) {printf("%s\n", envp[i]);i++;}return 0;
}

就像這張圖里的main函數參數說明:
image.png

方法2:getenv函數(推薦!)

想直接拿某個環境變量(比如PATH),用getenv("變量名")最方便,返回值就是變量的值:

#include <stdio.h>
#include <stdlib.h> // getenv需要的頭文件int main() {// 拿PATH環境變量的值char *path = getenv("PATH");// 拿USER環境變量的值char *user = getenv("USER");printf("PATH: %s\n", path);printf("USER: %s\n", user);return 0;
}

編譯運行后,就能看到PATH和USER的值,對應這張圖:
image.png

方法3:全局變量environ

系統有個全局二級指針environ,專門存環境變量,需要用extern聲明后才能用:

#include <stdio.h>// 聲明全局變量environ
extern char **environ;int main() {int i = 0;// 循環打印所有環境變量while (environ[i] != NULL) {printf("%s\n", environ[i]);i++;}return 0;
}

就像這張圖里的environ說明:
image.png

二、程序地址空間:不是內存,是“虛擬地圖”

你寫C程序時,可能以為指針指向的是“物理內存地址”——其實不是!程序里的地址都是“虛擬地址”,而“程序地址空間”就是系統給進程畫的一張“虛擬地圖”。

1. C程序的地址空間劃分

C程序運行時,代碼和數據會被分到不同的“區域”,就像這張圖里展示的:
image.png

用通俗的話解釋這幾個區域:

  • 代碼段:存你的代碼(比如printfmain函數),是“只讀”的——你不能改代碼里的內容,比如字符串常量"hello"就存在這,像這張圖里說的“字符串被編譯成代碼,只讀”:
    image.png
  • 數據段:存全局變量和static變量(比如int g_val = 10;static int s_val = 20;),程序一啟動就分配空間。
  • :存你手動申請的內存(比如malloc(10)new int),需要自己freedelete釋放。
  • :存函數里的局部變量(比如int a = 5;),函數結束后自動釋放。

2. 關鍵:程序地址空間 ≠ 物理內存

很多人會把“程序地址空間”和“物理內存”搞混,其實它們的關系是:

  • 程序地址空間 = 虛擬地址空間:是系統給進程分配的“地址范圍”(比如0~4GB),進程以為自己獨占這部分地址。
  • 物理內存:電腦里真實的內存條(比如8GB、16GB),系統會把“虛擬地址”轉換成“物理地址”,再去訪問真實內存。

就像這張圖里強調的:C/C++指針用的都是虛擬地址,程序地址空間是“系統概念”,不是“語言概念”:
image.png

簡單說:進程拿著“虛擬地址”(地圖上的位置),系統幫它找到“物理地址”(真實的房子),這樣既能保護內存安全(進程看不到彼此的地址),又能高效利用內存。

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

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

相關文章

機器學習 - Kaggle項目實踐(8)Spooky Author Identification 作者識別

Spooky Author Identification | Kaggle Approaching (Almost) Any NLP Problem on Kaggle &#xff08;參考&#xff09; Spooky Author Identification | Kaggle &#xff08;My work&#xff09; 根據三位的一些作品訓練集&#xff0c;三分類測試集是哪個作家寫的概率。 …

[frontend]WebGL是啥?

對于初學者來說&#xff0c;通常的建議是&#xff1a; 不要直接從原生 WebGL 開始&#xff0c;而是先使用一個基于 WebGL 的高級框架或庫&#xff0c;最著名的就是 Three.js。 webgl是啥 three.js是啥&#xff1f; Three.js 封裝了 WebGL 的復雜細節&#xff0c;提供了更簡單、…

[光學原理與應用-400]:設計 - 深紫外皮秒脈沖激光器 - 元件 - 聲光調制器AOM

聲光調制器&#xff08;Acousto-Optic Modulator, AOM&#xff09;是深紫外皮秒脈沖激光器中實現脈沖主動控制、頻率穩定及光束管理的核心元件。其通過聲波與光波的彈光相互作用&#xff0c;在皮秒時間尺度內實現激光強度、頻率或傳播方向的精準調制。以下從工作原理、關鍵性能…

25高教社杯數模國賽【D題頂流思路+問題分析】

注&#xff1a;本內容由”數模加油站“ 原創出品&#xff0c;雖無償分享&#xff0c;但創作不易。歡迎參考teach&#xff0c;但請勿抄襲、盜賣或商用。后續都在”數模加油站“......

利用 openssl api 實現 TLS 雙向認證

1. 環境 openssl1.1.1gwget https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1g/openssl-1.1.1g.tar.gz sha256 為&#xff1a; ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46Linux 環境 2. 靜態編譯 openssl tar -zxvf openssl-1.1.1…

低代碼開發平臺技術總結

一、 核心定義 低代碼開發平臺&#xff08;Low-Code Development Platform, LCDP&#xff09;是一種通過圖形化界面、可視化建模、拖拽組件和模型驅動邏輯來構建應用程序的開發環境。其核心目標是顯著減少傳統手寫代碼的數量&#xff0c;從而降低開發門檻&#xff0c;提升應用交…

Web與Nginx網站服務

文章目錄前言1、Web 概念1.1 Web 的特點1.2 B/S 架構模型1.3 Web 請求與響應過程1.4 靜態資源與動態資源1.5 Web 的發展階段1.6 小結2、HTTP 與 HTTPS 協議2.1 http與https區別2.2 HTTPS 握手流程2.3 HTTP狀態碼2.3.1 HTTP 狀態碼概覽2.3.2 常用狀態碼詳解3、Nginx 概念3.1 Ngi…

【算法--鏈表】25.K個一組翻轉鏈表--通俗講解

一、題目是啥?一句話說清 給你一個鏈表,每k個節點一組進行反轉,如果最后剩余的節點不足k個,則保持原狀。需要實際交換節點,而不僅僅是改變值。 示例: 輸入:head = [1,2,3,4,5], k = 2 輸出:[2,1,4,3,5](因為每2個一組反轉,最后剩余5不足2個,保持原狀) 二、解題核…

Git指令 | 個人學習筆記

主要包含git的日常核心操作。 1.創建新倉庫 創建新文件夾&#xff0c;打開&#xff0c;然后執行。 git init2.創建一個本地倉庫的克隆版本 先cd到指定的目錄下&#xff0c;再 git clone /path/to/respository # 指定遠程分支 git clone -b <分支名> <倉庫地址> …

Apache 的安裝及基本使用

1 Apache 簡介Apache HTTP Server&#xff08;通常簡稱 “Apache”&#xff09;是世界上最流行、歷史最悠久的開源 Web 服務器軟件之一&#xff0c;由 Apache 軟件基金會&#xff08;Apache Software Foundation&#xff09;維護。它的核心功能是接收客戶端&#xff08;如瀏覽器…

五大主流大語言模型(LLM)對比

文章目錄&#x1f916; 五大主流大型語言模型&#xff08;LLM&#xff09;對比1. ChatGPT (GPT-5) - OpenAI2. Claude 4 (Sonnet & Opus) - Anthropic3. Gemini 2.5 Pro - Google DeepMind4. Grok 4 - xAI5. DeepSeek R1 - 深度求索五款模型的綜合對比表&#x1f680; 該如…

redo log詳解

在 MySQL 中&#xff0c;Redo Log&#xff08;重做日志&#xff09; 是 InnoDB 存儲引擎實現事務持久性&#xff08;ACID 中的 D&#xff09; 的核心機制&#xff0c;同時也通過 “預寫日志&#xff08;Write-Ahead Logging, WAL&#xff09;” 策略提升了數據寫入性能。它記錄…

Linux awk命令完全指南:從原理到實戰,搞定文本處理難題

在Linux世界里&#xff0c;文本處理是運維、開發繞不開的日常——從分析日志、提取配置信息到統計數據&#xff0c;都需要高效的工具支撐。而awk&#xff0c;作為一款強大的文本分析語言&#xff0c;憑借“按字段處理”的核心能力&#xff0c;成為了比grep&#xff08;單純匹配…

畢業項目推薦:68-基于yolov8/yolov5/yolo11的水稻蟲害檢測識別系統(Python+卷積神經網絡)

文章目錄 項目介紹大全&#xff08;可點擊查看&#xff0c;不定時更新中&#xff09;概要一、整體資源介紹技術要點功能展示&#xff1a;功能1 支持單張圖片識別功能2 支持遍歷文件夾識別功能3 支持識別視頻文件功能4 支持攝像頭識別功能5 支持結果文件導出&#xff08;xls格式…

Qt為什么要引入QML語言?

Qt發布于1991年&#xff0c;經過30多年的發展&#xff0c;Qt/C已經成為了眾多學子&#xff0c;拿來學習C的首選框架。Qt/Widgets&#xff0c;相對于其他界面庫&#xff08;如GNOME、KDE&#xff09;&#xff0c;其實已經很優秀&#xff0c;已經可以成為number one了。在已經是第…

設計模式在Java中的應用:從單例模式到工廠模式的全面解析!

全文目錄&#xff1a;開篇語前言1. 單例模式&#xff1a;確保全局只有一個實例1.1 餓漢式單例1.2 懶漢式單例1.3 雙重檢查鎖定&#xff08;DCL&#xff09;2. 工廠模式&#xff1a;簡化對象創建2.1 簡單工廠模式2.2 工廠方法模式2.3 抽象工廠模式3. 其他設計模式3.1 觀察者模式…

Meta AIUCSD放大招:DeepConf 讓大語言模型推理既快又準,84.7%的token節省+近乎完美的準確率!

1. 【前言】 Meta&UCSD 大語言模型&#xff08;LLMs&#xff09; 在推理任務中通過自一致性等測試時縮放方法展現出巨大潛力&#xff0c;但存在精度收益遞減和計算開銷高的問題。為此&#xff0c;Meta與UCSD的研究人員提出DeepConf方法&#xff0c;它利用模型內部的置信度信…

解決leetcode第3671.子序列美麗值求和問題

3671. 子序列美麗值求和難度&#xff1a;困難問題描述&#xff1a;給你一個長度為 n 的整數數組 nums。對于每個 正整數 g&#xff0c;定義 g 的 美麗值 為 g 與 nums 中符合要求的子序列數量的乘積&#xff0c;子序列需要 嚴格遞增 且最大公約數&#xff08;GCD&#xff09;恰…

電機控制(一)-電機分類

電機分類 電機分類&#xff1a; 電機的拓撲模型并沒有發生太大變化,變化較大的是控制電機的方法。 常見的電機類型有&#xff1a; 步進電機vs伺服電機 在工業自動化、機器人、精密設備等領域&#xff0c;步進電機和伺服電機是兩種最常用的驅動電機&#xff0c;但兩者的核心…

【Qt】QToolBar、QToolButton的常用用法

一、QToolBar 常用用法 QToolBar 是 Qt 中用于創建工具欄的控件&#xff0c;可快速放置常用功能按鈕、分隔符或自定義控件&#xff0c;并支持拖動停靠、浮動等特性。 1. 基礎創建與添加到主窗口 // 在 QMainWindow 中創建工具欄 QToolBar *toolBar new QToolBar(tr("主工…