经典C语言能力测试题(值得一看)
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                经典C语言能力测试题(值得一看)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                
                            
                            
                            絕對(duì)能夠測(cè)試你的C語(yǔ)言功力的幾個(gè)問(wèn)題!
很少有真正精通了C語(yǔ)言編程的學(xué)員,一般都有或多或少概念不是完全清楚的問(wèn)題,特別是一些需要豐富的實(shí)戰(zhàn)經(jīng)驗(yàn)才能體會(huì)和明白的問(wèn)題,如字符串,指針,類(lèi)型轉(zhuǎn)換,定義指向函數(shù)的指針類(lèi)型,這也是導(dǎo)致學(xué)習(xí)C困難的一個(gè)原因。下面有幾個(gè)簡(jiǎn)單測(cè)試將能發(fā)現(xiàn)你對(duì)C語(yǔ)言的掌握情況。
1)int x=35;
char str[10];
//問(wèn):strlen(str)和sizeof(str)的值分別是多少?
答:strlen(str) 值不確定,strlen根據(jù)'/0'確定字符串是否結(jié)束。
sizeof(str)=10 sizeof一個(gè)數(shù)組為數(shù)組長(zhǎng)度
 
strcpy(str,"www.it315.org"/*共13個(gè)字母*/);
//問(wèn):此時(shí)x和strlen(str)的值分別是多少?
答:x 為35
strcpy(char* dest, const char* src)
根據(jù)src來(lái)復(fù)制dest,依照src的'/0'決定復(fù)制的長(zhǎng)度,而dest必須要提供足夠的長(zhǎng)度,這里會(huì)引起溢出,strlen返回13,但是數(shù)組外部的數(shù)據(jù)已經(jīng)被破壞
strlen的值為13,在VC++環(huán)境下,x的值是要改變的(其他編譯器下沒(méi)試,).雖然表面上看來(lái),在程序中并沒(méi)有修改x的值,但是實(shí)際運(yùn)行的結(jié)果是上面的x的值發(fā)生了修改,這是因?yàn)閟trcpy以后,把多余的數(shù)據(jù)拷貝進(jìn)了str的鄰居(int類(lèi)型的x)中,所以x的數(shù)據(jù)也就變了.這是一個(gè)曾讓我刻骨銘心的問(wèn)題,在我剛出道時(shí)遇到這個(gè)問(wèn)題,雖然在朋友的幫助下解決了這個(gè)問(wèn)題,但一直不明白x的值為何變了,只有最后走上培訓(xùn)教師的崗位,才開(kāi)始梳理自己曾經(jīng)的困惑,才開(kāi)始總結(jié)以前的經(jīng)驗(yàn)供學(xué)員們借鑒.我覺(jué)得這個(gè)題目的價(jià)值非常之大,它能引起學(xué)員對(duì)字符串拷貝越界問(wèn)題的足夠重視,并且通過(guò)這個(gè)問(wèn)題更能明白字符串的處理是怎么回時(shí),更能明白字符串與字符數(shù)組的關(guān)系:字符串就是一個(gè)字符數(shù)組,只是把這個(gè)字符數(shù)組用在處理串的函數(shù)中時(shí),這些函數(shù)不考慮數(shù)組的長(zhǎng)度,只是記住數(shù)組的首地址,從首地址開(kāi)始處理,并在遇到0時(shí)結(jié)束處理,
 
3)char str[10];
str="it315.org";
//編譯能通過(guò)嗎?
答:數(shù)組不能賦值,只能初始化。char str[10] = "it315.org";
而且初始化時(shí)編譯器會(huì)檢查數(shù)組的長(zhǎng)度與初始化串的長(zhǎng)度是否匹配
 
4)char *pstr;
strcpy(pstr,"http://www.it315.org");
//上句編譯能通過(guò)嗎?運(yùn)行時(shí)有問(wèn)題嗎?
答:可以通過(guò)編譯,但是pstr指向了常量區(qū),運(yùn)行時(shí)最好只做讀操作,寫(xiě)操作不保險(xiǎn)。
編譯可以通過(guò),但是pstr沒(méi)有進(jìn)行有效的初始化,它指向了一個(gè)不確定的內(nèi)存區(qū),運(yùn)行時(shí)會(huì)出現(xiàn)內(nèi)存不可寫(xiě)錯(cuò)誤!
 
 
const char *p1;
char * const p2;
//上面兩句有什么區(qū)別嗎?
答:const char* 和 char const* 一樣,都是表示指向常量的字符指針。
char * const 表示指向字符的常量指針
 
