面試中你不可迴避的C、C++的問題(一)

1.      局部變量與全局變量問題 (使用’ ::’)

2.      如何在另個文件中引用一個全局變量 (extern)

3.      全局變量可以定義被多個C文件包含,並且是static

4.      static全局變量就是靜態全局變量,static限制了全局變量的作用域

5.      static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝.

6.      程序的局部變量存在於(堆棧)中,全局變量存在於(靜態區 )中,動態申請數據存在於(堆)中

7.      兩個棧實現一個隊列

8.      atol、atoi、fprintf---將字符串轉換成數字

9.      兩個數交換

#include <stdio.h>
#include <math.h>

int main()
{
	int a = 100,b=1000;
	int max = ((a+b)+abs(a-b))/2;
	printf("max = %d\n",max);
	max = a-b;
	char *strs[2] = {"a bigger","b bigger"};
	max = unsigned(max) >> (sizeof(int)*8-1);
	printf("max = %s\n",strs[max]);
	return 0;
}

10.  Extern “C”---extern也可用來進行鏈接指定.C++語言在編譯的時候爲了解決函數的多態問題,會將函數名和參數聯合起來生成一箇中間的函數名稱,

       而C語言則不會,因此會         造成鏈接時找不到對應函數的情況,此時C函數就需要用extern “C”進行鏈接指定,這告訴編譯器,請保持我的名稱,

       不要給我生成用於鏈接的中間函數名。

11.  C++語言的創建初衷是“abetter C”,但是這並不意味着C++中類似C語言的全局變量函數所採用的編譯和連接方式與C語言完全相同

12.  假設某個函數的原型爲:voidfoo( int x, int y );

13.  該函數被C編譯器編譯後在符號庫中的名字爲_foo,而C++編譯器則會產生像_foo_int_int之類的名字(不同的編譯器可能生成的名字不同,

        但是都採用了相同的機制,生成的新名字稱爲“mangled name”)。_foo_int_int這樣的名字包含了函數名、函數參數數量及類型信息,

        C++就是靠這種機制來實現函數重載的。例如,在C++中,函數void foo( int x, inty )與void foo( int x, float y )編譯生成的符號是不相同的,

        後者爲_foo_int_float。同樣地,C++中的變量除支持局部變量外,還支持類成員變量全局變量。用戶所編寫程序的類成員變量可能與全局變量同名,

        我們以"."來區分。而本質上,編譯器在進行編譯時,與函數的處理相似,也爲類中的變量取了一個獨一無二的名字,這個名字與用戶程序中同名的全局變量名字不同。

14.  Volatile

        a)volatile是一個類型修飾符(type specifier)。它是被設計用來修飾被不同線程訪問和修改的變量。如果沒有volatile,

           基本上會導致這樣的結果:要麼無法編寫多線程程序,要麼編譯器失去大量優化的機會。

        b)volatile的作用: 作爲指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值.簡單地說就是防止編譯器對代碼進行優化.

        c)一個定義爲volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。

          精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器裏的備份。

       d)使用的地方:中斷服務程序中修改的供其他程序檢測的變量,多任務環境下的共享標誌,存儲器映射的硬件寄存器通常也要加

15.atexit()函數的使用

/*
很多時候我們需要在程序退出的時候做一些諸如釋放資源的操作,但程序退出的方式有很多種
比如main()函數運行結束、在程序的某個地方用exit()結束程序、用戶通過Ctrl+C或Ctrl+break操作來終止程序等等
因此需要有一種與程序退出方式無關的方法來進行程序退出時的必要處理
方法就是用atexit()函數來註冊程序正常終止時要被調用的函數
atexit()函數的參數是一個函數指針,函數指針指向一個沒有參數也沒有返回值的函數。
atexit()的函數原型是:int atexit (void (*)(void));
在一個程序中最多可以用atexit()註冊32個處理函數,這些處理函數的調用順序與其註冊的順序相反
也即最先註冊的最後調用,最後註冊的最先調用。
*/
#include <stdlib.h>
#include <stdio.h>

int atexit(void (*function)(void));

void fn1(void),fn2(void),fn3(void),fn4(void);

int main(void)
{
	atexit(fn1);
	atexit(fn2);
	atexit(fn3);
	atexit(fn4);
	printf("This is executed first!\n");
	return 0;
}

void fn1()
{
	printf(" next!\n");
}
void fn2()
{
	printf(" executed");
}
void fn3()
{
	printf(" is");
}
void fn4()
{
	printf("This");
}


發佈了72 篇原創文章 · 獲贊 14 · 訪問量 89萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章