?? c語言常見筆試題.txt
字號:
c語言常見筆試題總結
【1 使用宏】
1.1
#ifdef NDEBUG
#define TRACE(S) S
#else
#define TRACE(S) printf("%s;\n", #S); S
#endif
問:以上TRACE()宏的作用是什么?
1.2 #error的作用?
1.3 定義一個宏,求出給定數組中的元素的個數
#define NELEMENTS(array) ??
1.4 定義一個宏,求出給定結構中給定成員的偏移量
#define OFFSET(structure, member) ??
【2 數據聲明和定義】
給定以下類型的變量a的定義式:
a) An integer
b) A pointer to an integer
c) A pointer to a pointer to an integer
d) An array of 10 integers
e) An array of 10 pointers to integers
f) A pointer to an array of 10 integers
g) A pointer to a <I>function</I> that takes an integer as an argument and returns an integer
h) An array of ten pointers to <I>function</I>s that take an integer argument and return an integer
【3 復雜類型(1)】
有如下表達式:
char (*(*x())[])();
請用文字描述x是什么。
【4 復雜類型(2)】
jmp_buf的定義:
typedef struct _jmp_buf
{
REG_SET reg;
int extra[3];
} jmp_buf[1];
setjmp函數的原型:
extern int setjmp (jmp_buf __env);
問:調用setjmp時傳遞__env的內容,還是傳遞指針?
【5 頭文件】
問:為什么標準頭文件都有類似以下的結構?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
#endif /* __INCvxWorksh */
【6 static關鍵字】
請說出static關鍵字的3種用處:
(1)用于全局變量;
(2)用于局部變量;
(3)用于函數。
/* file.c */
static int a;
int b;
static int fn()
{
static int x;
int y;
}
【7 const關鍵字】
7.1 const關鍵字的意義是什么?
7.2 解釋以下的變量定義:
const int a1;
int const a2;
const int *a3;
int * const a4;
int const * const a5;
【8 volatile關鍵字】
8.1 volatile意義?例如
volatile int *p;
8.2 volatile能和const一起使用嗎?例如
volatile const int *p;
【9 sizeof()】
有以下定義:
char *pmsg = "A";
char msg[] = "A";
char ch = 'A';
問:
sizeof(pmsg) = ?
sizeof(msg) = ?
sizeof(“A”) = ?
sizeof(ch) = ?
sizeof(‘A’) = ? (在C++中等于多少?)
void f(char param[100])
{
// sizeof(param) = ?
}
【10 字符串】
有以下代碼
char *pmsg = "hello, world!";
strcpy(pmsg, "hi, there.");
試評論該代碼。
【11 混合運算】
有以下代碼:
void foo()
{
unsigned int a = 6;
int b = -20;
(a+b > 6) ? puts("> 6") : puts(" < = 6");
}
請問調用foo()的輸出?
【12 內存訪問】
有以下代碼:
void fn()
{
int a[100];
int *p;
p = (int *)((unsigned int)a + 1);
printf(“p=0x%x\n”, *p);
}
試評論以上代碼。
【13 C庫函數】
請說明以下函數的意義:
void perror(const char *__s);
fdprintf(int, const char *, ...);
isspace(), isxdigit(), strerr(), sprintf()
coon @ 23:44:01 | 閱讀全文 | 評論 0 | 引用 0 | 編輯
c語言筆試題(九)
2006-09-06
Tag: C語言
1.
#include "stdio.h"
int main()
{
int a;
int *p;
p = &a;
*p = 0x500;
a = (int )(*(&p));
a = (int )(&(*p));
if(a == (int)p)
printf("equal !\n");
else
printf("not equal !\n");
}
請問本程序的輸出顯示是什么?
答案:輸出顯示為”equal!”
2.
struct {
signed int bit0:1;
signed int bit1:1;
signed int bit2:1;
signed int bit3:1;
signed int bit4:1;
signed int bit5:1;
signed int bit6:1;
signed int bit7:1;
}bits;
請問sizeof(bits)是否是正確的表達式?
請問語句bits mybits; 的定義是否正確?如果不正確,要如何修改上述的結構定義才能使該語句正確?修改后的結構定義是否會影響sizeof(bits)的正確性?如果正確則該表達式的值為多少?如果將上述的結構中int類型改為char類型,此時sizeof(bits)的大小為多少?
答案:1)是正確的表達式,因為sizeof后面的內容可以是類型,也可以是變量。
2)該語句的定義不正確,因為此時的bits為一個變量;應該這樣修改結構的定義
typedef struct {
signed int bit0:1;
signed int bit1:1;
signed int bit2:1;
signed int bit3:1;
signed int bit4:1;
signed int bit5:1;
signed int bit6:1;
signed int bit7:1;
}bits;
修改后sizeof(bits)表達式依然正確,其值為4;類型改為char后其值為1,注意該值是在VC環境中的32位程序中得到的值,在不同的編譯器其值有可能不同,因此在編程時不能自己假定類似結構的大小。
3.
struct bit{
unsigned int a[0]:1,a[1]:1,a[2]:1….a[7]:1;
}
請問這種寫法是否正確?為什么?
答案:不正確,位域中的變量不能是數組。
4.
struct a {
int x;
char y;
struct a z;
struct a *p;
}
請問這種定義結構正確否? 如果有問題,問題在哪里?
答案:結構中不能對定義結構本身的非指針變量,如果編譯器支持則會導致無限嵌套,因此一般編譯器都會認為struct a是未定義的類型,即使提前聲明也不會有任何用處。
5. 什么是可重入函數?C語言中寫可重入函數,應注意的事項?
答案:可重入函數是指能夠被多個線程“同時”調用的函數,并且能保證函數結果的正確性的函數。在編寫可重入函數時通常要注意如下的一些問題:
盡量不要使用全局變量,靜態變量,如果使用了應該注意對變量訪問的互斥。通常可以根據具體的情況采用:信號量機制,關調度機制,關中斷機制等方式來保證函數的可重入性。
不要調用不可重入的函數,調用了不可重入的函數會使該函數也變為不可重入的函數。
注意對系統中的臨界資源,互斥資源的訪問方式,防止使函數成為不可重入的函數。
一般驅動程序都是不可重入的函數,因此在編寫驅動程序時一定要注意重入的問題。
6. 簡述stack frame 的含義。
答案:stack frame的中文譯名為:棧框架,表示函數在棧空間的調用層次,以x86平臺的函數調用為例,通常一個函數編譯成匯編程序,都有如下的結構:
其中的leave指令相當于:mov ebp,esp ;pop ebp
各個函數在棧空間的映象為:
test1函數 test2函數 test3函數
因此在函數test3中,就可以根據這種棧框架的形式得到函數調用層次上的每個函數的基址指針,當前棧指針,以及函數調用點等信息。
7. printf (“%d%d\n”,++n, power(2,n)); 其中power(2,n)為實現一定功能的函數 如 2^n 。
請問這種表示方法有什么潛在的問題?
答案:編譯器的不同,對++n 和power(2,n)處理的先后順序不一樣,形成二義性,造成程
序的移植性差,因此最好把++n 寫在printf函數外面,以消除二義性。
printf (s);
請問這樣的語句有沒有問題?(s為一指向有效字符串的指針)
答案:沒有%的話,可以這樣表達,如果有%在s中的話,有意想不到的輸出結果。
9. 兩段代碼共存于一個文件,編譯時有選擇的編譯其中的一部分,請問如何實現?
答案:有兩種簡單的辦法可以實現:
在源碼中使用條件編譯語句,然后在程序文件中定義宏的形式來選擇需
要的編譯代碼。
在源碼中使用條件編譯語句,然后在編譯命令的命令中加入宏定義命令
來實現選擇編譯。
10.數據結構指針傳給函數,函數能訪問數據單元,但不能修改實際的內容,如何實現?
答案:定義為指向常量的指針,這樣指針所指的數據結構中的內容就不會被改變。如:
const 類型 *p 或 類型 const *p
11. 在頭文件中定義靜態變量,可能產生什么問題?
答案:在使用了該頭文件的每個c程序文件中都單獨存在一個該靜態變量,這樣造成空間的浪費并且很容易引起錯誤。因此建議不要在頭文件中定義任何變量。
12.malloc()與 calloc()的區別?
答案:
1)參數上的區別
malloc (size_t size);
calloc (size_t n , size_t size);
malloc分配一塊size大小的內存塊,而calloc分配一個n*size大小的內存塊
2)返回內存塊的狀態不同
malloc分配的內存塊沒有被清零,而calloc分配的內存塊是清了零的。但是建議在使用內存時,如果需要初始化,則最好自己按照需要來進行初試化,不要依賴函數的實現說明。
13.寄存器變量可不可以訪問其地址?可否是全局變量?在什么場合使用寄存器變量?
答案:這些問題都與編譯器的實現有關,建議不要聲明全局變量為寄存器變量,即使是局部變量都最好不要聲明其為寄存器變量,現在的編譯器在優化時都會較為合理的安排寄存器變量的使用,而人為的安排有時會造成優化的低效。
14."\n" '\n' 的區別?
答案:前者是一個字符串并且以’/0’結束,而后者只是一個簡單的字符。
15.包含預定義頭文件< > 和" "的區別?
答案:< >只在指定的目錄里尋找被包含文件;" "先在當前目錄下查找 ,再在指定目錄下查找;通常<>方式用于系統的頭文件,而一般用戶的頭文件用" "的方式。
16.strunt S_A{
int a[10];
};
void f()
{
int i;
strunt S_A *s_ptr;
for (i=0,i<10,i++)
s_ptr -> a[i] = i;
}
請問這段代碼正確否?
答案:這段代碼不正確,沒有對s_ptr指針進行初始化,在編程中要注意此類低級錯誤的發生。
coon @ 23:37:37 | 閱讀全文 | 評論 0 | 引用 0 | 編輯
c語言筆試題(八)
2006-09-06
Tag: C語言
#pragma pack(8)
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long long e;
};
#pragma pack()
問
1.sizeof(s2) = ?
2.s2的s1中的a后面空了幾個字節接著是b?
如果您知道答案請在討論中寫出,以下是部份網友的答案,供參考:
網友rwxybh(行云)的答案:
內存布局是
1*** 11**
1111 ****
1111 1111
所以答案就是24和3
下面是一個測試的程序,試一試就知道了,我用的是VC2005
#pragma pack(8)
struct s1{
short a; // 2 BYtes
long b; // 4 Bytes
};
struct s2{
char c; // 1 Byte
s1 d; // 8 Bytes
long long e; // 8 Bytes
};
// 1*** 11**
// 1111 ****
// 1111 1111
//
// 00 01 02 03 04 05 06 07
// 00 01 02 03 04 05 06 07
// 00 01 02 03 04 05 06 07
//
#pragma pack()
int main(int argc, char* argv[])
{
s2 a;
char *p = (char *)&a;
for(int i=0;i<24;++i)
p[i] = (char)(i%8);
printf("%d\n",sizeof(a));
printf("c=0x%lx\n",a.c);
printf("d.a=0x%x\n",a.d.a);
printf("d.b=0x%x\n",a.d.b);
printf("e=0x%llx\n",a.e);
return 0;
}
結果:
24
c=0x0
d.a=0x504
d.b=0x3020100
e=0x706050403020100
網友 redleaves (ID最吊的網友)的答案和分析:
如果代碼:
#pragma pack(8)
struct S1{
char a;
long b;
};
struct S2 {
char c;
struct S1 d;
long long e;
};
#pragma pack()
sizeof(S2)結果為24.
成員對齊有一個重要的條件,即每個成員分別對齊.即每個成員按自己的方式對齊.
也就是說上面雖然指定了按8字節對齊,但并不是所有的成員都是以8字節對齊.其對齊的規則是,每個成員按其類型的對齊參數(通常是這個類型的大小)和指定對齊參數(這里是8字節)中較小的一個對齊.并且結構的長度必須為所用過的所有對齊參數的整數倍,不夠就補空字節.
S1中,成員a是1字節默認按1字節對齊,指定對齊參數為8,這兩個值中取1,a按1字節對齊;成員b是4個字節,默認是按4字節對齊,這時就按4字節對齊,所以sizeof(S1)應該為8;
S2中,c和S1中的a一樣,按1字節對齊,而d 是個結構,它是8個字節,它按什么對齊呢?對于結構來說,它的默認對齊方式就是它的所有成員使用的對齊參數中最大的一個,S1的就是4.所以,成員d就是按4字節對齊.成員e是8個字節,它是默認按8字節對齊,和指定的一樣,所以它對到8字節的邊界上,這時,已經使用了12個字節了,所以又添加了4個字節的空,從第16個字節開始放置成員e.這時,長度為24,已經可以被8(成員e按8字節對齊)整除.這樣,一共使用了24個字節.
a b
S1的內存布局:11**,1111,
c S1.a S1.b d
S2的內存布局:1***,11**,1111,****11111111
這里有三點很重要:
1.每個成員分別按自己的方式對齊,并能最小化長度
2.復雜類型(如結構)的默認對齊方式是它最長的成員的對齊方式,這樣在成員是復雜類型時,可以最小化長度
3.對齊后的長度必須是成員中最大的對齊參數的整數倍,這樣在處理數組時可以保證每一項都邊界對齊
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -