91视频免费?看_蜜芽MY188精品TV在线观看_国产免费无遮挡在线观看视频_深夜国产_亚洲精品欧洲精品_欧美黑人粗暴多交

  • 回復(fù)
  • 收藏
  • 點(diǎn)贊
  • 分享
  • 發(fā)新帖

朱兆祺教你C語言筆試、學(xué)習(xí)與機(jī)試難點(diǎn)(連載)

C語言編程中的幾個(gè)基本概念

1.1 #include< >與#include" "

1. #include< >和#include" "有什么區(qū)別?

這個(gè)題目考查大家的基礎(chǔ)能力,#include< >用來包含開發(fā)環(huán)境提供的庫,

#include" "用來包含.c/.cpp文件所在目錄下的頭文件。注意:有些開發(fā)環(huán)境可以在當(dāng)前目錄下面自動(dòng)收索(包含子目錄),有些開發(fā)環(huán)境需要指定明確的文件路徑名。

1.2 switch()

1. switch(c) 語句中 c 可以是 int, long, char, float, unsigned int 類型?

其實(shí)這個(gè)題目很基礎(chǔ),c應(yīng)該是整型或者可以隱式轉(zhuǎn)換為整型的數(shù)據(jù),很明顯不能是實(shí)型(float、double)。所以這個(gè)命題是錯(cuò)誤的。

1.3 const

1. const有什么用途?

雖然const很常用,但是我相信有很多人仍然答不上來。

(1) 欲阻止一個(gè)變量被改變,可以使用const 關(guān)鍵字。在定義該 const 變量時(shí),通常需要對(duì)它進(jìn)行初 始化,因?yàn)橐院缶蜎]有機(jī)會(huì)再去改變它了;

(2) 對(duì)指針來說,可以指定指針本身為 const,也可以指定指針?biāo)傅臄?shù)據(jù)為 const,或二者同時(shí)指定為 const;

(3) 在一個(gè)函數(shù)聲明中,const 可以修飾形參,表明它是一個(gè)輸入?yún)?shù),在函數(shù)內(nèi)部不能改變其值;

(4) 對(duì)于類的成員函數(shù),若指定其為 const 類型,則表明其是一個(gè)常函數(shù),不能修改類的成員變量;

(5) 對(duì)于類的成員函數(shù),有時(shí)候必須指定其返回值為 const 類型,以使得其返回值不為“左值”。

1.4 #ifndef/#define/#endif

1. 頭文件中的 #ifndef/#define/#endif 干什么用?

其實(shí)#ifndef、#define、#endif這些在u-boot、linux內(nèi)核文件中經(jīng)常見到,在這么大型的程序中大量使用,可見它的作用不可小覷。

這些條件預(yù)編譯多用于對(duì)代碼的編譯控制,增加代碼的可裁剪性,通過宏定義可以輕松的對(duì)代碼進(jìn)行裁剪。

#ifndef/#define/#endif最主要的作用是防止頭文件被重復(fù)定義。

1.5 全局變量和局部變量

1. 全局變量和局部變量在內(nèi)存中是否有區(qū)別?如果有,是什么區(qū)別?

全局變量?jī)?chǔ)存在靜態(tài)數(shù)據(jù)庫,局部變量在堆棧。 其實(shí),由于計(jì)算機(jī)沒有通用數(shù)據(jù)寄存器,則函數(shù)的參數(shù)、局部變量和返回值只能保存在堆棧中。提示:局部變量太大可能導(dǎo)致棧溢出,所以建議把較大數(shù)組放在main函數(shù)外,防止產(chǎn)生棧溢出。

思考:如程序清單1. 1所示。會(huì)出現(xiàn)怎樣的情況?

程序清單1. 1 大數(shù)組放在main函數(shù)中導(dǎo)致堆棧溢出

int main(int argc, char *argv[])

{

int iArray[1024 * 1024];

return 0;

}

全部回復(fù)(1)
正序查看
倒序查看
一木01
LV.3
2
2014-02-15 16:46

第二節(jié) 數(shù)據(jù)存儲(chǔ)與變量

2.1 變量的聲明與定義

