乙個巨集定義引發的問題

2022-05-02 17:42:09 字數 1280 閱讀 7227

問題1:對與buffer巨集定義的理解

一些得到的基本結論:int型資料占有乙個字的空間,char型資料占有乙個位元組的空間,並且char資料型別的定義是為ascii字元表量身定製的

對與buffer的理解:

#define buffer ((char*) * (int far*)0x200)

首先,複習對與基本巨集定義的知識:對於# define pi (3.14)即pi = 3.14,在此我們首先應該認識到,最外面的括號僅僅是乙個結構,來說明裡面的內容是乙個整體。

下面來研究buffer究竟是什麼:

基本出發點:

通過研究buffer[10] = 0;這個語句的彙編結構來認識buffer是什麼

圖1通過彙編語句,我們發現,首先,我們的將偏移位址0x200變成了0x0000 0200.並不是我們想當然認為的ds:0200

於是,我們首先對(int far *)0x200進行乙個詳細深入解讀:

1.*首先賦予了0x200這個數字址的含義

2.()表明要對後面的資料進行強制性轉換,但是轉換成多少位?

3 far則表明了要將後面的資料進行4位16進製制數擴充套件成8位16進製制數。所以前面變成了0000

4 int 則表明了 0x0000 0200這個位址存放的整型資料。

清楚了上面的結構來進一步研究,則*(…) 其實就相當於取0x00000200處的內容.再將這個內容作為位址,放的是乙個char型資料,也就是說buffer代表的是乙個位址常量。

通過上面的彙編**清晰的驗證了這一點。 

在此再次總結兩個要點:1,括號裡面的*用來賦予資料實際意義,來告訴我們後面的資料是乙個位址,而不是乙個資料。2括號外面的*用來告訴我們我們要取位址裡面的內容,深入理解以上兩點對於c語言指標的理解十分必要!

其實又重新引入了這樣乙個問題:我們為什麼大費周折的讓buffer等於乙個位址裡面的內容,而不是直接等於這個位址?這樣做的意義何在

順帶思考buffer[0] = 0,&buffer,buffer = 0

如果是承接上面的內容,那麼無疑地,&buffer雖然本意是要取buffer的位址,但這樣的操作是錯誤的,因為#define定義的是常量,而常量可以認為是標號,沒有被分配給位址空間,編譯的時候直接賦予相應的值,只有變數才有取位址的意義,同樣的對buffer進行賦值同樣不正確。而buffer[0] = 0這個操作是合理的,因為這是乙個有意義的操作,是將ds:buffer+0處的記憶體賦值為0,是有確定的含義的。

進一步,我們發現刪除掉buffer  = (char*)malloc(20);

發現程式編譯連線仍讓能夠通過,說明了上述語句並不是賦值語句?

乙個巨集定義的用法

巨集定義就是簡單的替換,之前沒見過帶符號的替換,看到這個有點懵了,記錄如下。這裡用 n,代替 fninfo n,l 用的很巧妙。define fninfo n,l n,measvalue measfntbl 以下為names.h中內容 fninfo dominmaxmidhilo,min fninf...

乙個printf引發的問題

牛客網上的乙個題目 intmain 看起來挺簡單的,牽扯的東西比較多。這是我的思路 printf函式執行的時候,會先把這三個數字壓入棧裡,然後再執行列印。壓入棧的時候按照資料本身的長度來,首先把c和b壓入,並且每乙個都是8個位元組 printf自動轉化為double 然後再壓入a是4個位元組。然後再...

乙個索引引發的問題

215 上了乙個大表的組合索引,引發了查詢sql的執行計畫混亂,最終cpu充到100 業務系統掛掉,庫也幾乎宕掉。1,為什麼建了索引後,oracle執行計畫會亂掉,而且選擇了乙個最慢的執行計畫?dba答覆 表關聯!關聯表越多,oracle選擇執行計畫出錯的概率變大!如何防止此類事件 上索引之前,先固...