《c语言修炼内功之第二种境界(看代码就是内存)之关键字系列一》
- 前言:這個系列內容我會深入講解一下c語言中的重點內容,會把每一個知識點講的更加底層些,會增強大家的c語言內功,從內存維度看代碼你會有不同的理解。
- 第一節會比較簡單,博主為以后復習專用,大家可以用來鞏固基礎進行學習
目錄
從編譯和內存角度理解程序的運行
變量的定義和聲明
?什么是變量
?怎么樣定義變量
??為什么要定義變量呢?
變量定義的本質
變量聲明的本質
關鍵字auto
register關鍵字
從編譯和內存角度理解程序的運行
- 我們以第一個c語言程序為例進行講解?
我們理解一下這段代碼的編譯。
首先我們通過文本代碼通過編譯鏈接運行出來的可執行程序,那這個可執行程序是什么呢?
這個可執行程序其實就是我們常說的二進制文件,而這個文件又叫做可執行文件(.exe文件),這個文件我們沒編譯一段代碼都會生成這個可執行文件,而當我們清理解決方案的時候這個.exe文件就會被刪除。
那接著我們怎樣執行這個可執行文件的,一種是使用快捷鍵ctrl+f5,一種是雙擊鼠標,
那在windows系統中這種雙擊鼠標的本質是什么呢?
其實這種雙擊鼠標的實質就是在運行程序的時候,將程序加載到內存當中去。那我們啟動程序的本質是什么呢?本質就是將數據加載到內存中,能夠讓計算機運行。而我們在執行程序之前這些數據放在哪里呢?由于這些程序都是數據,我們一般存儲這些數據都放在硬盤中去,所以這些執行程序就是在硬盤中。好,最后一個問題,我們在加載程序時為什么要加載到內存中去?要說到這里就不得不提一下馮諾依曼體系(當然由于博主水平有限,只能講的淺一些)
首先馮諾依曼體系有五個部件分別是存儲器,運算器和控制器(這里統稱cpu),輸入設備,輸出設備。
?經過這個理解我們把數據加載到內存中才能更快的顯示出數據。
變量的定義和聲明
-
什么是變量
變量我們以前的理解是就是可以改變的量,而我們現在認識就不一樣了,我們現在用內存的角度可以理解是在內存中的某個位置開辟的空間就是變量。
-
怎么樣定義變量
我們一般定義變量,就是類型+變量名=默認值進行定義。
這里會有初始化和賦值的概念
這里的初始化內存為我們開辟空間,而這個空間就對應我們存放的數據。
賦值就是那個空間已經被開辟,我們把那個空間的數據要改成你要修改的值。
舉個生活中的例子:比如智商高的人和智商普通的人最總都會變成很厲害的人
初始化就是這個人一出生智商就很高這就是與生俱來。(與生俱來就在那塊空間里)
賦值就是一個智商一般的人通過自己不斷的努力成為厲害的人。(通過被修改被存放在那塊空間里)。
-
為什么要定義變量呢?
由于計算機要進行計算,但是由于數據太多,得一個個進行處理,所以這些數據就會被暫時存放,等待被執行和計算,所以我們需要變量進行暫時存放數據?。
-
變量定義的本質
- ?程序運行,需要加載到內存中
- ?程序計算,需要使用變量
- 定義變量的本質:在內存中開辟一塊空間,用來保存數據。(為何一定是內存:因為定義變量,也是程序邏輯的一部分,程序已經被加載到內存)
-
變量聲明的本質
這里我們也應該學過函數的聲明,就是聲明有這個函數的存在,而這個函數的具體功能就是函數的定義了。
關鍵字auto
其實提到auto那就跟局部變量有關,我們接下來過一下局部變量,全局變量,生命周期及作用域的概念
局部變量是什么呢?先了解啥是代碼塊也就是我們經常寫代碼時候的{}花括號。
我們將在代碼塊內部的變量叫做局部變量。全局變量相反就是定義在代碼塊外部的變量,也就有全局性,全局都可以使用。
#include <stdio.h> #include <windows.h> int g_x = 100; //全局變量 int main() { int x = 10; //局部變量,main函數也是函數,也有代碼塊{} printf("x:%d\n", x);system("pause"); return 0; } 作用域概念:指的是該變量的可以被正常訪問的代碼區域。 int main() { int x = 10; if (x == 10){ int y = 20; printf("局部: x: %d, y: %d\n", x, y);//y只能在本代碼塊內有效 }printf("局部: x: %d, y: %d\n", x, y); //報錯,y不能被訪問 system("pause"); return 0; }所以局部變量只在自己的代碼塊內部有效,而全局變量時全局有效。
#include <stdio.h> #include <windows.h> int g_x = 100; //全局變量 int main() { int g_x = 10; //局部變量,與全局同名printf("g_x:%d\n", g_x);//輸出的是局部,也就是局部和全部同名的時候,優先局部。所以,強烈不建議這樣用。system("pause");return 0; }總結:當我們局部變量和全局變量同名時候先輸出局部變量
生命周期概念:指的是該變量從定義到被釋放的時間范圍,所謂的釋放,指的是曾經開辟的空間”被釋放“ 局部變量: 進入代碼塊,形成局部變量[開辟空間],退出代碼塊,"釋放"局部變量 全局變量: 定義完成之后,程序運行的整個生命周期內,該變量一直都有效 這里我給大家講一下作用域和生命周期的區別?大家可以看一下運行結果·這段代碼想告訴我們的是關于局部變量的生命周期和作用域
可知我們這個j定義在if的代碼塊內部,出了這個代碼塊就會被銷毀所以一直是1,2交替打印,而i一直在for循環代碼塊內部沒有出for循環的代碼塊因此不銷毀。
-
register關鍵字
這個圖就是cpu內部圖,但具體的細節這里就不再講(太偏硬件了,博主學了繼續補充)。?
寄存器存在的本質 ? ? 在硬件層面上,提高計算機的運算效率。因為不需要從內存里讀取數據啦 register 修飾變量 盡量將所修飾變量,放入CPU寄存區中,從而達到提高效率的目的 register可以存放的變量 1. 局部的(全局會導致CPU寄存器被長時間占用 2. 不會被寫入的(寫入就需要寫回內存,后續還要讀取檢測的話,register的意義在哪呢?) 3. 高頻被讀取的(提高效率所在) 4. 如果要使用,請不要大量使用,因為寄存器數量有限還有一點需要注意
int main() {register int a = 0; printf("&a = %p\n", &a); //編譯器報錯:錯誤 1 error C2103: 寄存器變量上的“&” //注意,這里不是所有的編譯器都報錯,目前我們的vs是報錯的。 system("pause"); return 0; }這里利用register關鍵字修飾變量不能取地址,因為計算機已經默認他已經在寄存器中。
寄存器變量能夠被寫入但不能被取地址,編譯器必須考慮寄存器被優化,到寄存器,在內存中是直接開辟空間的,所以不能取地址。(就是已經認為在寄存器中,所以內存以為他開辟好空間)。
總結
以上是生活随笔為你收集整理的《c语言修炼内功之第二种境界(看代码就是内存)之关键字系列一》的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐17款最好用的跨浏览器测试工具
- 下一篇: 致自己,时时需要修炼内功