1. 如程序清單2. 1所示會(huì)不會(huì)報(bào)錯(cuò)?為什么?如果不會(huì)報(bào)錯(cuò),又是輸出什么結(jié)果?

程序清單2. 1 變量的聲明與定義

#include

static int a ;

static int b[] ;

int main( int argc , char *argv[] )

{

printf( "%d %d \n" , a , b[0] ) ;

return 0 ;

}

static int a = 8 ;

static int b[4] ;

這個(gè)程序是不會(huì)報(bào)錯(cuò)的,并且連警告都不會(huì)出現(xiàn)。輸出的結(jié)果是:8 0

static int a ,這句程序是聲明全局變量a;static int b[],這句程序是聲明全局?jǐn)?shù)組變量b,并且是不完全聲明,也就是可以省略數(shù)組下標(biāo)。static int a = 8,這里才是定義全局變量a,static int b[4],這里是定義全局變量b。

2.2 局部變量與全局變量的較量

1. 請(qǐng)問如程序清單2. 2所示輸出什么?

程序清單2. 2 局部變量與全局變量

#include

static int a = 8 ;

int main( int argc , char *argv[] )

{

int a = 4 ;

printf( "%d \n" , a ) ;

return 0 ;

}

C語言規(guī)定,局部變量在自己的可見范圍內(nèi)會(huì)“擋住”同名的全局變量,讓同名的全局變量臨時(shí)不可見。即在局部變量的可見范圍內(nèi)不能訪問同名的全局變量。因此本程序輸出為:4。

2.3 char、int、float、double的數(shù)據(jù)存儲(chǔ)

1. 請(qǐng)問如程序清單2. 3所示,i和j輸出什么?

程序清單2. 3 數(shù)據(jù)存儲(chǔ)

float i = 3 ;

int j = *(int*)(&i) ;

printf( "i = %f \n" , i ) ;

printf( "j = %#x \n" , j ) ;

i是毋庸置疑是:3.000000。但是j呢?3.000000?答案是否定的,j是輸出:0x4040 0000。有人會(huì)問了,難道j是隨機(jī)輸出?瞎說,j輸出0x4040 0000是有依據(jù),是一個(gè)定值!

由于i是float數(shù)據(jù)類型,而j是int數(shù)據(jù)類型。理論上說,j是取了i的地址然后再去地址,應(yīng)該得到的就是i的值:3。但是問題的關(guān)鍵就是float數(shù)據(jù)類型的存儲(chǔ)方式和int數(shù)據(jù)類型不一樣,float是占用4個(gè)字節(jié)(32位),但是float存儲(chǔ)是使用科學(xué)計(jì)數(shù)法存儲(chǔ),最高位是存儲(chǔ)數(shù)符(負(fù)數(shù)的數(shù)符是0,正數(shù)的數(shù)符是1);接下來8位是存儲(chǔ)階碼;剩下的23位是存儲(chǔ)尾數(shù)。上面i=3.000000,那么3.000000(10進(jìn)制) = 11(2進(jìn)制) = (二進(jìn)制)。數(shù)據(jù)在電腦中存儲(chǔ)都是二進(jìn)制,這個(gè)應(yīng)該都沒有疑問。那么這里的數(shù)符為:0 ,階碼為:E – 127 = 1 ,那么階碼為:E = 128 即為:1000 0000 (2進(jìn)制) ,尾數(shù)為:100 0000 0000 0000 0000 0000 。那么存儲(chǔ)形式就是:0100 0000 0100 0000 0000 0000 0000 0000。這個(gè)數(shù)據(jù)轉(zhuǎn)換成16進(jìn)制就是0x4040 0000。

 

圖2. 1 數(shù)據(jù)存儲(chǔ)方式

char、int、float、double的存儲(chǔ)方式如圖2. 1所示。

提問:如果i = -3.5 的話,請(qǐng)問j輸出多少?

i = -3.500000

j = 0xc0600000

這個(gè)希望讀者自行分析。

再問:如果如程序清單2. 4所示。

程序清單2. 4 數(shù)據(jù)存儲(chǔ)

double i = 3 ;

int j = *(int*)(&i) ;

printf( "i = %lf \n" , i ) ;

printf( "j = %#x \n" , j ) ;

這樣的話,j又輸出多少呢?

