C語言面試題大彙總 java
一、局部變量可否和全局變量重名?
答:能,局部會屏蔽全局。要用全局變量,須要使用"::" ;局部變量能夠與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。對於有些編譯器而言,在同一個函數內能夠定義多個同名的局部變量,好比在兩個循環體內都定義一個同名的局部變量,而那個局部變量的做用域就在那個循環體內。
二、如何引用一個已經定義過的全局變量?
答: extern 能夠用引用頭文件的方式,也能夠用extern關鍵字,若是用引用頭文件方式來引用某個在頭文件中聲明的全局變理,假定你將那個編寫錯了,那麼在編譯期間會報錯,若是你用extern方式引用時,假定你犯了一樣的錯誤,那麼在編譯期間不會報錯,而在鏈接期間報錯。
三、全局變量可不能夠定義在可被多個.C文件包含的頭文件中?爲何?
答:能夠,在不一樣的C文件中以static形式來聲明同名全局變量。 能夠在不一樣的C文件中聲明同名的全局變量,前提是其中只能有一個C文件中對此變量賦初值,此時鏈接不會出錯.
四、請寫出下列代碼的輸出內容
#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
五、static全局變量與普通的全局變量有什麼區別?static局部變量和普通局部變量有什麼區別?static函數與普通函數有什麼區別?
答: 1) 全局變量(外部變量)的說明以前再冠以static 就構成了靜態的全局變量。全局變量自己就是靜態存儲方式,靜態全局變量固然也是靜態存儲方式。 這二者在存儲方式上並沒有不一樣。這二者的區別在於非靜態全局變量的做用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。 而靜態全局變量則限制了其做用域, 即只在定義該變量的源文件內有效,在同一源程序的其它源文件中不能使用它。因爲靜態全局變量的做用域侷限於一個源文件內,只能爲該源文件內的函數公用,所以能夠避免在其它源文件中引發錯誤。
2) 從以上分析能夠看出, 把局部變量改變爲靜態變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變爲靜態變量後是改變了它的做用域,限制了它的使用範圍。 3) static函數與普通函數做用域不一樣,僅在本文件。只在當前源文件中使用的函數應該說明爲內部函數(static),內部函數應該在當前源文件中說明和定義。對於可在當前源文件之外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件
綜上所述:
static全局變量與普通的全局變量有什麼區別:
static全局變量只初使化一次,防止在其餘文件單元中被引用;
static局部變量和普通局部變量有什麼區別:
static局部變量只被初始化一次,下一次依據上一次結果值;
static函數與普通函數有什麼區別:
static函數在內存中只有一份,普通函數在每一個被調用中維持一份拷貝
六、程序的局部變量存在於(堆棧)中,全局變量存在於(靜態區 )中,動態申請數據存在於( 堆)中。
七、設有如下說明和定義:
typedef union
{
long i;
int k[5];
char c;
} DATE;
struct data
{
int cat;
DATE cow;
double dog;
} too;
DATE max;
則語句 printf("%d",sizeof(struct data)+sizeof(max));的執行結果是:___52____
考點:區別struct與union.(通常假定在32位機器上)
答: DATE是一個union, 變量公用空間. 裏面最大的變量類型是int[5], 佔用20個字節. 因此它的大小是20. data是一個struct, 每一個變量分開佔用空間. 依次爲int4 + DATE20 + double8 = 32. 因此結果是 20 + 32 = 52. 固然...在某些16位編輯器下, int多是2字節,那麼結果是 int2 + DATE10 + double8 = 20
八、隊列和棧有什麼區別?
隊列先進先出,棧後進先出
九、寫出下列代碼的輸出內容
#include <stdio.h>
int inc(int a)
{ return(++a); }
int multi(int*a,int*b,int*c)
{ return(*c=*a**b); }
typedef int(FUNC1)(int in);
typedef int(FUNC2) (int*,int*,int*);
void show(FUNC2 fun,int arg1, int*arg2)
{
FUNC1 p=&inc;
int temp =p(arg1);
fun(&temp,&arg1, arg2);
printf("%dn",*arg2);
}
main()
{
int a; //局部變量a爲0;
show(multi,10,&a);
return 0;
}
答:110
十、請找出下面代碼中的全部錯誤 (題目不錯,值得一看)
說明:如下代碼是把一個字符串倒序,如「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()
{
char str[]="hello,world";
int len=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;
}
11.對於一個頻繁使用的短小函數,在C語言中應用什麼實現,在C++中應用什麼實現?
c用宏定義,c++用inline
12.直接連接兩個信令點的一組鏈路稱做什麼?
PPP點到點鏈接
13.接入網用的是什麼接口?
V5接口
14.voip都用了那些協議?
H.323協議簇、SIP協議、Skype協議、H.248和MGCP協議
15.軟件測試都有那些種類?
黑盒:針對系統功能的測試
白盒:測試函數功能,各函數接口
16.肯定模塊的功能和模塊的接口是在軟件設計的那個隊段完成的?
概要設計階段
17.
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
請問p1+5= ;
p2+5= ;
答案:0x801005(至關於加上5位) 0x810014(至關於加上20位);
選擇題:
21.Ethternet連接到Internet用到如下那個協議? D
A.HDLC;B.ARP;C.UDP;D.TCP;E.ID
22.屬於網絡層協議的是:( B C)
A.TCP;B.IP;C.ICMP;D.X.25
23.Windows消息調度機制是:(C)
A.指令隊列;B.指令堆棧;C.消息隊列;D.消息堆棧;
找錯題:
25.請問下面程序有什麼錯誤?
int a[60][250][1000],i,j,k;
for(k=0;kMax_GT_Length)
{ return GT_Length_ERROR;
} ....... }
答: 死循環//
問答題:
29.IP Phone的原理是什麼?
IP 電話(又稱IP PHONE或VoIP)是創建在IP技術上的分組化、數字化傳輸技術,其基本原理是:經過語音壓縮算法對語音數據進行壓縮編碼處理,而後把這些語音數據按 IP等相關協議進行打包,通過IP網絡把數據包傳輸到接收地,再把這些語音數據包串起來,通過解碼解壓處理後,恢復成原來的語音信號,從而達到由IP網絡傳送語音的目的。
30.TCP/IP通訊創建的過程怎樣,端口有什麼做用?
三次握手,肯定是哪一個應用程序使用該協議
31.1號信令和7號信令有什麼區別,我國某前普遍使用的是那一種?
1號信令接續慢,可是穩定,可靠。
7號信令的特色是:信令速度快,具備提供大量信令的潛力,具備改變和增長信令的靈活性,便於開放新業務,在通話時能夠隨意處理信令,成本低。目前獲得普遍應用。
32.列舉5種以上的電話新業務
如「鬧鐘服務」、「免干擾服務」、「熱線服務」、「轉移呼叫」、「遇忙回叫」、「缺席用戶服務」、「追查惡意呼叫」、「三方通話」、「會議電話」、「呼出限制」、「來電顯示」、「虛擬網電話」等
四.找錯題:
1.請問下面程序有什麼錯誤?
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;
答: 把循環語句內外換一下
2.#define Max_CB 500
void LmiQueryCSmd(Struct MSgCB * pmsg)
{
unsigned char ucCmdNum;
......
for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)
{
......;
}
答: 死循環,unsigned int的取值範圍是0~255
3.如下是求一個數的平方的程序,請找出錯誤:
#define SQUARE(a)((a)*(a))
int a=5;
int b;
b=SQUARE(a++);
答:結果與編譯器相關,獲得的可能不是平方值.
微軟亞洲技術中心的面試題!!!
1.進程和線程的差異。
答:線程是指進程內的一個執行單元,也是進程內的可調度實體.
與進程的區別:
(1)調度:線程做爲調度和分配的基本單位,進程做爲擁有資源的基本單位
(2)併發性:不只進程之間能夠併發執行,同一個進程的多個線程之間也可併發執行
(3)擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但能夠訪問隸屬於進程的資源.
(4)系統開銷:在建立或撤消進程時,因爲系統都要爲之分配和回收資源,致使系統的開銷明顯大於建立或撤消線程時的開銷。
2.測試方法
答:人工測試:我的複查、抽查和會審
機器測試:黑盒測試和白盒測試
3.Heap與stack的差異。
答:Heap是堆,stack是棧。
Stack的空間由操做系統自動分配/釋放,Heap上的空間手動分配/釋放。
Stack空間有限,Heap是很大的自由存儲區
C中的malloc函數分配的內存空間即在堆上,C++中對應的是new操做符。
程序在編譯期對變量和函數分配內存都在棧上進行,且程序運行過程當中函數調用時參數的傳遞也在棧上進行
4.Windows下的內存是如何管理的?
分頁管理
8.談談IA32下的分頁機制
小頁(4K)兩級分頁模式,大頁(4M)一級
9.給兩個變量,如何找出一個帶環單鏈表中是什麼地方出現環的?
一個遞增一,一個遞增二,他們指向同一個接點時就是環出現的地方
10.在IA32中一共有多少種辦法從用戶態跳到內核態?
經過調用門,從ring3到ring0,中斷從ring3到ring0,進入vm86等等
11.若是隻想讓程序有一個實例運行,不能運行兩個。像winamp同樣,只能開一個窗口,怎樣實現?
用內存映射或全局原子(互斥變量)、查找窗口句柄..
FindWindow,互斥,寫標誌到文件或註冊表,共享內存。.
12.如何截取鍵盤的響應,讓全部的'a’變成'b’?
答:鍵盤鉤子SetWindowsHookEx
14.存儲過程是什麼?有什麼用?有什麼優勢?
答:個人理解就是一堆sql的集合,能夠創建很是複雜的查詢,編譯運行,因此運行一次後,之後再運行速度比單獨執行SQL快不少
15.Template有什麼特色?何時用?
答: Template能夠獨立於任何特定的類型編寫代碼,是泛型編程的基礎.
當咱們編寫的類和函數可以多態的用於跨越編譯時不相關的類型時,用Template.
模板主要用於STL中的容器,算法,迭代器等以及模板元編程.
(C++的template是實如今庫設計和嵌入式設計中的關鍵。
template能實現抽象和效率的結合;同時template還能有效地防止代碼膨脹)
template能實現抽象和效率的結合;同時template還能有效地防止代碼膨脹)
16.談談Windows DNA結構的特色和優勢。
答:Windows Distributed interNet Application Architecture(Windows分佈式應用結構,簡稱Windows DNA)是微軟建立新一代高適應性商業解決方案的框架,它使公司可以充分地挖掘數字神經系統的優勢。Windows DNA是第一個將Internet、客戶/服務器、和用於計算的PC模型結合並集成在一塊兒的爲新一類分佈式計算方案而設計的應用軟件體系結構
17. 網絡編程中設計併發服務器,使用多進程與多線程,請問有什麼區別?
答:1)進程:子進程是父進程的複製品。子進程得到父進程數據空間、堆和棧的複製品。
2)線程:相對與進程而言,線程是一個更加接近與執行體的概念,它能夠與同進程的其餘線程共享數據,但擁有本身的棧空間,擁有獨立的執行序列。
二者均可以提升程序的併發度,提升程序運行效率和響應時間。
線程和進程在使用上各有優缺點:線程執行開銷小,但不利於資源管理和保護;而進程正相反。同時,線程適合於在SMP機器上運行,而進程則能夠跨機器遷移。
思科
1. 用宏定義寫出swap(x,y)
答#define swap(x, y)
x = x + y;
y = x - y;
x = x - y;
2.數組a[N],存放了1至N-1個數,其中某個數重複一次。寫一個函數,找出被重複的數字.時間複雜度必須爲o(N)函數原型:
int do_dup(int a[],int N)
答:int do_dup(int a[],int N) //未經調試
{
int sun = 0;
int sum2;
for(int i=0;i<N;++i)
{
Sum+=a[i];
}
Sum2 = (1+N-1)*N/2;
Return (sum-sum2);
}
3 一語句實現x是否爲2的若干次冪的判斷
答:方法1)int i = 512;
cout << boolalpha << ((i & (i - 1)) ? false : true) << endl; //位與爲0,則表示是2的若干次冪
2)return (x>>N==1);
4.unsigned int intvert(unsigned int x,int p,int n)實現對x的進行轉換,p爲起始轉化位,n爲須要轉換的長度,假設起始點在右邊.如x=0b0001 0001,p=4,n=3轉換後x=0b0110 0001
答:unsigned int intvert(unsigned int x,int p,int n) //假定p=4,n=3
{
unsigned int _t = 0;
unsigned int _a = 1;
for(int i = 0; i < n; ++i)//循環的目的主要是-t
{
_t |= _a; //位或
_a = _a << 1;
}
_t = _t << p; //轉換後_t變爲1110000
x ^= _t; /異或,將原來的位取反
return x;
}
慧通:
1. 什麼是預編譯,什麼時候須要預編譯:
答: 就是指程序執行前的一些預處理工做,主要指#表示的.
什麼時候須要預編譯?
1)、老是使用不常常改動的大型代碼體。
2)、程序由多個模塊組成,全部模塊都使用一組標準的包含文件和相同的編譯選項。在這種狀況下,能夠將全部包含文件預編譯爲一個預編譯頭。
2. 下述三個有什麼區別?
char * const p;
char const * p
const char *p
解答:
char * const p; //常量指針,p的值不能夠修改
char const * p;//指向常量的指針,指向的常量值不能夠改
const char *p; //和char const *p
3. 解釋下列輸出結果
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是指針,它們指向相同的常量區域。
4. 如下代碼中的兩個sizeof用法有問題嗎?[C易]
void UpperCase( char str[] ) // 將 str 中的小寫字母轉換成大寫字母
{
for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )
if( 'a'<=str[i] && str[i]<='z' )
str[i] -= ('a'-'A' );
}
char str[] = "aBcDe";
cout << "str字符長度爲: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;
答:函數內的sizeof有問題。根據語法,sizeof如用於數組,只能測出靜態數組的大小,沒法檢測動態分配的或外部數組大小。函數外的str是一個靜態定義的數組,所以其大小爲6,函數內的str實際只是一個指向字符串的指針,沒有任何額外的與數組相關的信息,所以sizeof做用於上只將其當指針看,一個指針爲4個字節,所以返回4。
注意:數組名做爲函數參數時,退化爲指針.
數組名做爲sizeof()參數時,數組名不退化,由於sizeof不是函數.
4. 一個32位的機器,該機器的指針是多少位
指針是多少位只要看地址總線的位數就好了。80386之後的機子都是32的數據總線。因此指針的位數就是4個字節了。
5. 指出下面代碼的輸出,並解釋爲何。(不錯,對地址掌握的深刻挖潛)
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
輸出:2,5
*(a+1)就是a[1],*(ptr-1)就是a[4],執行結果是2,5
&a+1不是首地址+1,系統會認爲加一個a數組的偏移,是偏移了一個數組的大小(本例是5個int)
int *ptr=(int *)(&a+1);
則ptr實際是&(a[5]),也就是a+5
緣由以下:
&a是數組指針,其類型爲 int (*)[5];
而指針加1要根據指針類型加上必定的值,
不一樣類型的指針+1以後增長的大小不一樣
a是長度爲5的int數組指針,因此要加 5*sizeof(int)
因此ptr實際是a[5]
可是prt與(&a+1)類型是不同的(這點很重要)
因此prt-1只會減去sizeof(int*)
a,&a的地址是同樣的,但意思不同,a是數組首地址,也就是a[0]的地址,&a是對象(數組)首地址,a+1是數組下一元素的地址,即a[1],&a+1是下一個對象的地址,即a[5].
6.請問如下代碼有什麼問題:
1).
int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}
答;沒有爲str分配內存空間,將會發生異常
問題出在將一個字符串複製進一個字符變量指針所指地址。雖然能夠正確輸出結果,但由於越界進行內在讀寫而致使程序崩潰。
Strcpy的在庫函數string.h中.程序的主要錯誤在於越界進行內存讀寫致使程序崩潰//
2).
char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
有什麼錯?
答: "AAA"是字符串常量。s是指針,指向這個字符串常量,因此聲明s的時候就有問題。
cosnt char* s="AAA";
而後又由於是常量,因此對是s[0]的賦值操做是不合法的。
一、寫一個「標準」宏,這個宏輸入兩個參數並返回較小的一個。
答:#define Min(X, Y) ((X)>(Y)?(Y):(X)) //結尾沒有;
二、嵌入式系統中常常要用到無限循環,你怎麼用C編寫死循環。
答:while(1){}或者for(;;) //前面那個較好
三、關鍵字static的做用是什麼?
答:1)定義靜態局部變量,做用域從函數開始到結束.
2) 在模塊內的static函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明它的模塊內;
3) 在類中的static成員變量屬於整個類所擁有,對類的全部對象只有一份拷貝
四、關鍵字const有什麼含意?
答 :1)表示常量不能夠修改的變量。
2)能夠修飾參數,做爲輸入參數.
3)修飾函數,防止之外的改動.
4)修飾類的成員函數,不改變類中的數據成員.
五、關鍵字volatile有什麼含意?並舉出三個不一樣的例子?
答: 提示編譯器對象的值可能在編譯器未監測到的狀況下改變。
例子: 硬件時鐘;多線程中被多個任務共享的變量等
6. int (*s[10])(int) 表示的是什麼啊
int (*s[10])(int) 函數指針數組,每一個指針指向一個int func(int param)的函數。
1.有如下表達式:
int a=248; b=4;int const c=21;const int *d=&a;
int *const e=&b;int const *f const =&a;
請問下列表達式哪些會被編譯器禁止?爲何?
答:*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;
*c 這是個什麼東東,禁止
*d 說了是const, 禁止
e = &a 說了是const 禁止
const *f const =&a; 禁止
2.交換兩個變量的值,不使用第三個變量。即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;
or
a ^= b ^= a;
3.c和c++中的struct有什麼不一樣?
答: c和c++中struct的主要區別是c中的struct不能夠含有成員函數,而c++中的struct能夠。c++中struct和class的主要區別在於默認的存取權限不一樣,struct默認爲public,而class默認爲private.
4.#include <stdio.h>
#include <stdlib.h>
void getmemory(char *p)
{
p=(char *) malloc(100);
}
int main( )
{
char *str=NULL;
getmemory(str);
strcpy(p,"hello world");
printf("%s/n",str);
free(str);
return 0;
}
答: 程序崩潰,getmemory中的malloc 不能返回動態內存, free()對str操做很危險
5.char szstr[10];
strcpy(szstr,"0123456789");
產生什麼結果?爲何?
答;正常輸出,長度不同,會形成非法的OS,覆蓋別的內容.
6.列舉幾種進程的同步機制,並比較其優缺點。
答:原子操做
信號量機制
自旋鎖
管程,會合,分佈式系統
7.進程之間通訊的途徑
答 共享存儲系統
消息傳遞系統
管道:以文件系統爲基礎
面試經典試題
silver6 | 02 一月, 2007 11:41
面試經典試題
Author:Vince
————即便你是個編程高手,你在面試前也應該要看看這套題,她也許會給你帶來好運,不然你有可能後悔當初爲何沒有看而跳樓自殺,這樣我會很內疚的。這套題看似簡單,但你未必能得高分,即便你看不懂也要把她背下來!
歡迎轉載此文,轉載時請註明文章來源:文斯測試技術研究中心
http://blog.csdn.net/vincetest
1. const的理解:const char*, char const*, char*const的區別問題幾乎是C++面試中每次 都會有的題目。事實上這個概念誰都有隻是三種聲明方式很是類似很容易記混。 Bjarne在他的The C++ Programming Language裏面給出過一個助記的方法: 把一個聲明從右向左讀。
char * const cp; ( * 讀成 pointer to )
cp is a const pointer to char
const char * p;
p is a pointer to const char;
char const * p;
同上由於C++裏面沒有const*的運算符,因此const只能屬於前面的類型。
2. c指針
int *p[n];-----指針數組,每一個元素均爲指向整型數據的指針。
int (*p)[n];------p爲指向一維數組的指針,這個一維數組有n個整型數據。
int *p();----------函數帶回指針,指針指向返回的值。
int (*p)();------p爲指向函數的指針。
3. 數組越界問題 (這個題目仍是有點小險的)
下面這個程序執行後會有什麼錯誤或者效果:
#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]
4. 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'就結束拷貝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串長度(第一個'/0'以前)是否超過50位,如超過,則會形成b的內存地址溢出。
strcpy
原型:extern char *strcpy(char *dest,char *src);
{
ASSERT((dest!=NULL)&&(src!=NULL));
Char *address = dest;
While((*dest++=*src++)!=’/0’)
Continue;
Return dest;
}
用法:#include <string.h>
功能:把src所指由NULL結束的字符串複製到dest所指的數組中。
說明:src和dest所指內存區域不能夠重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest的指針。
memcpy
原型:extern void *memcpy(void *dest, void *src, unsigned int count);
{
ASSERT((dest!=NULL)&&(src!=NULL));
ASSERT((dest>src+count)||(src>dest+count));//防止內存重疊,也能夠用restrict修飾指針
Byte* bdest = (Byte*)dest;
Byte* bsrc = (Byte*) src;
While(count-->0)
*bdest++ = **bsrc++;
Return dest;
}
用法:#include <memory.h>
功能:由src所指內存區域複製count個字節到dest所指內存區域。
說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。
Memset
原型:extern void *memset(void *buffer, char c, int count);
用法:#include
功能:把buffer所指內存區域的前count個字節設置成字符c。
說明:返回指向buffer的指針。
5. ASSERT()是幹什麼用的
答:ASSERT()是一個調試程序時常用的宏,在程序運行時它計算括號內的表達式,若是表達式爲FALSE (0), 程序將報告錯誤,並終止執行。若是表達式不爲0,則繼續執行後面的語句。這個宏一般原來判斷程序中是否出現了明顯非法的數據,若是出現了終止程序以避免致使嚴重後果,同時也便於查找錯誤。例如,變量n在程序中不該該爲0,若是爲0可能致使錯誤,你能夠這樣寫程序:
......
ASSERT( n != 0);
k = 10/ n;
......
ASSERT只有在Debug版本中才有效,若是編譯爲Release版本則被忽略。
assert()的功能相似,它是ANSI C標準中規定的函數,它與ASSERT的一個重要區別是能夠用在Release版本中。
6. system("pause");做用?
答:系統的暫停程序,按任意鍵繼續,屏幕會打印,"按任意鍵繼續。。。。。" 省去了使用getchar();
7. 請問C++的類和C裏面的struct有什麼區別?
答:c++中的類具備成員保護功能,而且具備繼承,多態這類oo特色,而c裏的struct沒有
c裏面的struct沒有成員函數,不能繼承,派生等等.
8. 請講一講析構函數和虛函數的用法和做用?
答: 析構函數也是特殊的類成員函數,它沒有返回類型,沒有參數,不能隨意調用,也沒有重載。只是在類對象生命期結束的時候,由系統自動調用釋放在構造函數中分配的資源。這種在運行時,能依據其類型確認調用那個函數的能力稱爲多態性,或稱遲後聯編。另: 析構函數通常在對象撤消前作收尾工做,好比回收內存等工做,
虛擬函數的功能是使子類能夠用同名的函數對父類函數進行覆蓋,而且在調用時自動調用子類覆蓋函數,若是是純虛函數,則純粹是爲了在子類覆蓋時有個統一的命名而已。
注意:子類從新定義父類的虛函數的作法叫覆蓋,override,而不是overload(重載),重載的概念不屬於面向對象編程,重載指的是存在多個同名函數,這些函數的參數表不一樣..重載是在編譯期間就決定了的,是靜態的,所以,重載與多態無關.與面向對象編程無關.
含有純虛函數的類稱爲抽象類,不能實例化對象,主要用做接口類//
9. 全局變量和局部變量有什麼區別?是怎麼實現的?操做系統和編譯器是怎麼知道的?
答;全局變量的生命週期是整個程序運行的時間,而局部變量的生命週期則是局部函數或過程調用的時間段。其實現是由編譯器在編譯時採用不一樣內存分配方法。
全局變量在main函數調用後,就開始分配,
靜態變量則是在main函數前就已經初始化了。
局部變量則是在用戶棧中動態分配的(仍是建議看編譯原理中的活動記錄這一塊)
10. 8086是多少位的系統?在數據總線上是怎麼實現的?
答:8086系統是16位系統,其數據總線是20位。
1. 編寫用C語言實現的求n階階乘問題的遞歸算法:
答:long int fact(int n)
{
{
If(n==0||n==1)
Return 1;
Else
Return n*fact(n-1);
}
2. 二分查找算法:
1) 遞歸方法實現:
int BSearch(elemtype a[],elemtype x,int low,int high)
/*在下屆爲low,上界爲high的數組a中折半查找數據元素x*/
{
int mid;
if(low>high) return -1;
mid=(low+high)/2;
if(x==a[mid]) return mid;
if(x<a[mid]) return(BSearch(a,x,low,mid-1));
else return(BSearch(a,x,mid+1,high));
}
2) 非遞歸方法實現:
int BSearch(elemtype a[],keytype key,int n)
{
int low,high,mid;
low=0;high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid].key==key) return mid;
else if(a[mid].key<key) low=mid+1;
else high=mid-1;
}
return -1;
}
3. 遞歸計算以下遞歸函數的值(斐波拉契):
f(1)=1
f(2)=1
f(n)=f(n-1)+f(n-2) n>2
解:非遞歸算法:
int f(int n)
{
int i,s,s1,s2;
s1=1;/*s1用於保存f(n-1)的值*/
s2=1;/*s2用於保存f(n-2)的值*/
s=1;
for(i=3;i<=n;i++)
{
s=s1+s2;
s2=s1;
s1=s;
}
return(s);
}
遞歸算法:
Int f(int n)
{
If(n==1||n==2)
Rerurn 1;
Else
Rerutn f(n-1)+f(n-2);
}
4. 交換兩個數,不用第三塊兒內存:
答:int a = ……;
int b = ……;
a = a + b;
b = a - b;
a = a - b;
5. 冒泡排序:
答:void BubbleSort(elemtype x[],int n) //時間複雜度爲0(n*n);
{
int i,j;
elemtype temp;
for(i=1;i<n;i++)
for(j=0;j<n-i;j++)
{
if(x[j].key>x[j+1].key)
{
temp=x[j];
x[j]=x[j+1];
x[j+1]=temp;
}
}
}
//補充一個改進的冒泡算法:
void BubbleSort(elemtype x[],int n)
{
Int i,j;
BOOL exchange; //記錄交換標誌
for(i=1;i<n;++i) //最多作n-1趟排序
{
Exchange = false;
For(j=n-1;j>=i;--j)
{
If(x[j]>x[j+1])
{
x[0] = x[j];
X[j] = x[j+1];
X[j+1] = x[0];
Exchange = true; //發生了交換,設置標誌爲真.
}
}
if (!Exchange ) //爲發生替換,提早終止算法
return;
}
}
6. c語言 文件讀寫
#include "stdio.h"
main()
{
FILE *fp;
char ch,filename[10];
scanf("%s",filename);
if((fp=fopen(filename,"w")==NULL)
{
printf("cann't open filen");
exit(0);
}
ch=getchar();
while(ch!='#')
{
fputc(ch,fp);
putchar(ch);
ch=getchar();
}
fclose(fp);
}
7. winsocket編程 //這個不錯
// 服務器代碼
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORD wVersionRequested; //版本號
WSADATA wsaData; //數據
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup(wVersionRequested,&wsaData);
if( err != 0)
{
return;
}
if(LOBYTE( wsaData.wVersion ) != 1||
HIBYTE( wsaData.wVersion) != 1)
{
WSACleanup();
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); //創建套接字
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); //綁定端口
listen(sockSrv,5); //轉換socket套接子爲偵聽套接子
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1) //無限循環
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprint(sendBuf,"Welcome %s to
http://www.sunxin.org",
inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf);
printf("%sn",recvBuf);
closesocket(sockConn);
WSACleanup();
}
}
注:這是Server端;File->New->Win32 Console Application,工程名:TcpSrv;而後,File->New->C++ Source File,文件名:TcpSrv;在該工程的Setting的Link的Object/library modules項要加入ws2_32.lib
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup(wVersionRequested,&wsaData); //啓動winsock Dll
if( err != 0)
{
return;
}
if(LOBYTE( wsaData.wVersion ) != 1||
HIBYTE( wsaData.wVersion) != 1)
{
WSACleanup();
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port = htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%sn",recvBuf);
send(sockClient,"This is zhangsan",strlen("This is zhangsan")+1,0);
closesocket(sockClient);
WSACleanup();
}
注:這是Client端;File->New->Win32 Console Application,工程名:TcpClient;而後,File->New->C++ Source File,文件名:TcpClient;同理,在該工程的Setting的Link的Object/library modules項要加入ws2_32.lib
8. 類的知識 (很是不錯的一道題目)..
C++
#include <iostream.h>
class human
{
public:
human(){ human_num++;}; //默認構造函數
static int human_num; //靜態成員
~human()
{
human_num--;
print();
}
void print() //
{
cout<<"human num is: "<<human_num<<endl;
}
protected:
private:
};
int human::human_num = 0; //類中靜態數據成員在外部定義,僅定義一次
human f1(human x)
{
x.print();
return x;
}
int main(int argc, char* argv[])
{
human h1; //調用默認構造函數,human_num變爲1
h1.print(); // 打印Human_man:1
human h2 = f1(h1); //先調用函數f1(),輸出human_num:1,然後輸出human_num爲0,
h2.print();//打印輸出:human_num:0
return 0;
} //依次調用兩個析構函數:輸出:human_num:-1,human_num:-2;
輸出:
1
1
0
0
-1
-2
----------------------------
分析:
human h1; //調用構造函數,---hum_num = 1;
h1.print(); //輸出:"human is 1"
human h2 = f1(h1); //再調用f1(h1)的過程當中,因爲函數參數是按值傳遞對象,調用默認的複製構造函數
,h2並無調用定義的構造函數.
C/C++ 程序設計員應聘常見面試試題深刻剖析
silver6 | 25 九月, 2006 09:07
本文的寫做目的並不在於提供C/C++程序員求職面試指導,而旨在從技術上分析面試題的內涵。文中的大多數面試題來自各大論壇,部分試題解答也參考了網友的意見。
許多面試題看似簡單,卻須要深厚的基本功才能給出完美的解答。企業要求面試者寫一個最簡單的strcpy函數均可看出面試者在技術上究竟達到了怎樣的程度,咱們能真正寫好一個strcpy函數嗎?咱們都以爲本身能,但是咱們寫出的strcpy極可能只能拿到10分中的2分。讀者可從本文看到strcpy 函數從2分到10分解答的例子,看看本身屬於什麼樣的層次。此外,還有一些面試題考查面試者敏捷的思惟能力。
分析這些面試題,自己包含很強的趣味性;而做爲一名研發人員,經過對這些面試題的深刻剖析則可進一步加強自身的內功。
2.找錯題
試題1:
許多面試題看似簡單,卻須要深厚的基本功才能給出完美的解答。企業要求面試者寫一個最簡單的strcpy函數均可看出面試者在技術上究竟達到了怎樣的程度,咱們能真正寫好一個strcpy函數嗎?咱們都以爲本身能,但是咱們寫出的strcpy極可能只能拿到10分中的2分。讀者可從本文看到strcpy 函數從2分到10分解答的例子,看看本身屬於什麼樣的層次。此外,還有一些面試題考查面試者敏捷的思惟能力。
分析這些面試題,自己包含很強的趣味性;而做爲一名研發人員,經過對這些面試題的深刻剖析則可進一步加強自身的內功。
2.找錯題
試題1:
void test1() { char string[10]; char* str1 = "0123456789"; strcpy( string, str1 ); } |
試題2:
void test2() { char string[10], str1[10]; int i; for(i=0; i<10; i++) { str1[i] = 'a'; } strcpy( string, str1 ); } |
試題3:
void test3(char* str1) { char string[10]; if( strlen( str1 ) <= 10 ) { strcpy( string, str1 ); } } |
解答:
試題1字符串str1須要11個字節才能存放下(包括末尾的’’),而string只有10個字節的空間,strcpy會致使數組越界;
對試題2,若是面試者指出字符數組str1不能在數組內結束能夠給3分;若是面試者指出strcpy(string, str1)調用使得從str1內存起復制到string內存起所複製的字節數具備不肯定性能夠給7分,在此基礎上指出庫函數strcpy工做方式的給10 分;
對試題3,if(strlen(str1) <= 10)應改成if(strlen(str1) < 10),由於strlen的結果未統計’’所佔用的1個字節。
剖析:
考查對基本功的掌握:
(1)字符串以’/0’結尾;
(2)對數組越界把握的敏感度;
(3)庫函數strcpy的工做方式,若是編寫一個標準strcpy函數的總分值爲10,下面給出幾個不一樣得分的答案:
2分
void strcpy( char *strDest, char *strSrc ) { while( (*strDest++ = * strSrc++) != '’ ); } |
4分
void strcpy( char *strDest, const char *strSrc ) //將源字符串加const,代表其爲輸入參數,加2分 { while( (*strDest++ = * strSrc++) != '’ ); } |
7分
void strcpy(char *strDest, const char *strSrc) { //對源地址和目的地址加非0斷言,加3分 assert( (strDest != NULL) && (strSrc != NULL) ); while( (*strDest++ = * strSrc++) != '’ ); } |
10分
//爲了實現鏈式操做,將目的地址返回,加3分! char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) && (strSrc != NULL) ); char *address = strDest; while( (*strDest++ = * strSrc++) != '’ ); return address; } |
從2分到10分的幾個答案咱們能夠清楚的看到,小小的strcpy居然暗藏着這麼多玄機,真不是蓋的!須要多麼紮實的基本功才能寫一個完美的strcpy啊!
(4)對strlen的掌握,它沒有包括字符串末尾的''。
讀者看了不一樣分值的strcpy版本,應該也能夠寫出一個10分的strlen函數了,完美的版本爲: int strlen( const char *str ) //輸入參數const
{ assert( strt != NULL ); //斷言字符串地址非0 int len; while( (*str++) != '' ) { len++; } return len; } |
試題4:
void GetMemory( char *p ) { p = (char *) malloc( 100 ); } void Test( void ) { char *str = NULL; GetMemory( str ); strcpy( str, "hello world" ); printf( str ); } |
試題5:
char *GetMemory( void ) { char p[] = "hello world"; return p; } void Test( void ) { char *str = NULL; str = GetMemory(); printf( str ); } |
試題6:
void GetMemory( char **p, int num ) { *p = (char *) malloc( num ); } void Test( void ) { char *str = NULL; GetMemory( &str, 100 ); strcpy( str, "hello" ); printf( str ); } |
試題7:
void Test( void ) { char *str = (char *) malloc( 100 ); strcpy( str, "hello" ); free( str ); ... //省略的其它語句 } |
解答:
試題4傳入中GetMemory( char *p )函數的形參爲字符串指針,在函數內部修改形參並不能真正的改變傳入形參的值,執行完
char *str = NULL; GetMemory( str ); |
後的str仍然爲NULL;
試題5中
char p[] = "hello world"; return p; |
的p[]數組爲函數內的局部自動變量,在函數返回後,內存已經被釋放。這是許多程序員常犯的錯誤,其根源在於不理解變量的生存期。
試題6的GetMemory避免了試題4的問題,傳入GetMemory的參數爲字符串指針的指針,可是在GetMemory中執行申請內存及賦值語句
*p = (char *) malloc( num ); |
後未判斷內存是否申請成功,應加上:
if ( *p == NULL ) { ...//進行申請內存失敗處理 } |
試題7存在與試題6一樣的問題,在執行
char *str = (char *) malloc(100); |
後未進行內存是否申請成功的判斷;另外,在free(str)後未置str爲空,致使可能變成一個「野」指針,應加上:
str = NULL; |
試題6的Test函數中也未對malloc的內存進行釋放。
剖析:
試題4~7考查面試者對內存操做的理解程度,基本功紮實的面試者通常都能正確的回答其中50~60的錯誤。可是要徹底解答正確,卻也絕非易事。
對內存操做的考查主要集中在:
(1)指針的理解;
(2)變量的生存期及做用範圍;
(3)良好的動態內存申請和釋放習慣。
再看看下面的一段程序有什麼錯誤:
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; } |
3.內功題
試題1:分別給出BOOL,int,float,指針變量 與「零值」比較的 if 語句(假設變量名爲var)
解答:
BOOL型變量:if(!var)
int型變量: if(var==0)
float型變量:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
指針變量: if(var==NULL)
剖析:
考查對0值判斷的「內功」,BOOL型變量的0判斷徹底能夠寫成if(var==0),而int型變量也能夠寫成if(!var),指針變量的判斷也能夠寫成if(!var),上述寫法雖然程序都能正確運行,可是未能清晰地表達程序的意思。
通常的,若是想讓if判斷一個變量的「真」、「假」,應直接使用if(var)、if(!var),代表其爲「邏輯」判斷;若是用if判斷一個數值型變量(short、int、long等),應該用if(var==0),代表是與0進行「數值」上的比較;而判斷指針則適宜用if(var==NULL),這是一種很好的編程習慣。
浮點型變量並不精確,因此不可將float變量用「==」或「!=」與數字比較,應該設法轉化成「>=」或「<=」形式。若是寫成if (x == 0.0),則判爲錯,得0分。
試題2:如下爲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。
試題3:寫一個「標準」宏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 ) |
都應判0分;
(2)防止宏的反作用。
宏定義#define MIN(A,B) ((A) <= (B) ? (A) : (B))對MIN(*p++, b)的做用結果是:
((*p++) <= (b) ? (*p++) : (*p++))
這個表達式會產生反作用,指針p會做三次++自增操做。
除此以外,另外一個應該判0分的解答是:
#define MIN(A,B) ((A) <= (B) ? (A) : (B)); |
這個解答在宏定義的後面加「;」,顯示編寫者對宏的概念模糊不清,只能被無情地判0分並被面試官淘汰。
試題4:爲何標準頭文件都有相似如下的結構?
#ifndef __INCvxWorksh #define __INCvxWorksh #ifdef __cplusplus extern "C" { #endif /*...*/ #ifdef __cplusplus } #endif #endif /* __INCvxWorksh */ |
解答:
頭文件中的編譯宏
#ifndef __INCvxWorksh #define __INCvxWorksh #endif |
的做用是防止被重複引用。
做爲一種面向對象的語言,C++支持函數重載,而過程式語言C則不支持。函數被C++編譯後在symbol庫中的名字與C語言的不一樣。例如,假設某個函數的原型爲:
void foo(int x, int y); |
該函數被C編譯器編譯後在symbol庫中的名字爲_foo,而C++編譯器則會產生像_foo_int_int之類的名字。_foo_int_int這樣的名字包含了函數名和函數參數數量及類型信息,C++就是考這種機制來實現函數重載的。
爲了實現C和C++的混合編程,C++提供了C鏈接交換指定符號extern "C"來解決名字匹配問題,函數聲明前加上extern "C"後,則編譯器就會按照C語言的方式將該函數編譯爲_foo,這樣C語言中就能夠調用C++的函數了。
試題5:編寫一個函數,做用是把一個char組成的字符串循環右移n個。好比原來是「abcdefghi」若是n=2,移位後應該是「hiabcdefgh」
函數頭是這樣的:
函數頭是這樣的:
//pStr是指向以''結尾的字符串的指針 //steps是要求移動的n void LoopMove ( char * pStr, int steps ) { //請填充... } |
解答:
正確解答1:
void LoopMove ( char *pStr, int steps ) { int n = strlen( pStr ) - steps; char tmp[MAX_LEN]; strcpy ( tmp, pStr + n ); strcpy ( tmp + steps, pStr); *( tmp + strlen ( pStr ) ) = ''; strcpy( pStr, tmp ); } |
正確解答2:
void LoopMove ( char *pStr, int steps ) { int n = strlen( pStr ) - steps; char tmp[MAX_LEN]; memcpy( tmp, pStr + n, steps ); memcpy(pStr + steps, pStr, n ); memcpy(pStr, tmp, steps ); } |
剖析:
這個試題主要考查面試者對標準庫函數的熟練程度,在須要的時候引用庫函數能夠很大程度上簡化程序編寫的工做量。
最頻繁被使用的庫函數包括:
(1) strcpy
(2) memcpy
(3) memset
試題6:已知WAV文件格式以下表,打開一個WAV文件,以適當的數據結構組織WAV文件頭並解析WAV格式的各項信息。
WAVE文件格式說明表
偏移地址 | 字節數 | 數據類型 | 內 容 | |
文件頭
|
00H | 4 | Char | "RIFF"標誌 |
04H | 4 | int32 | 文件長度 | |
08H | 4 | Char | "WAVE"標誌 | |
0CH | 4 | Char | "fmt"標誌 | |
10H | 4 | 過渡字節(不定) | ||
14H | 2 | int16 | 格式類別 | |
16H | 2 | int16 | 通道數 | |
18H | 2 | int16 | 採樣率(每秒樣本數),表示每一個通道的播放速度 | |
1CH | 4 | int32 | 波形音頻數據傳送速率 | |
20H | 2 | int16 | 數據塊的調整數(按字節算的) | |
22H | 2 | 每樣本的數據位數 | ||
24H | 4 | Char | 數據標記符"data" | |
28H | 4 | int32 | 語音數據的長度 |
解答:
將WAV文件格式定義爲結構體WAVEFORMAT:
typedef struct tagWaveFormat { char cRiffFlag[4]; UIN32 nFileLen; char cWaveFlag[4]; char cFmtFlag[4]; char cTransition[4]; UIN16 nFormatTag ; UIN16 nChannels; UIN16 nSamplesPerSec; UIN32 nAvgBytesperSec; UIN16 nBlockAlign; UIN16 nBitNumPerSample; char cDataFlag[4]; UIN16 nAudioLength; } WAVEFORMAT; |
假設WAV文件內容讀出後存放在指針buffer開始的內存單元內,則分析文件格式的代碼很簡單,爲:
WAVEFORMAT waveFormat; memcpy( &waveFormat, buffer,sizeof( WAVEFORMAT ) ); |
直接經過訪問waveFormat的成員,就能夠得到特定WAV文件的各項格式信息。
剖析:
試題6考查面試者組織數據結構的能力,有經驗的程序設計者將屬於一個總體的數據成員組織爲一個結構體,利用指針類型轉換,能夠將memcpy、memset等函數直接用於結構體地址,進行結構體的總體操做。 透過這個題能夠看出面試者的程序設計經驗是否豐富。
試題7:編寫類String的構造函數、析構函數和賦值函數,已知類String的原型爲:
class String { public: String(const char *str = NULL); // 普通構造函數 String(const String &other); // 拷貝構造函數 ~ String(void); // 析構函數 String & operate =(const String &other); // 賦值函數 private: char *m_data; // 用於保存字符串 }; |
解答:
//普通構造函數 String::String(const char *str) { if(str==NULL) { m_data = new char[1]; // 得分點:對空字符串自動申請存放結束標誌''的空 //加分點:對m_data加NULL 判斷 *m_data = '/0'; } else { int length = strlen(str); m_data = new char[length+1]; // 若能加 NULL 判斷則更好 strcpy(m_data, str); } } // String的析構函數 String::~String(void) { delete [] m_data; // 或delete m_data; } //拷貝構造函數 String::String(const String &other) // 得分點:輸入參數爲const型 { int length = strlen(other.m_data); m_data = new char[length+1]; //加分點:對m_data加NULL 判斷 strcpy(m_data, other.m_data); } //賦值函數 String & String::operate =(const String &other) // 得分點:輸入參數爲const型 { if(this == &other) //得分點:檢查自賦值 return *this; delete [] m_data; //得分點:釋放原有的內存資源 int length = strlen( other.m_data ); m_data = new char[length+1]; //加分點:對m_data加NULL 判斷 strcpy( m_data, other.m_data ); return *this; //得分點:返回本對象的引用 } |
剖析:
可以準確無誤地編寫出String類的構造函數、拷貝構造函數、賦值函數和析構函數的面試者至少已經具有了C++基本功的60%以上!
在這個類中包括了指針類成員變量m_data,當類中包括指針類成員變量時,必定要重載其拷貝構造函數、賦值函數和析構函數,這既是對C++程序員的基本要求,也是《Effective C++》中特別強調的條款。
仔細學習這個類,特別注意加註釋的得分點和加分點的意義,這樣就具有了60%以上的C++基本功!
試題8:請說出static和const關鍵字儘量多的做用
解答:
static關鍵字至少有下列n個做用:
(1)函數體內static變量的做用範圍爲該函數體,不一樣於auto變量,該變量的內存只被分配一次,所以其值在下次調用時仍維持上次的值;
(2)在模塊內的static全局變量能夠被模塊內所用函數訪問,但不能被模塊外其它函數訪問;
(3)在模塊內的static函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明它的模塊內;
(4)在類中的static成員變量屬於整個類所擁有,對類的全部對象只有一份拷貝;
(5)在類中的static成員函數屬於整個類所擁有,這個函數不接收this指針,於是只能訪問類的static成員變量。
const關鍵字至少有下列n個做用:
(1)欲阻止一個變量被改變,能夠使用const關鍵字。在定義該const變量時,一般須要對它進行初始化,由於之後就沒有機會再去改變它了;
(2)對指針來講,能夠指定指針自己爲const,也能夠指定指針所指的數據爲const,或兩者同時指定爲const;
(3)在一個函數聲明中,const能夠修飾形參,代表它是一個輸入參數,在函數內部不能改變其值;
(4)對於類的成員函數,若指定其爲const類型,則代表其是一個常函數,不能修改類的成員變量;
(5)對於類的成員函數,有時候必須指定其返回值爲const類型,以使得其返回值不爲「左值」。例如:
(1)欲阻止一個變量被改變,能夠使用const關鍵字。在定義該const變量時,一般須要對它進行初始化,由於之後就沒有機會再去改變它了;
(2)對指針來講,能夠指定指針自己爲const,也能夠指定指針所指的數據爲const,或兩者同時指定爲const;
(3)在一個函數聲明中,const能夠修飾形參,代表它是一個輸入參數,在函數內部不能改變其值;
(4)對於類的成員函數,若指定其爲const類型,則代表其是一個常函數,不能修改類的成員變量;
(5)對於類的成員函數,有時候必須指定其返回值爲const類型,以使得其返回值不爲「左值」。例如:
const classA operator*(const classA& a1,const classA& a2); |
operator*的返回結果必須是一個const對象。若是不是,這樣的變態代碼也不會編譯出錯:
classA a, b, c; (a * b) = c; // 對a*b的結果賦值 |
操做(a * b) = c顯然不符合編程者的初衷,也沒有任何意義。
剖析:
驚訝嗎?小小的static和const竟然有這麼多功能,咱們能回答幾個?若是隻能回答1~2個,那還真得閉關再好好修煉修煉。
這個題能夠考查面試者對程序設計知識的掌握程度是初級、中級仍是比較深刻,沒有必定的知識廣度和深度,不可能對這個問題給出全面的解答。大多數人只能回答出static和const關鍵字的部分功能。
4.技巧題
試題1:請寫一個C函數,若處理器是Big_endian的,則返回0;如果Little_endian的,則返回1
解答:
int checkCPU() { { union w { int a; char b; } c; c.a = 1; return (c.b == 1); } } |
剖析:
嵌入式系統開發者應該對Little-endian和Big-endian模式很是瞭解。採用Little-endian模式的CPU對操做數的存放方式是從低字節到高字節,而Big-endian模式對操做數的存放方式是從高字節到低字節。例如,16bit寬的數0x1234在Little- endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)爲:
內存地址 | 存放內容 |
0x4000 | 0x34 |
0x4001 | 0x12 |
而在Big-endian模式CPU內存中的存放方式則爲:
內存地址 | 存放內容 |
0x4000 | 0x12 |
0x4001 | 0x34 |
32bit寬的數0x12345678在Little-endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)爲:
內存地址 | 存放內容 |
0x4000 | 0x78 |
0x4001 | 0x56 |
0x4002 | 0x34 |
0x4003 | 0x12 |
而在Big-endian模式CPU內存中的存放方式則爲:
內存地址 | 存放內容 |
0x4000 | 0x12 |
0x4001 | 0x34 |
0x4002 | 0x56 |
0x4003 | 0x78 |
聯合體union的存放順序是全部成員都從低地址開始存放,面試者的解答利用該特性,輕鬆地得到了CPU對內存採用Little-endian仍是Big-endian模式讀寫。若是誰能當場給出這個解答,那簡直就是一個天才的程序員。
試題2:寫一個函數返回1+2+3+…+n的值(假定結果不會超過長整型變量的範圍)
解答:
int Sum( int n ) { return ( (long)1 + n) * n / 2; //或return (1l + n) * n / 2; } |
剖析:
對於這個題,只能說,也許最簡單的答案就是最好的答案。下面的解答,或者基於下面的解答思路去優化,無論怎麼「折騰」,其效率也不可能與直接return ( 1 l + n ) * n / 2相比!
int Sum( int n ) { long sum = 0; for( int i=1; i<=n; i++ ) { sum += i; } return sum; } |
因此程序員們須要敏感地將數學等知識用在程序設計中。
終於明白了:按值傳遞意味着當將一個參數傳遞給一個函數時,函數接收的是原始值的一個副本。所以,若是函數修改了該參數,僅改變副本,而原始值保持不變。按引用傳遞意味着當將一個參數傳遞給一個函數時,函數接收的是原始值的內存地址,而不是值的副本。所以,若是函數修改了該參數,調用代碼中的原始值也隨之改變。
無論是在c/c++中仍是在java函數調用都是傳值調用,.
當參數是對象的時候,傳遞的是對象的引用,這個和c/c++傳遞指針是一個道理,在函數中改變引用自己,不會改變引用所指向的對象.
當參數是對象的時候,傳遞的是對象的引用,這個和c/c++傳遞指針是一個道理,在函數中改變引用自己,不會改變引用所指向的對象.
華爲面試題
四、SQL問答題
SELECT * FROM TABLE
和
SELECT * FROM TABLE
WHERE NAME LIKE '%%' AND ADDR LIKE '%%'
AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%'
OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' )
的檢索結果爲什麼不一樣?
答: 前者檢索所有,後者有三種狀況檢索不出:NAME=null或ADDR=null或1_ADDR LIKE 2_ADDR 3_ADDR 4_ADDR其一爲null.
SELECT * FROM TABLE
和
SELECT * FROM TABLE
WHERE NAME LIKE '%%' AND ADDR LIKE '%%'
AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%'
OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' )
的檢索結果爲什麼不一樣?
答: 前者檢索所有,後者有三種狀況檢索不出:NAME=null或ADDR=null或1_ADDR LIKE 2_ADDR 3_ADDR 4_ADDR其一爲null.
前者檢索全部記錄,後者只能檢索出 NAME 和ADDR中非Null的記錄。
五、SQL問答題
表結構:
一、 表名:g_cardapply
字段(字段名/類型/長度):
g_applyno varchar 8;//申請單號(關鍵字)
g_applydate bigint 8;//申請日期
g_state varchar 2;//申請狀態
二、 表名:g_cardapplydetail
字段(字段名/類型/長度):
g_applyno varchar 8;//申請單號(關鍵字)
g_name varchar 30;//申請人姓名
g_idcard varchar 18;//申請人身份證號
g_state varchar 2;//申請狀態
其中,兩個表的關聯字段爲申請單號。
題目:
一、 查詢身份證號碼爲440401430103082的申請日期
select A.g_applydate
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idCard = '440401430103082'
二、 查詢同一個身份證號碼有兩條以上記錄的身份證號碼及記錄個數
select g_idCard,count(*) as Cnt from g_cardapplydetail
group by g_idcard
having count(*) > 1
三、 將身份證號碼爲440401430103082的記錄在兩個表中的申請狀態均改成07
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'
update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idcard = '440401430103082'
四、 刪除g_cardapplydetail表中全部姓李的記錄
delete from g_cardapplydetail
where g_name like '李%'
表結構:
一、 表名:g_cardapply
字段(字段名/類型/長度):
g_applyno varchar 8;//申請單號(關鍵字)
g_applydate bigint 8;//申請日期
g_state varchar 2;//申請狀態
二、 表名:g_cardapplydetail
字段(字段名/類型/長度):
g_applyno varchar 8;//申請單號(關鍵字)
g_name varchar 30;//申請人姓名
g_idcard varchar 18;//申請人身份證號
g_state varchar 2;//申請狀態
其中,兩個表的關聯字段爲申請單號。
題目:
一、 查詢身份證號碼爲440401430103082的申請日期
select A.g_applydate
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idCard = '440401430103082'
二、 查詢同一個身份證號碼有兩條以上記錄的身份證號碼及記錄個數
select g_idCard,count(*) as Cnt from g_cardapplydetail
group by g_idcard
having count(*) > 1
三、 將身份證號碼爲440401430103082的記錄在兩個表中的申請狀態均改成07
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'
update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idcard = '440401430103082'
四、 刪除g_cardapplydetail表中全部姓李的記錄
delete from g_cardapplydetail
where g_name like '李%'
三、 將身份證號碼爲440401430103082的記錄在兩個表中的申請狀態均改成07
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'
update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idcard = '440401430103082'
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'
update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idcard = '440401430103082'
五、SQL問答題:
/*Select g_cardapply. g_applydate
From g_cardapply, g_cardapplydetail
Where g_cardapply. g_applyno=g_cardapplydetail. g_applyno
And g_cardapplydetail.g_idcard='440401430103082'*/
/*Select *From (select count(*) g_count , g_idcard
From g_cardapplydetail
Group by g_idcard ) a
Where a. g_count >= 2*/
/*Update g_cardapply
set g_state='07'
where g_applyno in (select distinct g_applyno
from g_cardapplydetail
where g_idcard ='440401430103082')
update g_cardapplydetail
set g_state='07'
where g_idcard='440401430103082' */
/*Delete from g_cardapplydetail
Where g_name like '李%'*/
經過測試
PS:偶GF作的,本身先汗一下
/*Select g_cardapply. g_applydate
From g_cardapply, g_cardapplydetail
Where g_cardapply. g_applyno=g_cardapplydetail. g_applyno
And g_cardapplydetail.g_idcard='440401430103082'*/
/*Select *From (select count(*) g_count , g_idcard
From g_cardapplydetail
Group by g_idcard ) a
Where a. g_count >= 2*/
/*Update g_cardapply
set g_state='07'
where g_applyno in (select distinct g_applyno
from g_cardapplydetail
where g_idcard ='440401430103082')
update g_cardapplydetail
set g_state='07'
where g_idcard='440401430103082' */
/*Delete from g_cardapplydetail
Where g_name like '李%'*/
經過測試
PS:偶GF作的,本身先汗一下
金山公司幾道面試題
4. In C++, there're four type of Casting Operators, please enumerate and explain them especially the difference.
解析: C++類型轉換問題
答案: reinterpret_cast,static_cast,const_cast,dynamic_cast
static_cast 數制轉換
dynamic_cast 用於執行向下轉換和在繼承之間的轉換
const_cast 去掉const
reinterpret_cast 用於執行並不安全的orimplmentation_dependent類型轉換
dynamic_cast 用於執行向下轉換和在繼承之間的轉換
const_cast 去掉const
reinterpret_cast 用於執行並不安全的orimplmentation_dependent類型轉換
7 如下代碼有什麼問題,如何修改?
#include <iostream>
#include <vector>
using namespace std;
void print(vector<int>);
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);
//刪除array數組中全部的6
vector<int>::iterator itor;
vector<int>::iterator itor2;
itor=array.begin();
for(itor=array.begin(); itor!=array.end(); )
{
if(6==*itor)
{
itor2=itor;
array.erase(itor2);
}
itor++;
}
print(array);
return 0;
}
void print(vector<int> v)
{
cout << "n vector size is: " << v.size() << endl;
vector<int>::iterator p = v.begin();
}
個人答案是,迭代器問題,只能刪除第一個6,之後迭代器就失效了,不能刪除以後的元素。
但我不知道怎麼改
void print(const vector<int>&);
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);
//刪除array數組中全部的6
array.erase( remove( array.begin(), array.end(), 6 ) , array.end() );
print(array);
return 0;
}
void print(const vector<int>& v)
{
cout << "n vector size is: " << v.size() << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ") );
}
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);
//刪除array數組中全部的6
array.erase( remove( array.begin(), array.end(), 6 ) , array.end() );
print(array);
return 0;
}
void print(const vector<int>& v)
{
cout << "n vector size is: " << v.size() << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ") );
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(3);
array.push_back(9);
array.push_back(8);
array.push_back(5);
//ɾ³ýarrayÊý×éÖÐËùÓеÄ6
vector<int>::iterator itor;
itor=array.begin();
for(itor=array.begin(); itor!=array.end();++itor )
{
if(6==*itor)
{
itor=array.erase(itor);
--itor;
}
}
cout << "vector size is: " << array.size() << endl;
for(itor=array.begin(); itor!=array.end();++itor )
{
cout<<*itor<<" ";
}
system("pause");
return 0;
}
#include <vector>
using namespace std;
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(3);
array.push_back(9);
array.push_back(8);
array.push_back(5);
//ɾ³ýarrayÊý×éÖÐËùÓеÄ6
vector<int>::iterator itor;
itor=array.begin();
for(itor=array.begin(); itor!=array.end();++itor )
{
if(6==*itor)
{
itor=array.erase(itor);
--itor;
}
}
cout << "vector size is: " << array.size() << endl;
for(itor=array.begin(); itor!=array.end();++itor )
{
cout<<*itor<<" ";
}
system("pause");
return 0;
}
答案: 執行itor=array.erase(itor);這句話後,itor不會移動,而只是把刪除的數後面的數都往前移一位,因此刪除了第一個6後,指針指向第2個6,而後在來個itor++,指針就指向array.end()了,給你畫個草圖:
1 6 6 3 array.end() //最開始指針itor指向第一個6;
1 6 3 array.end() //刪除第一個6後,指向第二個6
1 6 3 array.end() //itor++後,就指向3了,因此不能刪除
1 6 6 3 array.end() //最開始指針itor指向第一個6;
1 6 3 array.end() //刪除第一個6後,指向第二個6
1 6 3 array.end() //itor++後,就指向3了,因此不能刪除
2. What are three ways in which a thread can enter the waiting state?
答:
CPU調度給優先級更高的thread,原先thread進入waiting
阻塞的thread得到資源或者信號,進入waiting
還有什麼
答:
CPU調度給優先級更高的thread,原先thread進入waiting
阻塞的thread得到資源或者信號,進入waiting
還有什麼
面試與被面試總結
我從事技術工做,
這幾年的面試與被面試總結
先說我去被面試的經驗吧。
回答清楚了2個問題,就能順利過關了。
1。爲何要離開上一家公司。
2。公司爲何要僱傭你。
問第一個問題的是hr(或老闆),呵呵 ,即便你技術過關,hr那裏沒有好的影響,結果是一個字,難!
如何回答呢? hr想推論出你在他的公司能呆多久。這個時候,你甚至能夠明確告訴他,我在貴公司至少能呆n(n>=1)年----固然,你沒有把握的話,絕對不能亂說,社會上混,要講信用的。
有一次,我就在這個問題上吃了大虧,我看公司環境還不錯,就我自作主張回答1年,結果,hr心目中是m(m>=2)年,呵呵,結果可想而知了。要知道,技術面試都過關了,Hr面試是2選1,在回家的路上,我只能祈禱對手自動放棄或找到了其餘更好的工做。:)
問第二個問題的是技術官。你要讓他知道你已經作過哪些商業做品。必定要是商業做品。在裏面負責哪方面具體工做,對於你熟悉的地方要多說。最好就是能爭取筆試或上機,由於用用口說的話,你們理解都不同,偏差可能很大,結果對你至關不利。在這個問題上我也吃過虧的,曾有一個我很看好的職位,認爲把握很大,業務理解上也頗有優點,和技術官一談,結果是game over。要知道,在其餘公司的上機和筆試中,我都能在應聘者中取得高分。
再說我去面試別人的經驗吧。
當時,個人任務是出題,給分。若你以爲題很難,那麼,請千萬不要放棄,顯然,你的對手也以爲難。只要堅持,我會認爲這人有耐心很毅力,在之後的工做中也是好的合做者。題必定要作完,表現出認真的態度,如有疑問或卡殼,還能夠尋求面試官的幫助,這些不會減分,相反,會增長你和他們的接觸機會,面試官會評估你的溝通能力。
有一次,有1我的來面試,題沒有徹底ok,但很規範,態度很認真,他把他知道的都作上去了,我給了他技術類的高分。後來,順利進入公司,再後來進步很快,成了重要角色。
若文章對你有幫助的話,請在此討論。
祝你成功
面試題
1.鏈表和數組的區別在哪裏?
2.編寫實現鏈表排序的一種算法。說明爲何你會選擇用這樣的方法?
3.編寫實現數組排序的一種算法。說明爲何你會選擇用這樣的方法?
4.請編寫能直接實現strstr()函數功能的代碼。
5.編寫反轉字符串的程序,要求優化速度、優化空間。
6.在鏈表裏如何發現循環連接?
7.給出洗牌的一個算法,並將洗好的牌存儲在一個整形數組裏。
8.寫一個函數,檢查字符是不是整數,若是是,返回其整數值。(或者:怎樣只用4行代碼 ,編寫出一個從字符串到長整形的函數?)
9.給出一個函數來輸出一個字符串的全部排列。
10.請編寫實現malloc()內存分配函數功能同樣的代碼。
11.給出一個函數來複制兩個字符串A和B。字符串A的後幾個字節和字符串B的前幾個字節重疊。
12.怎樣編寫一個程序,把一個有序整數數組放到二叉樹中?
13.怎樣從頂部開始逐層打印二叉樹結點數據?請編程。
14.怎樣把一個鏈表掉個順序(也就是反序,注意鏈表的邊界條件並考慮空鏈表)?
另外:
1、單項選擇題:(共12題,每題2分,共24分)
1. 下面哪個不是C++的標準數據類型? ( D)
A. int B. char
C. bool D. real
2. break關鍵字在哪種語法結構中不能使用? (C)
A. for語句 B. switch語句
C. if語句 D. while語句
3. 類的繼承方式有幾種? (B )
A. 兩種 B. 三種
C. 四種 D. 六種
4. extern關鍵字的做用是什麼? (D)
A. 聲明外部連接 B. 聲明外部頭文件引用
C. 聲明使用擴展C++語句 D. 聲明外部成員函數、成員數據。
5. C庫函數strstr的功能是? (A )
A. 查找子串 B. 計算字符串長度
C. 字符串比較 D. 連結字符串
6. stl::deque是一種什麼數據類型? (A )
A. 動態數組 B. 鏈表
C. 堆棧 D. 樹
7. STL庫裏含有下面的哪種泛型算法? (D )
A. KMP查找 B. 折半查找
C. 冒泡排序 D. 快速排序
8. 如今最快且最通用的排序算法是什麼? (A )
A. 快速排序 B. 冒泡排序
C. 選擇排序 D. 外部排序
9. Win32下的線程的哪種優先級最高? ( C)
A. THREAD_PRIORITY_HIGHEST 高優先級
2.編寫實現鏈表排序的一種算法。說明爲何你會選擇用這樣的方法?
3.編寫實現數組排序的一種算法。說明爲何你會選擇用這樣的方法?
4.請編寫能直接實現strstr()函數功能的代碼。
5.編寫反轉字符串的程序,要求優化速度、優化空間。
6.在鏈表裏如何發現循環連接?
7.給出洗牌的一個算法,並將洗好的牌存儲在一個整形數組裏。
8.寫一個函數,檢查字符是不是整數,若是是,返回其整數值。(或者:怎樣只用4行代碼 ,編寫出一個從字符串到長整形的函數?)
9.給出一個函數來輸出一個字符串的全部排列。
10.請編寫實現malloc()內存分配函數功能同樣的代碼。
11.給出一個函數來複制兩個字符串A和B。字符串A的後幾個字節和字符串B的前幾個字節重疊。
12.怎樣編寫一個程序,把一個有序整數數組放到二叉樹中?
13.怎樣從頂部開始逐層打印二叉樹結點數據?請編程。
14.怎樣把一個鏈表掉個順序(也就是反序,注意鏈表的邊界條件並考慮空鏈表)?
另外:
1、單項選擇題:(共12題,每題2分,共24分)
1. 下面哪個不是C++的標準數據類型? ( D)
A. int B. char
C. bool D. real
2. break關鍵字在哪種語法結構中不能使用? (C)
A. for語句 B. switch語句
C. if語句 D. while語句
3. 類的繼承方式有幾種? (B )
A. 兩種 B. 三種
C. 四種 D. 六種
4. extern關鍵字的做用是什麼? (D)
A. 聲明外部連接 B. 聲明外部頭文件引用
C. 聲明使用擴展C++語句 D. 聲明外部成員函數、成員數據。
5. C庫函數strstr的功能是? (A )
A. 查找子串 B. 計算字符串長度
C. 字符串比較 D. 連結字符串
6. stl::deque是一種什麼數據類型? (A )
A. 動態數組 B. 鏈表
C. 堆棧 D. 樹
7. STL庫裏含有下面的哪種泛型算法? (D )
A. KMP查找 B. 折半查找
C. 冒泡排序 D. 快速排序
8. 如今最快且最通用的排序算法是什麼? (A )
A. 快速排序 B. 冒泡排序
C. 選擇排序 D. 外部排序
9. Win32下的線程的哪種優先級最高? ( C)
A. THREAD_PRIORITY_HIGHEST 高優先級
B. THREAD_PRIORITY_IDLE 最低優先級,僅在系統空閒時執行
C. THREAD_PRIORITY_TIME_CRITICAL 最高優先級
C. THREAD_PRIORITY_TIME_CRITICAL 最高優先級
D. THREAD_PRIORITY_ABOVE_NORMAL 高於普通優先級
10. 下面四個選項中,哪個不是WinMain函數的參數? (D )
A. HINSTANCE B. INT
C. LPSTR D. WPARAM
11. VC++的編譯器中,運算符new底層的實現是什麼? ( B )
A. VirtualAlloc() B. HeapAlloc()
C. GlobalAlloc() D. AllocateUserPhysicalPages()
12. 下面哪一本C++參考書最厚? ( C)
A. 《Think in C++》 B. 《深刻淺出MFC》
C. 《C++ Primer》 D. 《Effective C++》
10. 下面四個選項中,哪個不是WinMain函數的參數? (D )
A. HINSTANCE B. INT
C. LPSTR D. WPARAM
11. VC++的編譯器中,運算符new底層的實現是什麼? ( B )
A. VirtualAlloc() B. HeapAlloc()
C. GlobalAlloc() D. AllocateUserPhysicalPages()
12. 下面哪一本C++參考書最厚? ( C)
A. 《Think in C++》 B. 《深刻淺出MFC》
C. 《C++ Primer》 D. 《Effective C++》
13. 當調用Windows API函數InvalidateRect,將會產生什麼消息(A)
A. WM_PAINT B. WM_CREATE
C. WM_NCHITTEST D. WM_SETFOCUS
A. WM_PAINT B. WM_CREATE
C. WM_NCHITTEST D. WM_SETFOCUS
14. 關於virtual void Draw()=0,下面說法正確的有幾個(C)
(1)它是純虛函數(對)
(2)它在定義它的類中不能實現(對)
(3)定義它的類不可實例化(對)
(4)若是一個類要繼承一個ADT類,必需要實現其中的全部純虛函數(錯)//能夠不實現,派生以後的類仍舊做爲一個抽象類.
A. 1 B. 2
C. 3 D. 4
2、不定項選擇題:(共6題,每題3分,共18分,多選、錯選、漏選均不給分)
1. vector::iterator重載了下面哪些運算符? (ACD)
A. ++ B. >>
C. *(前置) D. ==
2. CreateFile( )的功能有哪幾個? (AB )
A. 打開文件 B. 建立新文件
C. 文件更名 D. 刪除文件
3. 下面哪些是句柄(HANDLE)? (ABCD )
A. HINSTANCE 實例句柄B. HWND 窗口句柄
C. HDC 設備描述符號句柄 D. HFONT 字體句柄
4. 下面哪些不是OpenGL標準幾何元素的繪製模式? (A )
A. GL_FOG B. GL_LINE_STRIP
C. GL_POINTS D. GL_TRIANGLE_FAN
5. 下面哪些運算符不能被重載? (ABD )
A. 作用域運算符「::」 B. 對象成員運算符「.」
C. 指針成員運算符「->」 D. 三目運算符「? :」
6. 下面哪些人曾參與了世界上第一個C++編譯器的開發? ( )
A. Bill Gates B. Stanley Lippman
C. Anderson Hejlsberg D. Bjarne Stroustrup
(1)它是純虛函數(對)
(2)它在定義它的類中不能實現(對)
(3)定義它的類不可實例化(對)
(4)若是一個類要繼承一個ADT類,必需要實現其中的全部純虛函數(錯)//能夠不實現,派生以後的類仍舊做爲一個抽象類.
A. 1 B. 2
C. 3 D. 4
2、不定項選擇題:(共6題,每題3分,共18分,多選、錯選、漏選均不給分)
1. vector::iterator重載了下面哪些運算符? (ACD)
A. ++ B. >>
C. *(前置) D. ==
2. CreateFile( )的功能有哪幾個? (AB )
A. 打開文件 B. 建立新文件
C. 文件更名 D. 刪除文件
3. 下面哪些是句柄(HANDLE)? (ABCD )
A. HINSTANCE 實例句柄B. HWND 窗口句柄
C. HDC 設備描述符號句柄 D. HFONT 字體句柄
4. 下面哪些不是OpenGL標準幾何元素的繪製模式? (A )
A. GL_FOG B. GL_LINE_STRIP
C. GL_POINTS D. GL_TRIANGLE_FAN
5. 下面哪些運算符不能被重載? (ABD )
A. 作用域運算符「::」 B. 對象成員運算符「.」
C. 指針成員運算符「->」 D. 三目運算符「? :」
6. 下面哪些人曾參與了世界上第一個C++編譯器的開發? ( )
A. Bill Gates B. Stanley Lippman
C. Anderson Hejlsberg D. Bjarne Stroustrup
7. 如下說法正確的是? ( ABC)
A. 頭文件中的 ifndef/define/endif 是爲了防止該頭文件被重複引用。
B. 對於#include <filename.h> ,編譯器從標準庫路徑開始搜索 filename.h
對於#include 「filename.h」 ,編譯器從用戶的工做路徑開始搜索 filename.h
C. C++語言支持函數重載,C語言不支持函數重載。函數被C++編譯後在庫中的名字與C 語言的不一樣。假設某個函數的原型爲: void foo(int x, int y); 該函數被C編譯器編譯後在庫中的名字爲_foo,而C++編譯器則會產生像_foo_int_int之類的名字。C++提供了C鏈接交換指定符號extern「C」來解決名字匹配問題。
D. fopen函數只是把文件目錄信息調入內存。//錯,fopen是把整個文件讀入內存
3、填空題:(共8題,每題3分,共24分)
1. 一個大小爲320 X 192,顏色爲灰度索引色的設備相關位圖有______字節。若是此位圖顏色爲24位真彩色,則它的大小有______字節。
2. Windows API的中文意義是____ windows應用程序接口___。
3. 計算反正弦的庫函數是__asin()____;計算浮點數絕對值的庫函數是__fabs()____;計算浮點數n次方的庫函數是__pow()____;將浮點數轉化爲字符串的庫函數是___fcvt()___。
4. 若是i等於5,那麼( ++i ) - -的返回值是__6__。
5. API LoadBitmap()的功能是從__指定的模塊和或應用程序實例__中讀取位圖數據到內存。
6. new和__delete___對應,malloc和_free___對應,他們之間_ 不能__交叉混用。calloc的功能是__爲數組動態分配內存___,realloc的功能是_改變原有內存區域的大小_。
7. SendMessage和PostMessage都會向窗體發送一個消息,但SendMessage__將一條消息發送到指定窗口,當即處理__而PostMessage__將一條消息投遞到指定窗口的消息隊列,不須要當即處理___。
8. 輸出指定圓心、半徑、邊數的圓上的點:
const int nCount = 12;
const double dOrgX = 5.0,
dOrgY = 3.0;
const double dRadius = 2.0;
for( int i = 0; i < nCount; i++ )
{
double dAngle = M_PI * 2.0 / (double)nCount * i;
cout << "第" << i << "點:X = " << ________; cout << ", Y = " << __________ << endl;
}
3、判斷題:(共12題,每題2分,共24分)
1. 一個類必需要有一個不帶參數的構造函數。 錯
2. 你不能寫一個虛的構造函數。 對
3. 類裏面全部的函數都是純虛函數時纔是純虛類。 錯
4. const成員函數對於任何本類的數據成員都不能進行寫操做。 對
5. 函數中帶默認值的參數必須位於不帶默認值的參數以後。 對
6. char *p = "Test"; p[0] = 'R'; 錯
7. cout << "Test"; 對
8. stl::list不支持隨機訪問疊代器。 對
9. stl::vector的效率比stl::list高。 錯
10. VC和VC++是一回事,而VC++是一種比C++更難一些的語言。 錯
11. 理論上,new和malloc形成的內存泄露都會由操做系統回收。 錯
12. 在C++中struct和class的差異很大,因此從語法上不能混用。對
4、簡述題(共3題,每題5分,共15分)
1. 請簡述PeekMessage和GetMessage的區別。
A. 頭文件中的 ifndef/define/endif 是爲了防止該頭文件被重複引用。
B. 對於#include <filename.h> ,編譯器從標準庫路徑開始搜索 filename.h
對於#include 「filename.h」 ,編譯器從用戶的工做路徑開始搜索 filename.h
C. C++語言支持函數重載,C語言不支持函數重載。函數被C++編譯後在庫中的名字與C 語言的不一樣。假設某個函數的原型爲: void foo(int x, int y); 該函數被C編譯器編譯後在庫中的名字爲_foo,而C++編譯器則會產生像_foo_int_int之類的名字。C++提供了C鏈接交換指定符號extern「C」來解決名字匹配問題。
D. fopen函數只是把文件目錄信息調入內存。//錯,fopen是把整個文件讀入內存
3、填空題:(共8題,每題3分,共24分)
1. 一個大小爲320 X 192,顏色爲灰度索引色的設備相關位圖有______字節。若是此位圖顏色爲24位真彩色,則它的大小有______字節。
2. Windows API的中文意義是____ windows應用程序接口___。
3. 計算反正弦的庫函數是__asin()____;計算浮點數絕對值的庫函數是__fabs()____;計算浮點數n次方的庫函數是__pow()____;將浮點數轉化爲字符串的庫函數是___fcvt()___。
4. 若是i等於5,那麼( ++i ) - -的返回值是__6__。
5. API LoadBitmap()的功能是從__指定的模塊和或應用程序實例__中讀取位圖數據到內存。
6. new和__delete___對應,malloc和_free___對應,他們之間_ 不能__交叉混用。calloc的功能是__爲數組動態分配內存___,realloc的功能是_改變原有內存區域的大小_。
7. SendMessage和PostMessage都會向窗體發送一個消息,但SendMessage__將一條消息發送到指定窗口,當即處理__而PostMessage__將一條消息投遞到指定窗口的消息隊列,不須要當即處理___。
8. 輸出指定圓心、半徑、邊數的圓上的點:
const int nCount = 12;
const double dOrgX = 5.0,
dOrgY = 3.0;
const double dRadius = 2.0;
for( int i = 0; i < nCount; i++ )
{
double dAngle = M_PI * 2.0 / (double)nCount * i;
cout << "第" << i << "點:X = " << ________; cout << ", Y = " << __________ << endl;
}
3、判斷題:(共12題,每題2分,共24分)
1. 一個類必需要有一個不帶參數的構造函數。 錯
2. 你不能寫一個虛的構造函數。 對
3. 類裏面全部的函數都是純虛函數時纔是純虛類。 錯
4. const成員函數對於任何本類的數據成員都不能進行寫操做。 對
5. 函數中帶默認值的參數必須位於不帶默認值的參數以後。 對
6. char *p = "Test"; p[0] = 'R'; 錯
7. cout << "Test"; 對
8. stl::list不支持隨機訪問疊代器。 對
9. stl::vector的效率比stl::list高。 錯
10. VC和VC++是一回事,而VC++是一種比C++更難一些的語言。 錯
11. 理論上,new和malloc形成的內存泄露都會由操做系統回收。 錯
12. 在C++中struct和class的差異很大,因此從語法上不能混用。對
4、簡述題(共3題,每題5分,共15分)
1. 請簡述PeekMessage和GetMessage的區別。
答: Peekmessage和Getmessage都是向系統的消息隊列中取得消息,兩個函數的不一樣在於取不到消息的時候,若Getmessage()向消息隊列中取不到消息,則程序的主線程會被OS(操做系統)掛起,等到有合適的消息時才返回;如果用Peekmessage()在消息隊列中取不到消息,則程序會取得OS控制權,運行一段時間。
另外,在處理消息的時候,GetMessag()會將消息從隊列中刪除,而PeekMessage()能夠設置最後一個參數wRemoveMsg來決定是否將消息保留在隊列中。
2. 請列出你所知道的在Windows SDK平臺上,實現計時功能的方法。
另外,在處理消息的時候,GetMessag()會將消息從隊列中刪除,而PeekMessage()能夠設置最後一個參數wRemoveMsg來決定是否將消息保留在隊列中。
2. 請列出你所知道的在Windows SDK平臺上,實現計時功能的方法。
答:能夠使用SetTimer函數建立一個計時器,SetTimer的函數原型以下:
UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc
3. 請簡述你所知道的const的各類用法。
UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc
3. 請簡述你所知道的const的各類用法。
答: const 常量
const 修飾類的數據成員
const 修飾指針
const 應用在函數聲明中
const 應用在類成員函數
5、編程題:(共3題,第1小題7分,第2小題14分,第3小題24分)
1. 深度遍歷二叉樹。
struct Node
{
Node *Parent;
const 修飾類的數據成員
const 修飾指針
const 應用在函數聲明中
const 應用在類成員函數
5、編程題:(共3題,第1小題7分,第2小題14分,第3小題24分)
1. 深度遍歷二叉樹。
struct Node
{
Node *Parent;
Node *Left, *Right;
};
void Through(Node *Root)
{
}
2. 二分法查找。
int DicFind( int *Array, int Count, int Value )
{
}
3. 寫出字符串類String的默認構造函數、析構函數和重載賦值運算符。
已知類String的原型爲:
class String
{
public:
String( const char *pStr = NULL ); // 默認構造函數
~String( void ); // 析構函數
String &operate = ( const String &Source ); // 重載賦值運算符
private:
char *m_pData; // 指向字符串的指針
};
class String
{
public:
String( const char *pStr = NULL ); // 默認構造函數
~String( void ); // 析構函數
String &operate = ( const String &Source ); // 重載賦值運算符
private:
char *m_pData; // 指向字符串的指針
};
今天下午的兩道面試題
1。 一人歲數的3次方是四位數,四次方是六位數,並知道此人歲數的3次方和4次方用遍了0~9十個數字。編寫一程序求此人的歲數。
2。對1,2,3, 4, 5 這五個數任意取出兩個數,列出他們的全部組合。
2。對1,2,3, 4, 5 這五個數任意取出兩個數,列出他們的全部組合。
public static int getAge() {
int age;
int third;
int fourth;
for (int i = 11; true; i++) {
if (i < 200) {
third = (int) Math.pow(i, 3);
fourth = (int) Math.pow(i, 4);
if (getLength(third, fourth) == 10) {
age = i;
break;
}
}
}
return age;
}
public static int getLength(int args1, int args2) {
String str1 = String.valueOf(args1);
String str2 = String.valueOf(args2);
String str = str1 + str2;
if (str.length() != 10) {
return -1;
}
int[] intarray = new int[10];
for (int i = 0; i < str.length(); i++) {
intarray[i] = Integer.parseInt(str.substring(i,i+1));
}
Arrays.sort(intarray);
if(intarray[0]!=0 && intarray[9]!=9)
return -1;
return 10;
}
int age;
int third;
int fourth;
for (int i = 11; true; i++) {
if (i < 200) {
third = (int) Math.pow(i, 3);
fourth = (int) Math.pow(i, 4);
if (getLength(third, fourth) == 10) {
age = i;
break;
}
}
}
return age;
}
public static int getLength(int args1, int args2) {
String str1 = String.valueOf(args1);
String str2 = String.valueOf(args2);
String str = str1 + str2;
if (str.length() != 10) {
return -1;
}
int[] intarray = new int[10];
for (int i = 0; i < str.length(); i++) {
intarray[i] = Integer.parseInt(str.substring(i,i+1));
}
Arrays.sort(intarray);
if(intarray[0]!=0 && intarray[9]!=9)
return -1;
return 10;
}
第二題還更簡單了
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
public class A {
// http://community.csdn.net/Expert/topic/4667/4667929.xml?temp=.57922
public static void main(String[] args) {
String t;
String[] s = new String[5];
int j = s.length;
for(int i=0; i<j; i++) {
s[i] = new Integer(i+1).toString();
}
for(int i=0; i<j; i++) {
t = s[i];
for(int a=0; a<j; a++) {
t += s[i];
System.out.println(t);
}
System.out.println();
}
}
}
// http://community.csdn.net/Expert/topic/4667/4667929.xml?temp=.57922
public static void main(String[] args) {
String t;
String[] s = new String[5];
int j = s.length;
for(int i=0; i<j; i++) {
s[i] = new Integer(i+1).toString();
}
for(int i=0; i<j; i++) {
t = s[i];
for(int a=0; a<j; a++) {
t += s[i];
System.out.println(t);
}
System.out.println();
}
}
}
第二題還更簡單了
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
============================================================
樓上的沒看清題目,它是讓你對1,2,3, 4, 5 這五個數任意取出兩個數,列出他們的全部組合,因此重複的數字不該該算在裏面。
第二題應該改成:
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
break;
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
============================================================
樓上的沒看清題目,它是讓你對1,2,3, 4, 5 這五個數任意取出兩個數,列出他們的全部組合,因此重複的數字不該該算在裏面。
第二題應該改成:
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
break;
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
public class B {
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
int t = i;
for(int a = 0; a<5; a++) {
int c = a+1;
if(c == t) {
continue;
}else {
System.out.println(t*10+c);
}
}
System.out.println();
}
}
}
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
int t = i;
for(int a = 0; a<5; a++) {
int c = a+1;
if(c == t) {
continue;
}else {
System.out.println(t*10+c);
}
}
System.out.println();
}
}
}
第二題 public class Test { public static void main(String[] args) { int[][] a=new int[5][]; for(int i=0;i<a.length;i++) { a[i]=new int[i+1]; } for(int i=1;i<=a.length;i++) { for(int j=i+1;j<=a.length;j++) { System.out.print(i); System.out.print(j+" "); } System.out.print(" "); } for(int i=a.length;i>0;i--) { for(int j=i-1;j>0;j--) { System.out.print(i); System.out.print(j+" "); } System.out.print(" "); } } } |
public class Test {
public static int getDigits(String str) { int[] intarr = new int[10]; for (int i = 0; i < 10; i++) intarr[i] = 0; for (int i = 0; i < str.length(); i++) { int j = Integer.parseInt(str.substring(i, i + 1)); intarr[j] = 1; } int num = 0; for (int i = 0; i < 10; i++) num = num + intarr[i]; return num; } private static int getAge() { int age; int third; int fourth; for (age = 1; age < 100; age++) { third = (int) Math.pow(age, 3); fourth = (int) Math.pow(age, 4); if (third < 1000 || third >= 10000) continue; if (fourth < 100000 || fourth >= 1000000) continue; String str = String.valueOf(third) + String.valueOf(fourth); if (getDigits(str) == 10) return age; } return 0; } } |
第二道題
class Combine
{
public static void main(String[] args)
{
for(int i=1; i<5; i++)
{
for(int j=i+1; j<6; j++)
{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
class Combine
{
public static void main(String[] args)
{
for(int i=1; i<5; i++)
{
for(int j=i+1; j<6; j++)
{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
public class Age
{
public static void main(String [] args)
{
String str1 = null;
String str2 = null;
String str3 = null;
String str4 = "0123456789";
for(int i=10;i<50;i++)
{
str1 = Integer.toString(i*i*i);
str2 = Integer.toString(i*i*i*i);
str3 = str1+str2;
if((str1.length() == 4) && (str2.length() ==6))
{
boolean flag = true;
for(int j=0;j<10;j++)
if(str3.indexOf(str4.charAt(j))==-1)
flag = false;
if(flag){
System.out.println(">>>"+i);
System.out.println(str3);
}
}
}
}
}
{
public static void main(String [] args)
{
String str1 = null;
String str2 = null;
String str3 = null;
String str4 = "0123456789";
for(int i=10;i<50;i++)
{
str1 = Integer.toString(i*i*i);
str2 = Integer.toString(i*i*i*i);
str3 = str1+str2;
if((str1.length() == 4) && (str2.length() ==6))
{
boolean flag = true;
for(int j=0;j<10;j++)
if(str3.indexOf(str4.charAt(j))==-1)
flag = false;
if(flag){
System.out.println(">>>"+i);
System.out.println(str3);
}
}
}
}
}
比賽貼~微軟又一道筆試題
silver6 | 04 四月, 2006 09:48
怎樣只用4行代碼編寫出一個從字符串到長整形的轉換函數?
個人方法,不過好象比4行多 *_#!~
long atol(char *str)
{
char c = *str;
if( !isdigit(c) ) str++;
for(long value = 0; *str != ''; value = value * 10 + (*str -'0'),str++);
return c == '-' ? -value : value ;
}
long atol(char *str)
{
char c = *str;
if( !isdigit(c) ) str++;
for(long value = 0; *str != ''; value = value * 10 + (*str -'0'),str++);
return c == '-' ? -value : value ;
}
void stol(const char * des, long& num)
{
for (int base = 1, i = 0; des[i] != ''; base = 10, ++i)
{
num *= base;
num += (int)(des[i] - '0');
}
}
num 要初始化爲0
{
for (int base = 1, i = 0; des[i] != ''; base = 10, ++i)
{
num *= base;
num += (int)(des[i] - '0');
}
}
num 要初始化爲0
void stol(const char * des, long& num) { for (int i=num=0; des[i] != ''; i++) { num *= 10; num += (int)(des[i] - '0'); } } |
void stol(char *str, long &num)
{
while(*str != '')
{
num = num * 10 + (*str - '0');
str++;
}
}
{
while(*str != '')
{
num = num * 10 + (*str - '0');
str++;
}
}
void stol(const char * des, long& num)
{
char p = des[0];
for (int b = 1, pos = 1, base = 1; des[pos] != ''; b = 10, ++pos, base *= 10)
{
(num *= b) += (int)(des[pos] - '0');
}
p == '-' ? (num *= -1) : (num = (int)(des[0] - '0') * base + num);
}
改了一下
{
char p = des[0];
for (int b = 1, pos = 1, base = 1; des[pos] != ''; b = 10, ++pos, base *= 10)
{
(num *= b) += (int)(des[pos] - '0');
}
p == '-' ? (num *= -1) : (num = (int)(des[0] - '0') * base + num);
}
改了一下
真的是微軟的筆試題麼?
我只用了一行。
#include <iostream>
using namespace std;
long str2long(char* p,long xxx=0L)
{
return *p==''?xxx:str2long(p,xxx*10+(*p+++0-'0'));
}
int main()
{
char *str="123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}
我只用了一行。
#include <iostream>
using namespace std;
long str2long(char* p,long xxx=0L)
{
return *p==''?xxx:str2long(p,xxx*10+(*p+++0-'0'));
}
int main()
{
char *str="123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}
用STL,四行
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
long ToLong(string& s)
{
long l;
istringstream iss(s);
iss>>l;
return l;
}
int main(int argc, _TCHAR* argv[])
{
string s = "-12356";
cout<<ToLong(s);
return 0;
}
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
long ToLong(string& s)
{
long l;
istringstream iss(s);
iss>>l;
return l;
}
int main(int argc, _TCHAR* argv[])
{
string s = "-12356";
cout<<ToLong(s);
return 0;
}
謝謝剛纔上面的帖子提醒負數的問題,我更正了,仍是隻用一行:
#include <iostream>
using namespace std;
long str2long(char* p,long xxx=0L,bool IsPositive=true)
{
return *p==''?(IsPositive?xxx:xxx*(-1)):(*p=='-'?str2long(++p,0L,false):str2long(p,xxx*10+*p+++0-'0',IsPositive));
}
int main()
{
char *str="-123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}
#include <iostream>
using namespace std;
long str2long(char* p,long xxx=0L,bool IsPositive=true)
{
return *p==''?(IsPositive?xxx:xxx*(-1)):(*p=='-'?str2long(++p,0L,false):str2long(p,xxx*10+*p+++0-'0',IsPositive));
}
int main()
{
char *str="-123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}
- 上一篇機器視覺相關術語
- 下一篇用一個宏求結構體某個變量的相對偏移量