1.static有什麼用途?(請至少說明兩種)ios
1)限制變量的做用域c++
2)設置變量的存儲域(堆,主動分配內存也是堆)程序員
1)在函數體,一個被聲明爲靜態的變量在這一函數被調用過程當中維持其值不變。 算法
2) 在模塊內(但在函數體外),一個被聲明爲靜態的變量能夠被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。 數據庫
3) 在模塊內,一個被聲明爲靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地範圍內使用。數組
2.全局變量和局部變量在內存中是否有區別?若是有,是什麼區別?數據結構
全局變量儲存在靜態數據庫,局部變量在棧多線程
3.堆棧溢出通常是由什麼緣由致使的?函數
堆棧溢出通常是循環的遞歸調用致使的,若是使用的大數據結構的局部變量,也可能致使堆棧溢出。沒有回收垃圾資源致使的是內存泄露最後內存耗盡。post
4.不能作switch()的參數類型是:
switch的參數不能爲實型。(只能是int char)
5.寫出float x 與「零值」比 較的if語句。
if(x<0.000001&&x>-0.000001)
6.在c語言庫函數中將一個字符轉換成整型的函數是atol()嗎,這個函數的原型是什麼?
函數名: atol
功能: 把字符串轉換成長整型數
函數的原型: long atol(const char *nptr);
程序例:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
long l;
char *str = "98765432";
l = atol(lstr);
printf("string = %s integer = %ld\n", str, l);
return(0);
}
7.對於一個頻繁使用的短小函數,在C語言中應用什麼實現,在C++中應用什麼實現?
c用宏定義,c++用inline
8.軟件測試都有那些種類?
黑盒:針對系統功能的測試 白合:測試函數功能,各函數接口
9.肯定模塊的功能和模塊的接口是在軟件設計的那個階段完成的?
概要設計階段
10.unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
請問p1+5=? ;
p2+5=? ;
答:p1+5=0x801005 ;
p2+5=0x810014 ;
11.請問下面程序有什麼錯誤?
int a[60][250][1000],i,j,k;
for(k=0;k<1000;k++)
for(j=0;j<250;j++)
for(i=0;i<60;i++)
a[i][j][k]=0;
把循環語句內外換一下
(編譯的時候沒錯,運行的時候出錯,但這個數組太大,若是放在棧中,仍是會溢出,要做爲全局變量)
12.#define Max_CB 500
void LmiQueryCSmd(Struct MSgCB * pmsg)
{
unsigned charucCmdNum;
......
for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)
{
......;
}
死循環(unsignedchar 0 到 255)
13.如下是求一個數的平方的程序,請找出錯誤:
#define SQUARE(a)((a)*(a))
int a=5;
int b;
b=SQUARE(a++);//a被加了2次 a=7,b=25
14.有一個16位的整數,每4位爲一個數,寫函數求他們的和。
解釋:
整數1101010110110111
和 1101+0101+1011+0111
/* n就是16位的數,函數返回它的四個部分之和 */
char SumOfQuaters(unsigned short n)
{
char c = 0;
int i = 4;
do
{
c += n & 15;
n = n >> 4;
} while (--i);
return c;
}
1五、兩個字符串,s,t;把t字符串接到s字符串尾,s字符串有足夠的空間存放t字符串
void connect(char *s, char *t, int i)
{
char *q =t;
char *p =s;
if(q ==NULL)return;
while(*p!='\0')
{
p++;
}
while(*q!=0)
{
*p=*q;
p++;
q++;
}
*p = '\0';
}
void main()
{
charp[7]="ABC";
charp2[]="EFG";
connect(p,p2,3);
printf("%s",p);
}
1六、分析下面的代碼:
char *a = "hello";
char *b = "hello";
if(a= =b)
printf("YES");
else
printf("NO");
常量字符串。位於靜態存儲區,它在程序生命期內恆定不變。若是編譯器優化的話,會有可能a和b同時指向同一個hello的。則地址相同。若是編譯器沒有優化,那麼就是兩個不一樣的地址,則不一樣。對VC,是相同。
1七、局部變量可否和全局變量重名?
答:能,局部會屏蔽全局。要用全局變量,須要使用"::" ;局部變量能夠與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。對於有些編譯器而言,在同一個函數內能夠定義多個同名的局部變量,好比在兩個循環體內都定義一個同名的局部變量,而那個局部變量的做用域就在那個循環體內。
1八、如何引用一個已經定義過的全局變量?
答:extern 例如在某個.cpp中定義了一個全局變量int a,可在頭文件中加入extern a;而後在須要引用的文件中包含該頭文件。或者直接在文件中加入 extern a;
1九、全局變量可不能夠定義在可被多個.C文件包含的頭文件中?爲何?
答:能夠
在頭文件中用static來定義同名全局變量。
另外某個.C文件中定義的非靜態全局變量,能夠在其頭文件中用extern聲明,需引用此全局變量的其餘.C只需包含此頭文件便可。
20、請寫出下列代碼的輸出內容
#include <stdio.h>
int main(void)
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;
}
答:10,12,120
2一、static全局變量與普通的全局變量有什麼區別?static局部變量和普通局部變量有什麼區別?static函數與普通函數有什麼區別?
答: 1) 全局變量(外部變量)的說明以前再冠以static 就構成了靜態的全局變量。全局變量自己就是靜態存儲方式,靜態全局變量固然也是靜態存儲方式。這二者在存儲方式上並沒有不一樣。
這二者的區別在於非靜態全局變量的做用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。而靜態全局變量則限制了其做用域,即只在定義該變量的源文件內有效,在同一源程序的其它源文件中不能使用它。因爲靜態全局變量的做用域侷限於一個源文件內,只能爲該源文件內的函數公用,所以能夠避免在其它源文件中引發錯誤。
2) 從以上分析能夠看出,把局部變量改變爲靜態變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變爲靜態變量後是改變了它的做用域,限制了它的使用範圍。
3) static函數與普通函數做用域不一樣,僅在本文件。只在當前源文件中使用的函數應該說明爲內部函數(static),內部函數應該在當前源文件中說明和定義。對於可在當前源文件之外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件
綜上所述:
static全局變量與普通的全局變量有什麼區別:
static全局變量只初使化一次,防止在其餘文件單元中被引用;
static局部變量和普通局部變量有什麼區別:
static局部變量只被初始化一次,下一次依據上一次結果值;
static函數與普通函數有什麼區別:
static函數在內存中只有一份,普通函數在每一個被調用中維持一份拷貝
2二、設有如下說明和定義:
typedef union
{
long i;
int k[5];//20
char c;
} DATE;
struct data
{
int cat; //4
DATE cow; //20
double dog;//8
} too;
DATE max;
則語句printf("%d",sizeof(struct data)+sizeof(max));的執行結果是:
考點:區別struct與union.(通常假定在32位機器上)
答:DATE是一個union, 變量公用空間. 裏面最大的變量類型是int[5], 佔用20個字節. 因此它的大小是20. data是一個struct, 每一個變量分開佔用空間. 依次爲int4 + DATE20 + double8 = 32. 因此結果是 20 + 32 = 52.
2三、請找出下面代碼中的全部錯誤 (題目不錯,值得一看)
說明:如下代碼是把一個字符串倒序,如「abcd」倒序後變爲「dcba」
#include"string.h"
main()
{
char*src="hello,world";
char* dest=NULL;
int len=strlen(src);
dest=(char*)malloc(len);
char* d=dest;
char* s=src[len];
while(len--!=0)
*d++=*s--;
printf("%s",dest);
return 0;
}
答:
方法1:一共有4個錯誤;
int main()
{
char* src ="hello,world";
int len = strlen(src);
char* dest =(char*)malloc(len+1);//要爲分配一個空間
char* d =dest;
char* s =&src[len-1]; //指向最後一個字符
while( len--!= 0 )
*d++=*s--;
*d = 0; //尾部要加’\0’
printf("%sn",dest);
free(dest); // 使用完,應當釋放空間,以避免形成內存匯泄露
dest = NULL; //防止產生野指針
return 0;
}
方法2: (方法一須要額外的存儲空間,效率不高.) 不錯的想法
#include <stdio.h>
#include <string.h>
main()
{
charstr[]="hello,world";
intlen=strlen(str);
char t;
for(int i=0;i<len/2; i++)
{
t=str[i];
str[i]=str[len-i-1];//當心一點
str[len-i-1]=t;
}
printf("%s",str);
return 0;
}
24.Heap與stack的差異。
答:Heap是堆,stack是棧。
Stack的空間由操做系統自動分配/釋放,Heap上的空間手動分配/釋放。
Stack空間有限,Heap是很大的自由存儲區
C中的malloc函數分配的內存空間即在堆上,C++中對應的是new操做符。
程序在編譯期對變量和函數分配內存都在棧上進行,且程序運行過程當中函數調用時參數的傳遞也在棧上進行
// 1 2 4 8 16。。。
// 1 10 100 1000 1 0000
// 0 1 11 111 1111
25. 一語句實現x是否爲2的若干次冪的判斷
#define is2*n(x) ((x & (x - 1))? 0 :1)
int main(void)
{ int m = 512;
cout << ((m & (m - 1)) ? false: true) << endl;
//即當m中只有一位爲1時,才爲若干次冪值
//考試大提示:如有兩個及以上1,則(m & (m - 1))不爲0,輸出0,表示不爲2的若干次冪
return(0);
}
類比:x爲2的若干次冪即表示x中1的位數爲1,題目轉化爲求一個32位數中1的位數,若是爲1,則表示該數爲2的若干次冪 同理也能夠利用此規則求一個32位數中1的位數, (m & (m -1)每次可用消除一個1,計算的次數即爲1的個數!
26. 下述三個有什麼區別?
char * const p;
char const * p
const char *p
解答:
char * const p; //常量指針,p的值不能夠修改
char const * p;//指向常量的指針,指向的常量值不能夠改
const char *p; //和char const *p
27. 解釋下列輸出結果
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
結果是:0 0 1 1
答:str1,str2,str3,str4是數組變量,它們有各自的內存空間;
而str5,str6,str7,str8是指針,它們指向相同的常量區域。節省內存。
28. 如下代碼中的兩個sizeof用法有問題嗎?[C易]
#include <stdio.h>
#include"iostream.h"
void UpperCase( char str[] )// 將 str 中的小寫字母轉換成大寫字母
{ int i;
for( i=0; i<sizeof(str)/sizeof(str[0]); ++i )//是指針的大小4,只循環了4次。數組作參數,會退化爲指針。可改成strlen(str)
if( 'a'<=str[i] &&str[i]<='z' )
str[i] -= ('a'-'A' );//由小寫轉大寫
}
void main()
{
char str[] = "aBcDefg";
cout << "str字符長度爲: " <<sizeof(str)/sizeof(str[0]) << endl;//是數組的大小6
UpperCase( str );
cout << str << endl;
}
答:函數內的sizeof有問題。根據語法,sizeof如用於數組,只能測出靜態數組的大小,沒法檢測動態分配的或外部數組大小。函數外的str是一個靜態定義的數組,所以其大小爲8,函數內的str實際只是一個指向字符串的指針,沒有任何額外的與數組相關的信息,所以sizeof做用於上只將其當指針看,一個指針爲4個字節,所以返回4。
注意:數組名做爲函數參數時,退化爲指針.
數組名做爲sizeof()參數時,數組名不退化,由於sizeof不是函數.
29. 一個32位的機器,該機器的指針是多少位 2^32 =4G
地址總線寬度決定了CPU能夠訪問的物理地址空間.簡單地說就是CPU到底可以使用多大容量的內存.對於386以上的微機系統.地址線的寬度爲32位.最多能夠直接訪問4096MB (4GB)的物理空間.對大多數人來講已經夠用了.
指針是多少位只要看地址總線的位數就好了。80386之後的機子都是32的數據總線。因此指針的位數就是4個字節了。
8位處理器、16位處理器、32位處理器和64位處理器,其計數都是8的倍數。它表示一個時鐘週期裏,處理器處理的二進制代碼數。「0」和「1」就是二進制代碼,線路上有電信號,則計作1,沒有電信號則爲0。8位機有8條線路,每一個時鐘週期有8個電信號,組成一個字節。因此,隨8位處理器上升至64位處理器,每一個時鐘週期傳送1個字節到8個字節,關聯到時鐘速度提升到若干個千兆赫以後,處理器處理信息的能力愈來愈大。
CPU 的一次基本運算 (and, or, xor, not), 能處理/運算幾個 bits. 64 bits data 交由 32-bit CPU 去運算, 得分兩次才行.
30. 指出下面代碼的輸出,並解釋爲何。(不錯,對地址掌握的深刻挖潛)
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);//指針是數組類型,+1至關於加20.若是是(a+1)是+4
printf(「%d %d」,a,ptr);
printf("%d,%d",*(a+1),*(ptr-1));
}
輸出:12450361245056 2,5
a,&a的地址是同樣的,但意思不同,a是數組首地址,也就是a[0]的地址,&a是對象(數組)首地址,a+1是數組下一元素的地址,即a[1],&a+1是下一個對象的地址,即a[5].
31.請問如下代碼有什麼問題:
1).int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}
答;沒有爲str分配內存空間,將會發生異常問題出在將一個字符串複製進一個字符變量指針所指地址。雖然能夠正確輸出結果,但由於越界進行內在讀寫而致使程序崩潰。
2).char* s="AAA";//常量的內容不能改,可定義爲數組
printf("%s",s);
s[0]='B';
printf("%s",s);
有什麼錯?
答:"AAA"是字符串常量。s是指針,指向這個字符串常量,因此聲明s的時候就有問題。
cosnt char* s="AAA";
而後又由於是常量,因此對是s[0]的賦值操做是不合法的。
32.用變量a給出下面的定義
a)一個整型數(An integer)
b) 一個指向整型數的指針(A pointer to an integer)
c) 一個指向指針的的指針,它指向的指針是指向一個整型數(A pointer to a pointer to an integer)
d) 一個有10個整型數的數組(An array of10 integers)
e) 一個有10個指針的數組,該指針是指向一個整型數的(An array of 10 pointers to integers)
f) 一個指向有10個整型數數組的指針(A pointerto an array of 10 integers)
g) 一個指向函數的指針,該函數有一個整型參數並返回一個整型數(A pointer to a function that takes an integer as anargument and returns an integer)
h) 一個有10個函數指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數( An array of ten pointers to functions that take aninteger argument and return an integer )
答案是:
Int (*p[10])(int); a) int a; // Aninteger
b) int *a; // A pointer to an integer
c) int **a; // A pointer to apointer to an integer
d) int a[10]; // An array of 10integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // Apointer to an array of 10 integers
g) int (*a)(int);// A pointer to afunction a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of10 pointers to functions that take an integer argument and return an integer
33.用預處理指令#define 聲明一個常數,用以代表1年中有多少秒(忽略閏年問題)
#define SECONDS_PER_YEAR (60 * 60 *24 * 365)UL
34.寫一個「標準」宏MIN,這個宏輸入兩個參數並返回較小的一個。
#defineMIN( A,B) ((A) <= (B) ?(A) :(B)) A <= B ?A : B
35.關鍵字static的做用是什麼?
在C語言中,關鍵字static有三個明顯的做用:
1). 在函數體,一個被聲明爲靜態的全局變量在這一函數被調用過程當中維持其值不變。(值的保存)
2). 在模塊內(但在函數體外),一個被聲明爲靜態的全局變量能夠被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。(限制做用域)
3). 在模塊內,一個被聲明爲靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地範圍內使用。(限制做用域)
36.關鍵字const是什麼含意?下面的聲明都是什麼意思?
1 const int a; 2 int const a;
3 const int *a; 4 int const * a;
5 int * consta; 6 int const * const a;
答:1、const inta; 2、int const a;
3、 4、內容不可變,指針可變: const int *a;
5、內容不可變,指針可變: int * const a;
6、內容可變,指針不可變 : intconst * const a;
37. 關鍵字volatile有什麼含意 並給出三個不一樣的例子。
一個定義爲volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。
精確地說就是,優化器在用到這個變量時必須每次都當心地從新讀取這個變量的值,而不是使用保存在寄存器裏的備份。
下面是volatile變量的幾個例子:
1). 並行設備的硬件寄存器(如:狀態寄存器)
2). 一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)
3). 多線程應用中被幾個任務共享的變量
39. int (*s[10])(int) 表示的是什麼?
int (*s[10])(int) 函數指針數組,每一個指針指向一個int func(int param)的函數。
40.有如下表達式:
int a=248; b=4;int const c=21;const int *d=&a;
int *const e=&b;int const int *const f=&a;
請問下列表達式哪些會被編譯器禁止?爲何?
*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;
答:*c 這是個什麼東東,禁止
d=&b是很OK
e=34 不OK
e = &a 說了是const 禁止 e的地址不能改
const int *const f =&a; 禁止 f的內容和地址都不能改
41.交換兩個變量的值,不使用第三個變量。即a=3,b=5,交換以後a=5,b=3;
答:有兩種解法,一種用算術算法, 一種用^(異或)
a = a + b;
b = a - b;
a = a - b;
or
a = a^b;// 只能對int,char..
b = a^b;
a = a^b;
2個bit (bit1與bit2異或,結果爲0說明它們不一樣,則bit2異或0可把bit1還原。
結果爲1說明它們相同,則bit2異或1可把bit1還原。
42.
#include <stdio.h>
#include <stdlib.h>
void getmemory(char *p)//函數的參數是局部變量,在這裏給它分配內存還在,可是P釋放了。
{
p=(char *) malloc(100);
}
int main( )
{
char *str=NULL;
getmemory(str);
strcpy(str,"helloworld");
printf("%s/n",str);
free(str);
return 0;
}
答: 程序崩潰,getmemory中的malloc 不能返回動態內存, free()對str操做很危險
解決方案1:可改成按引用傳遞:void getmemory(char *&p)
解決方案2:返回指針
Char* getmemory(char *p)
{
p=(char *)malloc(100);
return p;
}
43.char szstr[10];
strcpy(szstr,"0123456789");
產生什麼結果?爲何?
答;正常輸出,長度不同,會形成非法的OS,覆蓋別的內容.‘\0’沒保存
44. c指針
int *p[n];-----指針數組,每一個元素均爲指向整型數據的指針。
int (*p)[n];------p爲指向一維數組的指針,這個一維數組有n個整型數據。
int *p();----------函數帶返回指針,指針指向返回的值。
int (*p)();------p爲指向函數的指針。
45. 數組越界問題 (這個題目仍是有點小險的)
下面這個程序執行後會有什麼錯誤或者效果:
#define MAX 255
int main()
{
unsigned char A[MAX],i;
for (i=0;i<=MAX;i++)
A[i]=i;
}
解答:MAX=255,數組A的下標範圍爲:0..MAX-1,這是其一,其二當i循環到255時,循環內執行: A[255]=255;這句自己沒有問題,可是返回for (i=0;i<=MAX;i++)語句時,因爲unsigned char的取值範圍在(0..255),i++之後i又爲0了..無限循環下去.
注:char類型爲一個字節,取值範圍是[-128,127],unsigned char [0 ,255]
46. C++:memset ,memcpy 和strcpy 的根本區別?
答:#include"memory.h"
memset用來對一段內存空間所有設置爲某個字符,通常用在對定義的字符串進行初始化爲' '或'';例:char a[100];memset(a, '', sizeof(a));
memcpy用來作內存拷貝,你能夠拿它拷貝任何數據類型的對象,能夠指定拷貝的數據長度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),會形成b的內存地址溢出。
strcpy就只能拷貝字符串了,它遇到'\0'就結束拷貝;例:chara[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串長度(第一個'\0'以前)是否超過50位,如超過,則會形成b的內存地址溢出。
void main()
{
chara[100];
memset(a,'a', sizeof(a)-1);
memset(&a[99], '\0',1);
printf("%s\n",a);
charstr1[100]="abc";
charstr2[50]="efghdfkdjf";
memcpy(str1,str2, sizeof(str2));
printf("%s\n",str1);
strcpy(str1,str2);
printf("%s\n",str1);
}
strcpy 原型:
char *strcpy_su(char *dest,char *src)
{
assert((dest!=NULL)&&(src!=NULL));
char*address = dest;
while((*dest++=*src++)!='\0')
continue;
returnaddress;
}
用法:#include<string.h>
功能:把src所指由NULL結束的字符串複製到dest所指的數組中。
說明:src和dest所指內存區域不能夠重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest的指針。
memcpy原型:
void *memcpy_su(void *dest, void *src,unsigned int count)
{
assert((dest!=NULL)&&(src!=NULL));
char*bdest = (char*)dest;
char*bsrc = (char*) src;
while(count-->0)
*bdest++ = *bsrc++;
returndest;
}
用法:#include<memory.h>
功能:由src所指內存區域複製count個字節到dest所指內存區域。
說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。
Memset原型:
原型:extern void*memset(void *buffer, char c, int count);
用法:#include
功能:把buffer所指內存區域的前count個字節設置成字符c。
說明:返回指向buffer的指針。
void *memset_su(void *buffer, int c, int count)
{
assert ((buffer!=NULL));
char* buffer2 = (char*)buffer;
while(count-->0)
*buffer2++ = c;
returnbuffer;
}
47. ASSERT()是幹什麼用的
答:ASSERT()是一個調試程序時常用的宏,在程序運行時它計算括號內的表達式,若是表達式爲FALSE (0), 程序將報告錯誤,並終止執行。若是表達式不爲0,則繼續執行後面的語句。這個宏一般用來判斷程序中是否出現了明顯非法的數據,若是出現了終止程序以避免致使嚴重後果,同時也便於查找錯誤。例如,變量n在程序中不該該爲0,若是爲0可能致使錯誤,你能夠這樣寫程序:
......
ASSERT( n != 0);
k = 10/ n;
......
ASSERT只有在Debug版本中才有效,若是編譯爲Release版本則被忽略。
assert()的功能相似,它是ANSI C標準中規定的函數,它與ASSERT的一個重要區別是能夠用在Release版本中。
#include<stdio.h>
#include<assert.h>
void main()
{
int n=1;
assert( n != 0); //c c++中使用
//ASSERT( n != 0); //什麼頭文件?
printf("su\n");
}
48. 編寫用C語言實現的求n階階乘問題的遞歸算法:
答:long intfact(int n)
{
If(n==0||n==1)
Return 1;
Else
Return n*fact(n-1);
}
49. 冒泡排序:
#include"stdio.h"
voidprintArr(int R[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",R[i]);
printf("\n");
}
void swap(int* a ,int * b)
{
int c=*a;
*a=*b;
*b=c;
}
//4 冒泡排序
voidmaopaoSort(int R[],int n)
{
for(int i=0;i<n-1;i++) // 須要冒泡的次數
{ /*
for(intj=0;j<n-1-i;j++) // // 每次須要比較的次數
{
if(R[j]>R[j+1]) //大的往下沉
{
swap(&R[j],&R[j+1]);
}
}
*/
for(int j=n-1;j>i;j--) // // 每次須要比較的次數
{
if(R[j]<R[j-1]) //小的往上冒
{
swap(&R[j],&R[j-1]);
}
}
}
}
void main()
{
int i;
int num[6]={0};
printf("Please input 6 numbers:\n");
for(i=0;i<6;i++)
scanf("%d",&num[i]);
puts("before sort:");
printArr(num,6);
maopaoSort(num,6);
puts("after sort:");
printArr(num,6);
}
50.再看看下面的一段程序有什麼錯誤:
swap( int* p1,int* p2 )
{
int *p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
在swap函數中,p是一個「野」指針,有可能指向系統區,致使程序運行的崩潰。在VC++中DEBUG運行時提示錯誤「Access Violation」。該程序應該改成:
swap( int* p1,int* p2 )
{
int p;
p = *p1;
*p1 = *p2;
*p2 = p;
}
51.分別給出BOOL,int,float,指針變量 與「零值」比較的if 語句(假設變量名爲var)
解答:
BOOL型變量:if(!var)
int型變量: if(var==0)
float型變量:
const floatEPSINON = 0.00001;
if ((x >= -EPSINON) && (x <= EPSINON)
指針變量: if(NULL ==var)
52.如下爲Windows NT下的32位C++程序,請計算sizeof的值
void Func ( char str[100] )
{
sizeof( str ) = ?
}
void *p = malloc( 100 );
sizeof ( p ) = ?
解答:
sizeof( str ) = 4
sizeof ( p ) = 4
剖析:
Func ( char str[100] )函數中數組名做爲函數形參時,在函數體內,數組名失去了自己的內涵,僅僅只是一個指針;在失去其內涵的同時,它還失去了其常量特性,能夠做自增、自減等操做,能夠被修改。
數組名的本質以下:
(1)數組名指代一種數據結構,這種數據結構就是數組;
例如:
char str[10];
cout << sizeof(str) << endl;
輸出結果爲10,str指代數據結構char[10]。
(2)數組名能夠轉換爲指向其指代實體的指針,並且是一個指針常量,不能做自增、自減等操做,不能被修改;
char str[10];
str++; //編譯出錯,提示str不是左值
(3)數組名做爲函數形參時,淪爲普通指針。
Windows NT 32位平臺下,指針的長度(佔用內存的大小)爲4字節,故sizeof( str ) 、sizeof ( p ) 都爲4。
53.寫一個「標準」宏MIN,這個宏輸入兩個參數並返回較小的一個。另外,當你寫下面的代碼時會發生什麼事?
least = MIN(*p++, b);
解答:
#define MIN(A,B) ((A) <= (B) ? (A) :(B))
MIN(*p++, b)會產生宏的反作用
剖析:
(1)謹慎地將宏定義中的「參數」和整個宏用用括弧括起來。因此,嚴格地講,下述解答:
#define MIN(A,B) (A) <= (B) ? (A) : (B)
#define MIN(A,B) (A <= B ? A : B )
#define MIN(A,B) ((A) <= (B) ? (A) :(B));
都應判0分;
(2)防止宏的反作用。
宏定義#defineMIN(A,B) ((A) <= (B) ? (A) : (B))對MIN(*p++, b)的做用結果是:
((*p++) <= (b) ? (*p++) : (b))
這個表達式會產生反作用,指針p會做2次++自增操做。
//」dfjdosfjkodskf」 「dos」 1000 3
54.請編寫能直接實現strstr()函數功能的代碼。 // strstr(str,substr);在str中找substr,找到後把後面的所有截取返回。
#include <iostream>
using std::cout;
using std::endl;
char* my_strstr( char* str1, char* str2 )
{
if (NULL == str1 || NULL == str2)
{
throw;
}
char *p = NULL;
char *q = NULL;
const char v = '\0';
for (int i=0; v != str1[i]; ++i)
{
p = &str1[i];
q = str2;
while (v != *q && *q == *p)
{
++p; ++q;
}
if ('\0' == *q)
{
return &str1[i];
}
}
return NULL;
}
int main( void )
{ char a[] = "ok2002.com";
char* p = my_strstr( a, "com" );
if (NULL == p)
{
cout << "not find" << endl;
}
else {
cout << p << endl;
}
p = my_strstr( a, "2002" );
if (NULL == p)
{ cout << "not find" << endl; }
else {
cout << p << endl;
}
}
55.寫一個函數,檢查字符是不是整數,若是是,返回其整數值。(或者:怎樣只用4行代碼,編寫出一個從字符串到長整形的函數?)
析 :掃描一遍,每次生成對應整數的最高位。一行也就搞定了!
//」1234」-à1*1000+2*100+3*10+4 ‘0’---‘9’「1234」1234
longconvert(char* s_string)
{
long s_integer=0;
for(int sLen = strlen(s_string),i = 0; i < sLen;s_integer += (s_string[i++] - '0')*pow(10,sLen - i - 1));
return s_integer;
}
12 21 23 34 15
56.對1,2,3, 4, 5 這五個數任意取出兩個數,列出他們的全部組合。
void main()
{
char a[]={'1','2','3','4','5'};
for(int i=0;i<5-1;i++)
{
for(intj=i+1;j<5;j++)
if(a[i]!=a[j])
{
cout<<a[i]<<a[j]<<" ";
cout<<a[j]<<a[i]<<" ";
}
cout<<endl;
}
}
//12 21 13 31 1441 15 51
//23 32 24 42 2552
//34 43 35 53
//45 54
57 . 用預處理指令#define 聲明一個常數,用以代表1年中有多少秒(忽略閏年問題)
#define SECONDS_PER_YEAR (60 * 60 *24 * 365)UL
1) #define 語法的基本知識(例如:不能以分號結束,括號的使用,等等)
2)懂得預處理器將爲你計算常數表達式的值,所以,直接寫出你是怎麼樣計算一年中有多少秒而不是計算出實際的值,是更清晰而沒有代價的。
3) 意識到這個表達式將使一個16位機的整型數溢出-所以要用到長整型符號L,告訴編譯器這個常數是的長整型數。
4) 若是你在你的表達式中用到UL(表示無符號長整型),那麼你有了一個好的起點。記住,第一印象很重要。
58.
1). 一個參數既能夠是const還能夠是volatile嗎?解釋爲何。
2). 一個指針能夠是volatile嗎?解釋爲何。
3). 下面的函數有什麼錯誤:
int square(volatile int *ptr)
{
return (*ptr) * (*ptr);
}
下面是答案:
1). 是的。一個例子是隻讀的狀態寄存器。它是volatile由於它可能被意想不到地改變。它是const由於程序不該該試圖去修改它。
2). 是的。儘管這並不很常見。一個例子是當一箇中服務子程序修該一個指向一個buffer的指針時。
3). 這段代碼的有個惡做劇。這段代碼的目的是用來返指針*ptr指向值的平方,可是,因爲*ptr指向一個volatile型參數,
編譯器將產生相似下面的代碼:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a *b;
}
因爲*ptr的值可能被意想不到地該變,所以a和b多是不一樣的。結果,這段代碼可能返不是你所指望的平方值!正確的代碼以下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a *a;
}
59. 嵌入式系統老是要用戶對變量或寄存器進行位操做。給定一個整型變量a,寫兩段代碼,第一個設置a的bit 3,
第二個清除a 的bit 3。在以上兩個操做中,要保持其它位不變。
#define BIT3 (0x1<<3)
static int a;
void set_bit3(void)
{
a |= BIT3;
}
void clear_bit3(void)
{
a &=~BIT3;
}
訪問固定的內存位置(Accessing fixed memorylocations) CC++ Development
60. 嵌入式系統常常具備要求程序員去訪問某特定的內存位置的特色。在某工程中,
要求設置一絕對地址爲0x67a9的整型變量的值爲0xaa66。編譯器是一個純粹的ANSI編譯器。寫代碼去完成這一任務。
這一問題測試你是否知道爲了訪問一絕對地址把一個整型數強制轉換(typecast)爲一指針是合法的。
這一問題的實現方式隨着我的風格不一樣而不一樣。典型的相似代碼以下:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa66;
61. 中斷是嵌入式系統中重要的組成部分,這致使了不少編譯開發商提供一種擴展—讓標準C支持中斷。
具表明事實是,產生了一個新的關鍵字__interrupt。下面的代碼就使用了__interrupt關鍵字去定義了一箇中斷服務子程序(ISR),
請評論一下這段代碼的。
__interrupt double compute_area (double radius)
{
double area = PI * radius* radius;
printf(" Area =%f", area);
return area;
}
這個函數有太多的錯誤了,以致讓人不知從何提及了:
1). ISR 不能返回一個值。若是你不懂這個,那麼你不會被僱用的。
2). ISR 不能傳遞參數。若是你沒有看到這一點,你被僱用的機會等同第一項。
3). 在許多的處理器/編譯器中,浮點通常都是不可重入的。有些處理器/編譯器須要讓額處的寄存器入棧,
有些處理器/編譯器就是不容許在ISR中作浮點運算。此外,ISR應該是短而有效率的,在ISR中作浮點運算是不明智的。
4). 與第三點一脈相承,printf()常常有重入和性能上的問題。
62 . 下面的代碼輸出是什麼,爲何?
Void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6)?puts("> 6") : puts("<= 6");
}
這個問題測試你是否懂得C語言中的整數自動轉換原則,我發現有些開發者懂得極少這些東西。無論如何,
這無符號整型問題的答案是輸出是「>6」。緣由是當表達式中存在有符號類型和無符號類型時全部的操做數都自動轉換爲無符號類型。
所以-20變成了一個很是大的正整數,因此該表達式計算出的結果大於6。
這一點對於應當頻繁用到無符號數據類型的嵌入式系統來講是豐常重要的。若是你答錯了這個問題,你也就到了得不到這份工做的邊緣。
63. 評價下面的代碼片段:
unsigned int zero = 0;
unsigned int compzero = 0XFFFF FFFF;
/*1's complement of zero */
對於一個int型不是16位的處理器爲說,上面的代碼是不正確的。應編寫以下:
unsigned int compzero = ~0;
這一問題真正能揭露出應試者是否懂得處理器字長的重要性。在個人經驗裏,好的嵌入式程序員很是準確地明白硬件的細節和它的侷限.