提示:double( 8個(gè)字節(jié)(64位) )的存儲(chǔ)方式是:最高位存儲(chǔ)數(shù)符,接下來11位存儲(chǔ)階碼,剩下52位存儲(chǔ)尾數(shù)。

是不是得不到你想要的結(jié)果?double是8個(gè)字節(jié),int是4個(gè)字節(jié)。一定別忘記了這個(gè)。用這個(gè)方法也同時(shí)可以驗(yàn)證大小端模式!

2.4 容易忽略char的范圍

1. 如程序清單2. 5所示,假設(shè)&b=0x12ff54,請(qǐng)問三個(gè)輸出分別為多少?

程序清單2. 5 char的范圍

unsigned int b = 0x12ff60 ;

printf("( (int)(&b)+1 ) = %#x \n" , ( (int)(&b)+1 ) ) ;

printf("*( (int*)( (int)(&b)+1 ) ) = %#x \n" , *( (int*)( (int)(&b)+1 ) ) ) ;

printf("*( (char*)( (int)(&b)+1 ) ) = %#x \n" , *( (char*)( (int)(&b)+1 ) ) ) ;

很顯然,&b是取無符號(hào)整型b變量的地址,那么(int)(&b)是強(qiáng)制轉(zhuǎn)換為整型變量,那么加1即為0x12ff54+1=0x12ff55。所以( (int)(&b)+1 )是0x12ff55。

 

圖2. 3 指針加1取字符型數(shù)據(jù)

由于( (int)(&b)+1 )是整型數(shù)據(jù)類型,通過(int *)( (int)(&b)+1 )轉(zhuǎn)化為了整型指針類型,說明要占4個(gè)字節(jié),即為:0x12ff55、0x12ff56、0x12ff57、0x12ff58,再去地址*( (int *)( (int) (&b)+1 ) )得到存儲(chǔ)在這4個(gè)字節(jié)中的數(shù)據(jù)。但是很遺憾,0x12ff58我們并不知道存儲(chǔ)的是什么,所以我們只能寫出0x**0012ff。**表示存儲(chǔ)在0x12ff58中的數(shù)據(jù)。如圖2. 2所示。

 

圖2. 2 指針加1取整型數(shù)據(jù)

以此類推,*( (char *)( (int) (&b)+1 ) ) = 0xff。如圖2. 3所示。

但是,*( (char *)( (int) (&b)+1 ) )輸出的卻是:0xff ff ff ff !

問題出現(xiàn)了,為什么*( (char *)( (int) (&b)+1 ) )不是0xff,而是0xff ff ff ff?char型數(shù)據(jù)應(yīng)該占用1個(gè)字節(jié),為什么會(huì)輸出0xff ff ff ff?

使用%d輸出,

printf("*( (char*)( (int)(&b)+1 ) ) = %d \n" , *( (char*)( (int)(&b)+1 ) ) ) ;

結(jié)果為-1???

問題出在signed char 的范圍是:-128~127,這樣肯定無法儲(chǔ)存0xff,出現(xiàn)溢出。所以將

printf("*( (char*)( (int)(&b)+1 ) ) = %#x \n" , *( (char*)( (int)(&b)+1 ) ) ) ;

改成

printf("*( (unsigned char*)( (int)(&b)+1 ) ) = %#x \n" ,

*( (unsigned char*)( (int)(&b)+1 ) ) ) ;

就可以輸出0xff,因?yàn)閡nsigned char 的范圍是:0~255(0xff)。

0
回復(fù)
發(fā)
主站蜘蛛池模板: 岳普湖县| 龙里县| 夏河县| 南宫市| 新宾| 绍兴市| 南溪县| 彩票| 宜城市| 班玛县| 武功县| 林口县| 闸北区| 安阳县| 潮州市| 逊克县| 泾阳县| 娱乐| 嘉定区| 临夏县| 九寨沟县| 丰顺县| 靖远县| 广州市| 宝兴县| 永平县| 皋兰县| 峨眉山市| 白玉县| 安阳县| 汾西县| 曲阳县| 同德县| 遂宁市| 仙游县| 河东区| 安仁县| 潢川县| 南阳市| 如东县| 昔阳县|