p1=(const char *)str;
//如果是p1=str;編譯能夠通過(guò)嗎?明白為什么要類(lèi)型轉(zhuǎn)換?類(lèi)型轉(zhuǎn)換的本質(zhì)是什么?
答:可以通過(guò)編譯。關(guān)于常量與非常量指針的關(guān)系是這樣的:
const指針可以指向const或者非const區(qū)域,不會(huì)造成什么問(wèn)題。
非const指針不能指向const區(qū)域,會(huì)引起錯(cuò)誤。(呵呵,這個(gè)問(wèn)題,很經(jīng)典)
 
strcpy(p1,"abc");//編譯能夠通過(guò)嗎?
答:不能通過(guò),strcpy( char*, const char*); char* 不能指向const char*
注意:非const指針不能指向const區(qū)域,會(huì)引起錯(cuò)誤。
 
 
printf("%d",str);//有問(wèn)題嗎?
答:沒(méi)有問(wèn)題,輸出的是str的地址信息
 
pstr=3000;//編譯能過(guò)嗎?如果不行,該如何修改以保證編譯通過(guò)呢?
答:不能通過(guò),char* pstr表示pstr是個(gè)字符指針,不能指向3000的整形變量。
修改的話(huà),可以這樣:pstr = (char*)3000,把pstr指向3000這個(gè)地址;
 
long y=(long)pstr;//可以這樣做嗎?
答:可以,y的值為pstr所指的地址。不過(guò)如果是純粹要地址的話(huà),最好是用unsigned long。
 
int *p=str;
*p=0x00313200;
printf("%s",str);//會(huì)是什么效果?提示0x31對(duì)應(yīng)字符'1',0x32對(duì)應(yīng)字符'2'。
答:首先編譯未必會(huì)過(guò)關(guān),有些編譯器可能不允許int * 直接指向char*。最好是改為int *p = (int*)str;
過(guò)關(guān)了效果就是什么東西都沒(méi)有。int *p=str; p為str所指的地址,*p表示修改了str所指向的內(nèi)存。
由于sizeof(int)在32位機(jī)上,int有4個(gè)字節(jié)(其實(shí)具體要看編譯器的配置文件,好像是limit.h,一般是4個(gè)字節(jié))所以修改了str[0]-str[3]
由于0x00313200頭尾都是0,所以字符串為'/0'開(kāi)頭,什么都打印不出來(lái)。這里有個(gè)Big-endin和little-endin的問(wèn)題。以0x31323334為例
little-endin的機(jī)器上面,0x31323334在內(nèi)存中排列順序?yàn)?4 33 32 31,輸出為4321,如INTEL芯片的pc
big-endin機(jī)器上面為31 32 33 34 ,輸出為1234,如IBM POWERPC
 
 
p=3000;//p+1的結(jié)果會(huì)是多少?
答:3000+sizeof(int); 指針+1均為原來(lái)地址加上sizeof(指針?biāo)傅臄?shù)據(jù)類(lèi)型)
 
char *pc=new char[100];//上述語(yǔ)句在內(nèi)存中占據(jù)幾個(gè)內(nèi)存塊,怎樣的布局情況?
答: 本身pc會(huì)占用函數(shù)棧一個(gè)4字節(jié)的指針長(zhǎng)度(具體是否為4個(gè)字節(jié)要看機(jī)器和編譯器)。
new會(huì)在堆上申請(qǐng)100個(gè)字節(jié)sizeof(char)的連續(xù)空間。
 
