本文目錄一覽:
C語言和內存關係
恩,不錯,可以這麼說。
軟件是怎麼到內存並運行的呢?這個內存地址有何關係呢?
就拿任何一個windows程序來說,程序的入口點都是WinMain,這個WinMain在內存的什麼地方呢?
在win7之前,只要你不修改鏈接器選項,這個WinMain一定是在內存的0X400000.
任何程序都需要操作系統內核支持,操作系統的內核的地址是0X80000000~4GB之間。
其他的庫文件,比如C語言中支持字符串函數(如strcap)的庫在400000與80000000之間。
可見,硬盤上的exe文件在進入內存之前,就已經明確知道自己會在內存的什麼位置。
當然,這裡有個4GB虛擬地址空間的概念:在32位系統中,系統為每個exe文件分配了一個4GB的虛擬空間,無論你是否安了4G內存。很顯然,很多庫,特別是系統內核,都是能共用的,所以你的系統能同時運行多個需要4GB虛擬空間的程序。
這個和C語言的指針有何關係呢?
舉個簡單例子:每個exe文件一般需要系統的dll文件才能運行,在exe文件的開頭,有一個表記錄了該exe需要那個dll中的哪個函數。由於dll地址是固定的,函數地址為相對於該dll地址的偏移地址,所以exe能在4GB空間中找到它需要的函數。你可以通過exe文件的基地址找到這個表,這個基地址在每個程序運行時由系統交給了exe程序,這個基地址就是一個指針。然後你能修改這個指針,所以以後每次調用這個函數時,程序將轉跳到你自己的代碼中。這其實就是c語言中的函數指針的概念。
在彙編語言中是沒有指針的,因為指針本質上就是內存中的地址。exe文件和dll文件中各種基地址和偏移地址,就是你所說的“無數個指針”。
當然,以上解釋是非常淺薄的,指針、內存、地址的概念是簡單的,但在實際的系統中卻非常複雜。如果你想了解一些底層的,本質的問題,可以在學習C語言之後參考一些彙編語言,windows底層編程等書籍,比如《Windows via C/C++ 第五版》《Intel彙編語言程序設計 第五版》就是兩本很好的入門教程。
C語言高低位互換操作
在看圖形處理源碼的時候有一段宏看不懂,就寫了一個demo自己看了一下。
還是不大熟悉C語言的位操作。
這個宏挺有意思
注意 括號的位置很重要
((const uint8_t*)(x)) 這相當於把x所在的內存當做一段uint8類型的指針,索引x的第0位,因為是小端機,低位存低字節,所以[0]位存的是低字節,[1]位存的是高字節。
這樣想的話,這個宏其實很簡單了,就是把16位的無符號數,按照8位一個單位高低位互換
事實也證明如此,程序輸出如下
“c語言允許直接訪問物理地址,能進行位操作”是什麼意思啊
就是使用C語言能夠直接定位物理內存的地址,即通過內存地址(如0xfa283401)得到該地址上的數據。
計算機中的數據都是以位(bit,比特)來作為基本單位的,C語言能直接對位進行操作,包括求與,並,或,異或,非等。
物理地址是一個很寬泛的概念,磁盤,內存等存儲設備都有物理地址的說法。
物理內存地址指的是硬件實現上物理內存展現給外部總線訪問的編碼地址,其範圍等於物理內存的大小.
大家常說的物理內存就是指安裝在主板上的內存條,其實不然,在計算機的系統中,物理內存不僅包括裝在主板上的內存條(RAM),還應該包括主板BIOS芯片的ROM,顯卡上的顯存(RAM)和BIOS(ROM),以及各種PCI、PCI-E設備上的RAM和ROM。
地址空間就是對物理內存編碼(地址編碼)的範圍。
所謂編碼就是對每一個物理存儲單元(一個字節)分配一個唯一的地址號碼,這個過程又叫做“編址”或者“地址映射”。這個過程就好像在日常生活中我們給每家每戶分配一個地址門牌號。與編碼相對應的是“尋址”過程——分配一個地址號碼給一個存儲單元的目的是為了便於找到它,完成數據的讀寫,這就是“尋址”,因此地址空間有時候又被稱作“尋址空間”。系統不僅要給主板上的內存條編址,還要給上述的其它物理內存編址;它們都被編在同一個地址空間內,編址後的物理內存就可以被系統資源使用或佔用。
C語言的小問題,涉及內存、地址、位操作等。高手進。
C語言中對指針(地址)進行加減1的操作只能讓你移動到下一個或上一個存儲單元,而不能讓你移動一個二進制位,具體這個移動量是幾個字節,這是由指針的類型決定的。
也就是說,在這個程序中,p是指向int型的指針(你所在操作系統規定int型為4字節,也就是32位二進制位),因此p+1就往後挪了32個二進制位,而不是你想象的1個二進制位。假設q的類型是long int型(8字節,64個二進制位),那麼q+1就是往後挪了64個二進制位。
達到你想法的做法(用書本上的東西),我想到的是通過位運算中是“按位與”和“右移”
即(沒上機調試,可能有錯,請看其思想):
int a=某個數,你想提取是數
int b[32]={0};
int t=1;這個t的二進制形式是0000 0000 0000 0001
int i=0;這個是移動的位數
for(i=0;i=32;i++)
b[32-i-1]=(ai)t;
思想是:假設a是0000 0000 0000 0101
那麼
當i=0時,是0000 0000 0000 0101 0000 0000 0000 0001 = 0000 0000 0000 0001 = 整型的1
當i=1時,是(右移了一位以後的)0 0000 0000 0000 010 0000 0000 0000 0001 = 0000 0000 0000 0000 = 整型的0
當i=2時,是(右移了二位以後的)00 0000 0000 0000 01 0000 0000 0000 0001 = 0000 0000 0000 0001 = 整型的1
……以此類推,這樣可以提取出來每個二進制,符合你的要求
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/182087.html