C语言 ,嵌入式 ,c++,数据结构 面试题目(4)
sizeof是C/C++中的一個操作符(operator),簡單的說其作用就是返回一個對象或者類型所占的內存字節數。
與strlen的區別:
一、sizeof
是運算符,確切的說是一個編譯時運算符,參數可以是數組、指針、類型、對象、函數等。用于統計類型或者變量所占的內存字節數。由于在編譯時計算,因此sizeof不能用來返回動態分配的內存空間的大小。
二、strlen()
是C標準庫中的字符串函數,要在運行時才能計算。參數必須是字符型指針(char*),且必須是以'\0'結尾的。它的功能是:返回字符串的長度。該字符串可能是自己定義的,也可能是內存中隨機的,該函數實際完成的功能是從代表該字符串的第一個地址開始遍歷,直到遇到結束符'\0'。返回的長度大小不包括'\0'。
三、實例
1、char?*str?=?"hello";
????? strlen(str);?//它的值是5,因為hello這個字符串有5個字符
???????????? sizeof(str);?//它的值是4,因為char?*是一個指針類型,它占4個字節。
???????????? sizeof("hello");?//它的值是5,是因為hello有5個字符,每一個字符占1個字節。
???? 2、int?a[2]?=?{0};
??????????? sizeof(a);?//它的值是8,因為a中有2個int型變量,每個int型占4個字節,所以8字節
??strlen(a) //a相當于一個指針,但是strlen只能接受char*類型,所以編譯時出錯
?
3、char arr[10] = "Hello";
? ? ? ? ? ? ? int len_one = strlen(arr);
? ? ? ? ? ? ? int len_two =sizeof(arr);?
? ? ? ? ? ? ? cout << len_one <<" and " << len_two << endl;?
? ? 輸出結果為:5 and 10
?????????? strlen只關心存儲的數據內容,不關心空間的大小和類型。???
??????? sizeof返回定義arr數組時,編譯器為其分配的數組空間大小,不關心里面存了多少數據(10x1)。 ? ?
? ?4、char * parr =new char[10];
? ? ? ? ? ? ? int len_one = strlen(parr);
? ? ? ? ? ? ? int len_two = sizeof(parr);
? ? ? ? ? ? ? int len_three = sizeof(*parr);
? ? ? ? ? ? ? cout << len_one <<" and " << len_two << " and " <<len_three << endl;
? ? 輸出結果:3 and 4 and 1
? ? ? 第一個輸出結果3實際上每次運行可能不一樣,這取決于parr里面存了什么(從parr[0]開始直到遇到第一個'\0'結束);
? ? ? 第二個結果實際上本意是想計算parr所指向的動態內存空間的大小,但是事與愿違,sizeof認為parr是個字符指針,因此返回的是該指針所占的空間(指針的存儲用的是長整型,所以為4)
???? 第三個結果,由于*parr所代表的是parr所指的地址空間存放的字符,所以長度為1。
?
面試題:定義一個空的數據類型,里面沒有任何成員變量和成員函數,對該類型求sizeof,得到的結果是多少?
答案:是1,為什么不是0?空類型的實例中不包含任何信息,本來求sizeof應該是0,但是當我們聲明該類型的實例時,它必須在內存中占有一定的空間,否則無法使用這些實例(也就不能求sizeof了),至于占用多少內存,由編譯器決定,Visual Studio中每個空類型的實例占用1字節的空間。
擴展1:如果在該類型中添加一個構造函數和析構函數,再求sizeof,得到的結果是多少?
答案:還是1。調用構造函數和析構函數只需要知道函數的地址即可,而這些地址只與類型相關,而與類型的實例無關,編譯器也不會因為這兩個函數而在實例內添加任何額外的信息。
注:不管添加的是構造函數還是析構函數還是其它任何類型的函數,都是這個結果。
擴展2:那如果把析構函數標記為虛函數呢?
答案:C++的編譯器一旦發現一個類型中有虛函數,就會為該類型生成虛函數表,并在該類型的每一個實例中添加一個指向虛函數表的指針,在32位機器上,一個指針占4字節空間,因此求sizeof得到4;如果是64位則為8。測試用例:
[cpp]?view plain?copy
1.? #include?<stdio.h>??
2.? ??
3.? struct?nullType?{?};??
4.? ??
5.? struct?type1???
6.? {??
7.? ????type1()?{}??
8.? ????~type1()?{}??
9.? ????int?print()?{?printf("Alexia");?return?0;?}??
10. };??
11. ??
12. struct?type2???
13. {??
14. ????type2()?{}??
15. ????virtual?~type2()?{}??
16. };??
17. ??
18. int?main()???
19. {??
20. ????printf("sizeof(nullType)?=?%d\n",?sizeof(nullType));??
21. ????printf("sizeof(type1)?=?%d\n",?sizeof(type1));??
22. ????printf("sizeof(type2)?=?%d\n",?sizeof(type2));??
23. ??
24. ????return?0;??
25. }??
?
原題
代碼的優化,給出下一段代碼,請做出最好的優化
intf(int n) {
??? if(n<=4)
??????? return n*n;
??? else {
??????? return f(n-4)*f(n-1)-f(n-2)*f(n-2);
??? }
}
解答
無非是將遞歸轉化為循環,防止重復計算中間值,跟斐波那契數列f(n)=f(n-1)+f(n-2)一樣,解決方式也一樣,就是利用幾個臨時變量保存中間值,然后每次循環都更新臨時變量即可。過程沒啥好說的,直接給出代碼即可。
intf2(int n) {
??? int first= 1;
??? int second= 4;
??? int third= 9;
??? int fourth= 16;
?
??? if(n<=4)
??????? return n*n;
?
??? for(int i= 5; i<= n; ++i) {
??????? int tmp= fourth * first - third * third;
??????? first = second;
??????? second = third;
??????? third = fourth;
??????? fourth = tmp;
??? }
?
??? return fourth;
}
1、局部變量能否和全局變量重名??
? 答:能,局部會屏蔽全局。要用全局變量,需要使用 "::"?
?局部變量可以與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。對于有些編譯器而言,在同一個函數內可以定義多個同名的局部變量,比如在兩個循環體內都定義一個同名的局部變量,而那個局部變量的作用域就在那個循環體內。?
?
2、如何引用一個已經定義過的全局變量??
? 答:可以用引用頭文件的方式,也可以用extern關鍵字,如果用引用頭文件方式來引用某個在頭文件中聲明的全局變量,假定你將那個變量寫錯了,那么在編譯期間會報錯,如果你用extern方式引用時,假定你犯了同樣的錯誤,那么在編譯期間不會報錯,而在連接期間報錯。?
3、全局變量可不可以定義在可被多個.C文件包含的頭文件中?為什么?
? 答:可以,在不同的C文件中以static形式來聲明同名全局變量。前提是只能有一個C文件中對此變量賦初值,連接才不會出錯?
?
4、語句for(;1 ;)有什么問題?它是什么意思?
? 答:和while(1)相同。?
5、do……while和while……do有什么區別??
? 答:前一個循環一遍再判斷,后一個判斷以后再循環
?????
6、請寫出下列代碼的輸出內容?
??
[cpp]?view plain?copy
1.? #include?<stdio.h>???
2.? main()???
3.? {???
4.? int?a,b,c,d;???
5.? a=10;???
6.? b=a++;???
7.? c=++a;????
8.? d=10*a++;???
9.? printf(?"b,c,d:%d,%d,%d",b,c,d);???
10. return?0;???
11. }??
答:10,12,120?
7、static全局變量與普通的全局變量有什么區別?static局部變量和普通局部變量有什么區別?static函數與普通函數有什么區別??
?
答:static全局變量與普通的全局變量有什么區別:static全局變量只初使化一次,防止在其他文件單元中被引用;
? ? ? ?static局部變量和普通局部變量有什么區別:static局部變量只被初始化一次,下一次依據上一次結果值;
? ? ? ?static函數與普通函數有什么區別:static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝
?
(1)用static定義的全局變量,構成靜態的全局變量,若是一個源程序由多個源文件組成,一般的全局變量在各個源文件中都是有效的,而用static修飾的全局變量只在定義該變量的源文件中是有效的,因此static限制了全局變量的作用范圍。
(2)普通局部變量在所在的函數每次調用的時候都會被重新分配存儲空間,函數結束后,就會回收該存儲空間。而用static修飾的局部變量不會,它的值始終保持著。
(3)static函數與普通函數作用域不同,它僅作用于定義它的源文件中。
(4)儲存方式:程序的局部變量存在于(堆棧)中,全局變量存在于(靜態區/全局區)中,動態申請(new)數據存在于(堆)中。
??
8.對于一個頻繁使用的短小函數,在C語言中應用什么實現,在C++中應用什么實現?
??c用宏定義, ?#define?S(a,b) a*b
? ? ?c++用inline ?
引入內聯函數的目的是為了解決程序中函數調用的效率問題。內聯函數是指用inline關鍵字修飾的函數。任何在類的說明部分定義的
函數都會被自動的認為是內聯函數。
它與一般函數所不同之處只在于函數調用的處理。
內聯函數必須是和函數體聲明在一起才有效。像這樣的申明Inline Tablefunction(int I)是沒有效果的,編譯器只是把函數作為普通的函數聲明,
我們必須定義函數體。
Inline tablefunction(int I) {return I*I};?這樣我們才算定義了一個內聯函數。我們可以把它作為一般的函數一樣調用。
但是執行速度確比一般函數的執行速度要快。
(C#有無內聯函數:C#就沒有頭文件,哪來的內聯外聯?要說內聯,應該全都是內聯,因為所有函數什么的都定義在一個文件里。存在內聯函數,但要注意,在何處內聯代碼的決定完全由CLR做出,我們無法使用像C++中inline這樣的關鍵字來控制那些方法是內聯的。)
static全局變量與普通的全局變量有什么區別?static局部變量和普通局部變量有什么區別?static函數與普通函數有什么區別?
答:
1) 全局變量(外部變量)的說明之前再冠以static就構成了靜態的全局變量。全局變量本身就是靜態存儲方式,靜態全局變量當然也是靜態存儲方式。這兩者在存儲方式上并無不同。這兩者的區別在于非靜態全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。而靜態全局變量則限制了其作用域,即只在定義該變量的源文件內有效,在同一源程序的其它源文件中不能使用它。由于靜態全局變量的作用域局限于一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。
2) 從以上分析可以看出,把局部變量改變為靜態變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量后是改變了它的作用域,限制了它的使用范圍。 ?????????????????
3) static函數與普通函數作用域不同,僅在本文件。只在當前源文件中使用的函數應該說明為內部函數(static),內部函數應該在當前源文件中說明和定義。對于可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件
綜上所述:
static全局變量與普通的全局變量有什么區別:
static全局變量只初使化一次,防止在其他文件單元中被引用;
static局部變量和普通局部變量有什么區別:
static局部變量只被初始化一次,下一次依據上一次結果值;
static函數與普通函數有什么區別:
static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝
?
什么是預編譯?何時需要預編譯?
?
什么是預編譯:
預編譯又稱為預處理 , 是做些代碼文本的替換工作。?
處理以# 開頭的指令 , 比如拷貝 #include 包含的文件代碼,#define 宏定義的替換 , 條件編譯等,就是為編譯做的預備工作的階段。
主要處理#開始的預編譯指令,預編譯指令指示了在程序正式編譯前就由編譯器進行的操作,可以放在程序中的任何位置。
C 編譯系統在對程序進行通常的編譯之前,首先進行預處理。?
c 提供的預處理功能主要有以下三種:
1 )宏定義 ?
2 )文件包含 ?
3 )條件編譯?
何時需要預編譯:
總是使用不經常改動的大型代碼體。?
程序由多個模塊組成,所有模塊都使用一組標準的包含文件和相同的編譯選項。在這種情況下,可以將所有包含文件預編譯為一個“預編譯頭”
?
?
?
const關鍵字
const是constant的簡寫,只要一個變量前面用const來修飾,就意味著該變量里的數據可以被訪問,不能被修改。也就是說const意味著“只讀”readonly
規則:const離誰近,誰就不能被修改;
const修飾一個變量,一定要給這個變量初始化值,若不初始化,后面就無法初始化。
本質:const在誰后面誰就不可以修改,const在最前面則將其后移一位,二者等效。
const關鍵字作用:
const關鍵字應用
總結
以上是生活随笔為你收集整理的C语言 ,嵌入式 ,c++,数据结构 面试题目(4)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于Docker swarm 集群搭建S
- 下一篇: R-CNN算法学习(步骤二:特征提取)