void test(char **p)
{
*p=new char[100];
}//這個(gè)編譯函數(shù)有問(wèn)題嗎?外面要調(diào)用這個(gè)函數(shù),該怎樣傳遞參數(shù)?
答:該程序沒(méi)有問(wèn)題。需要在函數(shù)中對(duì)指針?biāo)傅牡刂愤M(jìn)行變化是必須傳入指針的地址。
原因是這樣的:如果傳入的為指針本身,在函數(shù)調(diào)用的時(shí)候,實(shí)參會(huì)被復(fù)制一個(gè)實(shí)例,這 樣就不是原來(lái)的指針了,對(duì)該指針本身進(jìn)行的任何改變都不能傳遞回去了。
可以這樣理解,如果傳入的參數(shù)為int,那么對(duì)int本身的值的改變就傳不回去啦,加個(gè)*也是一樣的。
 
//能明白typedef int (*PFUN)(int x,int y)及其作用嗎?
答:定義了一個(gè)函數(shù)指針類(lèi)型的宏,這樣PFUN就表示指向返回值為int,且同時(shí)帶2個(gè)int 參數(shù)的函數(shù)指針類(lèi)型了。
可以用來(lái)定義這樣的變量:
比如有個(gè)函數(shù)為int fun( int x, int y );
PFUN p = fun;
補(bǔ)充::函數(shù)指針最大的用處在于它可以被一個(gè)模板方法調(diào)用,這是我在學(xué)java的設(shè)計(jì)模式時(shí)領(lǐng)悟到的.例如,有兩個(gè)函數(shù)的流程結(jié)構(gòu)完全一致,只是內(nèi)部調(diào)用的具體函數(shù)不同,如下所示:
void func1()
{
//一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
int sum = add( x , y);
//一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
}
void func2()
{
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
int difference = sub( x , y);
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
}
那么,可以只定義一個(gè)函數(shù),如下所示
void func(PFUNC p)
{
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
int difference = p( x , y);
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
}
調(diào)用程序在調(diào)用時(shí),讓參數(shù)p分別指向add和sub函數(shù)就可以了.
 
對(duì)于許多類(lèi)似的問(wèn)題一般從書(shū)本上是看不到的,不通過(guò)大量的實(shí)踐與調(diào)試是難以理解和令人困惑的,所以在本文中對(duì)于類(lèi)似上述的C語(yǔ)言問(wèn)題都將作出詳細(xì)的解釋和講解。
                        
                        
                        很少有真正精通了C語(yǔ)言編程的學(xué)員,一般都有或多或少概念不是完全清楚的問(wèn)題,特別是一些需要豐富的實(shí)戰(zhàn)經(jīng)驗(yàn)才能體會(huì)和明白的問(wèn)題,如字符串,指針,類(lèi)型轉(zhuǎn)換,定義指向函數(shù)的指針類(lèi)型,這也是導(dǎo)致學(xué)習(xí)C困難的一個(gè)原因。下面有幾個(gè)簡(jiǎn)單測(cè)試將能發(fā)現(xiàn)你對(duì)C語(yǔ)言的掌握情況。
1)int x=35;
char str[10];
//問(wèn):strlen(str)和sizeof(str)的值分別是多少?
答:strlen(str) 值不確定,strlen根據(jù)'/0'確定字符串是否結(jié)束。
sizeof(str)=10 sizeof一個(gè)數(shù)組為數(shù)組長(zhǎng)度
strcpy(str,"www.it315.org"/*共13個(gè)字母*/);
//問(wèn):此時(shí)x和strlen(str)的值分別是多少?
答:x 為35
strcpy(char* dest, const char* src)
根據(jù)src來(lái)復(fù)制dest,依照src的'/0'決定復(fù)制的長(zhǎng)度,而dest必須要提供足夠的長(zhǎng)度,這里會(huì)引起溢出,strlen返回13,但是數(shù)組外部的數(shù)據(jù)已經(jīng)被破壞
strlen的值為13,在VC++環(huán)境下,x的值是要改變的(其他編譯器下沒(méi)試,).雖然表面上看來(lái),在程序中并沒(méi)有修改x的值,但是實(shí)際運(yùn)行的結(jié)果是上面的x的值發(fā)生了修改,這是因?yàn)閟trcpy以后,把多余的數(shù)據(jù)拷貝進(jìn)了str的鄰居(int類(lèi)型的x)中,所以x的數(shù)據(jù)也就變了.這是一個(gè)曾讓我刻骨銘心的問(wèn)題,在我剛出道時(shí)遇到這個(gè)問(wèn)題,雖然在朋友的幫助下解決了這個(gè)問(wèn)題,但一直不明白x的值為何變了,只有最后走上培訓(xùn)教師的崗位,才開(kāi)始梳理自己曾經(jīng)的困惑,才開(kāi)始總結(jié)以前的經(jīng)驗(yàn)供學(xué)員們借鑒.我覺(jué)得這個(gè)題目的價(jià)值非常之大,它能引起學(xué)員對(duì)字符串拷貝越界問(wèn)題的足夠重視,并且通過(guò)這個(gè)問(wèn)題更能明白字符串的處理是怎么回時(shí),更能明白字符串與字符數(shù)組的關(guān)系:字符串就是一個(gè)字符數(shù)組,只是把這個(gè)字符數(shù)組用在處理串的函數(shù)中時(shí),這些函數(shù)不考慮數(shù)組的長(zhǎng)度,只是記住數(shù)組的首地址,從首地址開(kāi)始處理,并在遇到0時(shí)結(jié)束處理,
3)char str[10];
str="it315.org";
//編譯能通過(guò)嗎?
答:數(shù)組不能賦值,只能初始化。char str[10] = "it315.org";
而且初始化時(shí)編譯器會(huì)檢查數(shù)組的長(zhǎng)度與初始化串的長(zhǎng)度是否匹配
4)char *pstr;
strcpy(pstr,"http://www.it315.org");
//上句編譯能通過(guò)嗎?運(yùn)行時(shí)有問(wèn)題嗎?
答:可以通過(guò)編譯,但是pstr指向了常量區(qū),運(yùn)行時(shí)最好只做讀操作,寫(xiě)操作不保險(xiǎn)。
編譯可以通過(guò),但是pstr沒(méi)有進(jìn)行有效的初始化,它指向了一個(gè)不確定的內(nèi)存區(qū),運(yùn)行時(shí)會(huì)出現(xiàn)內(nèi)存不可寫(xiě)錯(cuò)誤!
const char *p1;
char * const p2;
//上面兩句有什么區(qū)別嗎?
答:const char* 和 char const* 一樣,都是表示指向常量的字符指針。
char * const 表示指向字符的常量指針
p1=(const char *)str;
//如果是p1=str;編譯能夠通過(guò)嗎?明白為什么要類(lèi)型轉(zhuǎn)換?類(lèi)型轉(zhuǎn)換的本質(zhì)是什么?
答:可以通過(guò)編譯。關(guān)于常量與非常量指針的關(guān)系是這樣的:
const指針可以指向const或者非const區(qū)域,不會(huì)造成什么問(wèn)題。
非const指針不能指向const區(qū)域,會(huì)引起錯(cuò)誤。(呵呵,這個(gè)問(wèn)題,很經(jīng)典)
strcpy(p1,"abc");//編譯能夠通過(guò)嗎?
答:不能通過(guò),strcpy( char*, const char*); char* 不能指向const char*
注意:非const指針不能指向const區(qū)域,會(huì)引起錯(cuò)誤。
printf("%d",str);//有問(wèn)題嗎?
答:沒(méi)有問(wèn)題,輸出的是str的地址信息
pstr=3000;//編譯能過(guò)嗎?如果不行,該如何修改以保證編譯通過(guò)呢?
答:不能通過(guò),char* pstr表示pstr是個(gè)字符指針,不能指向3000的整形變量。
修改的話(huà),可以這樣:pstr = (char*)3000,把pstr指向3000這個(gè)地址;
long y=(long)pstr;//可以這樣做嗎?
答:可以,y的值為pstr所指的地址。不過(guò)如果是純粹要地址的話(huà),最好是用unsigned long。
int *p=str;
*p=0x00313200;
printf("%s",str);//會(huì)是什么效果?提示0x31對(duì)應(yīng)字符'1',0x32對(duì)應(yīng)字符'2'。
答:首先編譯未必會(huì)過(guò)關(guān),有些編譯器可能不允許int * 直接指向char*。最好是改為int *p = (int*)str;
過(guò)關(guān)了效果就是什么東西都沒(méi)有。int *p=str; p為str所指的地址,*p表示修改了str所指向的內(nèi)存。
由于sizeof(int)在32位機(jī)上,int有4個(gè)字節(jié)(其實(shí)具體要看編譯器的配置文件,好像是limit.h,一般是4個(gè)字節(jié))所以修改了str[0]-str[3]
由于0x00313200頭尾都是0,所以字符串為'/0'開(kāi)頭,什么都打印不出來(lái)。這里有個(gè)Big-endin和little-endin的問(wèn)題。以0x31323334為例
little-endin的機(jī)器上面,0x31323334在內(nèi)存中排列順序?yàn)?4 33 32 31,輸出為4321,如INTEL芯片的pc
big-endin機(jī)器上面為31 32 33 34 ,輸出為1234,如IBM POWERPC
p=3000;//p+1的結(jié)果會(huì)是多少?
答:3000+sizeof(int); 指針+1均為原來(lái)地址加上sizeof(指針?biāo)傅臄?shù)據(jù)類(lèi)型)
char *pc=new char[100];//上述語(yǔ)句在內(nèi)存中占據(jù)幾個(gè)內(nèi)存塊,怎樣的布局情況?
答: 本身pc會(huì)占用函數(shù)棧一個(gè)4字節(jié)的指針長(zhǎng)度(具體是否為4個(gè)字節(jié)要看機(jī)器和編譯器)。
new會(huì)在堆上申請(qǐng)100個(gè)字節(jié)sizeof(char)的連續(xù)空間。
void test(char **p)
{
*p=new char[100];
}//這個(gè)編譯函數(shù)有問(wèn)題嗎?外面要調(diào)用這個(gè)函數(shù),該怎樣傳遞參數(shù)?
答:該程序沒(méi)有問(wèn)題。需要在函數(shù)中對(duì)指針?biāo)傅牡刂愤M(jìn)行變化是必須傳入指針的地址。
原因是這樣的:如果傳入的為指針本身,在函數(shù)調(diào)用的時(shí)候,實(shí)參會(huì)被復(fù)制一個(gè)實(shí)例,這 樣就不是原來(lái)的指針了,對(duì)該指針本身進(jìn)行的任何改變都不能傳遞回去了。
可以這樣理解,如果傳入的參數(shù)為int,那么對(duì)int本身的值的改變就傳不回去啦,加個(gè)*也是一樣的。
//能明白typedef int (*PFUN)(int x,int y)及其作用嗎?
答:定義了一個(gè)函數(shù)指針類(lèi)型的宏,這樣PFUN就表示指向返回值為int,且同時(shí)帶2個(gè)int 參數(shù)的函數(shù)指針類(lèi)型了。
可以用來(lái)定義這樣的變量:
比如有個(gè)函數(shù)為int fun( int x, int y );
PFUN p = fun;
補(bǔ)充::函數(shù)指針最大的用處在于它可以被一個(gè)模板方法調(diào)用,這是我在學(xué)java的設(shè)計(jì)模式時(shí)領(lǐng)悟到的.例如,有兩個(gè)函數(shù)的流程結(jié)構(gòu)完全一致,只是內(nèi)部調(diào)用的具體函數(shù)不同,如下所示:
void func1()
{
//一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
int sum = add( x , y);
//一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
}
void func2()
{
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
int difference = sub( x , y);
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
}
那么,可以只定義一個(gè)函數(shù),如下所示
void func(PFUNC p)
{
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
int difference = p( x , y);
//與func1完全相同的一段流程代碼和面向方面的代理,如安全檢查,日志記錄等
}
調(diào)用程序在調(diào)用時(shí),讓參數(shù)p分別指向add和sub函數(shù)就可以了.
對(duì)于許多類(lèi)似的問(wèn)題一般從書(shū)本上是看不到的,不通過(guò)大量的實(shí)踐與調(diào)試是難以理解和令人困惑的,所以在本文中對(duì)于類(lèi)似上述的C語(yǔ)言問(wèn)題都將作出詳細(xì)的解釋和講解。
總結(jié)
以上是生活随笔為你收集整理的经典C语言能力测试题(值得一看)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: C/C++ 程序设计员应聘常见面试试题深
- 下一篇: 二进制地址的伙伴地址
