c語言面試題大全

C語言面試題大匯總

4. static有什么用途?(請至少說明兩種)

1.限制變量的作用域(DL:使其只在定義的當前文件中起作用,static是只能由與變量在同一個文件中定義的程序存取的全局變量。也就是說使全局變量成為文件的私有變量,以致其他文件不可以通過將它們定義為extern而存取這些變量。)

2.設置變量的存儲域DL:存儲在最開始的靜態存儲空間里面)


7. 引用與指針有什么區別?

1) 引用必須被初始化,指針不必。

2) 引用初始化以后不能被改變,指針可以改變所指的對象。

2) 不存在指向空值的引用,但是存在指向空值的指針


8. 描述實時系統的基本特性

在特定時間內完成特定的任務,實時性與可靠性


9. 全局變量和局部變量在內存中是否有區別?如果有,是什么區別?

全局變量儲存在靜態數據庫,局部變量在堆棧


10. 什么是平衡二叉樹?

左右子樹都是平衡二叉樹 且左右子樹的深度差值的絕對值不大于1


11. 堆棧溢出一般是由什么原因導致的?

沒有回收垃圾資源


12. 什么函數不能聲明為虛函數?

Constructor(構造函數)


13. 冒泡排序算法的時間復雜度是什么?

O(n^2)


14. 寫出float x 零值比較的if語句。

if(x>0.000001? &&? x<-0.000001)


16. Internet采用哪種網絡協議?該協議的主要層次結構?

TCP/IP? ? 應用層/傳輸層/網絡層/數據鏈路層/物理層


具體的層次有物理層,數據鏈路層,網絡層,傳輸層,會話層,表示層,應用層.

物理層:處理電氣接口,傳輸介質,就是用什么線,電流的頻率等等.???

數據鏈路層:簡單的說就是對物理層的傳輸進行物理糾錯的.包括丟幀,錯幀,兩端速率差異,線路競爭,雙工線路的協調等等.???

網絡層:主要處理子網間傳遞時的路由選擇.???

傳輸層:用來從會話層得到數據傳至網絡層.???

會話層:用來建立用戶的會話.會話的任務是在單工的線路上控制雙方的發言順序,調節沖突的.同步也是會話層的任務,這里說的同步相當于底層的斷點續傳能力.?????

表示層:是把二進制的信息轉換成各種不同的數據類型,或語言種類.???

應用層:其實就是留給一般編程人員的接口.???


17. Internet物理地址和IP地址轉換采用什么協議?

ARP (Address Resolution Protocol)(地址解析協議)

18.IP地址的編碼分為哪倆部分?

IP地址由兩部分組成,網絡號和主機號。不過是要和子網掩碼按位與上之后才能區分

哪些是網絡位哪些是主機位。



2.用戶輸入M,N值,從1N開始順序循環數數,每數到M輸出該數值,直至全部輸出。寫出C程序。

循環鏈表,用取余操作做


3.不能做switch()的參數類型是:

switch的參數不能為實型。


華為

1、局部變量能否和全局變量重名?

答:能,局部會屏蔽全局。要用全局變量,需要使用"::"

局部變量可以與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不

會用到全局變量。對于有些編譯器而言,在同一個函數內可以定義多個同名的局部變量,

比如在兩個循環體內都定義一個同名的局部變量,而那個局部變量的作用域就在那個循環

體內

2、如何引用一個已經定義過的全局變量?

答:extern(在使用該變量的地方還要定義一次,extern只相當于聲明,且只能在函數體外定義)/

? ? static(在使用時不用定義,且作用域限制在當前源文件,且只能在函數體內重新賦值)

可以用引用頭文件的方式(必須用static聲明),也可以用extern關鍵字,如果用引用頭文件方式來引用某個在頭文件中聲明的全局變理,假定你將那個變寫錯了,那么在編譯期間會報錯,如果你用extern方式引用時,假定你犯了同樣的錯誤,那么在編譯期間不會報錯,而在連接期間報錯


3、全局變量可不可以定義在可被多個.C文件包含的頭文件中?為什么?

答:可以,在不同的C文件中以static形式來聲明同名全局變量。

可以在不同的C文件中聲明同名的全局變量,前提是其中只能有一個C文件中對此變量賦初值,此時連接不會出錯


4、語句for( 1 )有什么問題?它是什么意思?

答:while(1)相同。


5do……whilewhile……do有什么區別?

答:前一個循環一遍再判斷,后一個判斷以后再循環


6、請寫出下列代碼的輸出內容

#include<stdio.h>

main()

{

int a,b,c,d;

a=10;

b=a++;

c=++a;

d=10*a++;

printf("bcd%d%d%d"bcd;

return 0;

}

答:1012120


1static全局變量與普通的全局變量有什么區別?static局部變量和普通局部變量有什么

區別?static函數與普通函數有什么區別?

全局變量(外部變量)的說明之前再冠以static 就構成了靜態的全局變量。全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。 這兩者在存儲方式上并無不同。這兩者的區別雖在于非靜態全局變量的作用域是整個源程序, 當一個源程序由多個源文

件組成時,非靜態的全局變量在各個源文件中都是有效的。 而靜態全局變量則限制了其作

用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。

由于靜態全局變量的作用域局限于一個源文件內,只能為該源文件內的函數公用, 因此可

以避免在其它源文件中引起錯誤。

從以上分析可以看出, 把局部變量改變為靜態變量后是改變了它的存儲方式即改變了它的

生存期(靜態局部變量在程序運行結束釋放空間,而普通靜態局部變量在函數退出時釋放空間)。

把全局變量改變為靜態變量后是改變了它的作用域, 限制了它的使用范圍。

static函數與普通函數作用域不同。僅在本文件。只在當前源文件中使用的函數應該說明

為內部函數(static),內部函數應該在當前源文件中說明和定義。對于可在當前源文件以

外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件

(用static聲明的即內部函數,內部函數指只能被本文件的其他函數所調用的函數,

內部函數在C++實際上可以通過類名修飾符訪問其他均為外部函數)


static全局變量與普通的全局變量有什么區別:

static全局變量只初使化一次,防止在其他文件單元中被引用;

static局部變量和普通局部變量有什么區別:

static局部變量只被初始化一次,下一次依據上一次結果值;

static函數與普通函數有什么區別:

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


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


3、設有以下說明和定義:

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 date)+sizeof(max));的執行結果是:___52____

答:DATE是一個union, 變量公用空間. 里面最大的變量類型是int[5], 占用20個字節.

以它的大小是20

data是一個struct, 每個變量分開占用空間. 依次為int4 + DATE20 + double8 = 32.

所以結果是 20 + 32 = 52.

當然...在某些16位編輯器下, int可能是2字節,那么結果是 int2 + DATE10 + double8 =

?20

4、隊列和棧有什么區別?

隊列先進先出,棧后進先出

5、寫出下列代碼的輸出內容

#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)

{

INCp=&inc;

int temp =p(arg1);

fun(&temp,&arg1, arg2);

printf("%d\n",*arg2);

}


main()

{

int a;

show(multi,10,&a);

return 0;

}

答:110


7、請找出下面代碼中的所有錯誤

說明:以下代碼是把一個字符串倒序,如“abcd”倒序后變為“dcba”


1#include"string.h"

2main()

3{

4char*src="hello,world";

5char* dest=NULL;

6int len=strlen(src);

7dest=(char*)malloc(len);

8char* d=dest;

9char* s=src[len];

10while(len--!=0)

11d++=s--;

12printf("%s",dest);

13return 0;

14}

答:

方法1

int main(){

char* src = "hello,world";

int len = strlen(src); ? //src源地址

char* dest = (char*)malloc(len+1); //要為\0分配一個空間

char* d = dest; ? ? //dest目的地址

char* s = &src[len-1]; //指向最后一個字符

while( len-- != 0 )

*d++=*s--;

*d = 0; //尾部要加\0

printf("%s\n",dest);

free(dest); // 使用完,應當釋放空間,以免造成內存匯泄露

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;

}

1.-1,2,7,28,,126請問28126中間那個數是什么?為什么?

第一題的答案應該是4^3-1=63

規律是n^3-1(n為偶數024)

n^3+1(n為奇數135)

答案:63


2.用兩個棧實現一個隊列的功能?要求給出算法和思路!

2個棧為A,B, 一開始均為空.


入隊:

將新元素push入棧A;


出隊:

(1)判斷棧B是否為空;

(2)如果不為空,則將棧A中所有元素依次pop出并push到棧B

(3)將棧B的棧頂元素pop出;


這樣實現的隊列入隊和出隊的平攤復雜度都還是O(1), 比上面的幾種方法要好。


3.c語言庫函數中將一個字符轉換成整型的函數是atool()嗎,這個函數的原型是什么?

函數名: 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);

}


2.對于一個頻繁使用的短小函數,C語言中應用什么實現,C++中應用什么實現?

c用宏定義,c++inline


3.直接鏈接兩個信令點的一組鏈路稱作什么?

PPP點到點連接


4.接入網用的是什么接口?

DL:接入網在接入這些網絡時,一般采用E1V.24V.352B1Q“U”接口,其余類型的接口使用較少。


5.voip都用了那些協議?voip網絡語音電話業務)

VoIP使用IETF會話發起協議(SIP)和實時傳輸協議(RTP)提交呼叫信令和語音消息與VoIP相關的網絡技術協議很多,常見的有控制實時數據流應用在IP網絡傳輸的RTP(實時傳輸協議)RTCP(實時傳輸控制協議)

有保證網絡QoS質量服務的RSVP(資源預留協議)IP different Service等,

還有傳統語音數字化編碼的一系列協議如G.711G.728G.723G.729等等。

目前VoIP技術最常用的話音建立和控制信令是H.323SIP(會話初始協議)


6.軟件測試都有那些種類?

黑盒:針對系統功能的測試 白合:測試函數功能,各函數接口


7.確定模塊的功能和模塊的接口是在軟件設計的哪個隊段完成的?

概要設計階段


8.enum string

{

x1,

x2,

x3=10,

x4,

x5,

}x;

x= 0x8010050x8010f4 ;


9.unsigned char *p1;

unsigned long *p2;

p1=(unsigned char *)0x801000;

p2=(unsigned long *)0x810000;

請問p1+5= 0x801005;

p2+5= 0x810014(5*4=20字節,16進制為0x14);


.選擇題:

1.Ethternet鏈接到Internet用到以下那個協議?

A.HDLC; B.ARP; C.UDP; D.TCP; E.ID

2.屬于網絡層協議的是:? ? ? C

A.TCP; B.IP; C.ICMP; D.X.25

3.Windows消息調度機制是:? C

A.指令隊列;B.指令堆棧;C.消息隊列;D.消息堆棧;

4.unsigned short hash(unsigned short key)

{

return (key>>)%256

}

請問hash(16),hash(256)的值分別是:

A.1.16;B.8.32;C.4.16;D.1.32


.找錯題:

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;

把循環語句內外換一下(DL:換一下好像還是有錯)


2.#define Max_CB 500

void LmiQueryCSmd(Struct MSgCB * pmsg)

{

unsigned char ucCmdNum;

......


for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)

{

......;

}

死循環


3.以下是求一個數的平方的程序,請找出錯誤:

#define SQUARE(a)((a)*(a))

int a=5;

int b;

b=SQUARE(a++);


4.typedef unsigned char BYTE

int examply_fun(BYTE gt_len; BYTE *gt_code)

{

BYTE *gt_buf;

gt_buf=(BYTE *)MALLOC(Max_GT_Length);

......

if(gt_len>Max_GT_Length)

{

return GT_Length_ERROR;

}

.......

}

.問答題:

1.IP Phone的原理是什么?

IPV6

2.TCP/IP通信建立的過程怎樣,端口有什么作用?

三次握手,確定是哪個應用程序使用該協議

3.1號信令和7號信令有什么區別,我國某前廣泛使用的是那一種?

七號信令網是電話網、智能網以及各種新業務的神經和支撐網,是通信網建設維護的重要部分。根據我國七號信令技術體制要求,我國七號信令網最終采用三級準直聯結構方式。

1號信令利用TS16傳送時。每個TS16負責傳送兩個話路的線路信令,TS16和話路有著固定的一一對應關系。

7號信令利用TS16來傳送時,只是將組成信令單元的若干個8位位組,依次插入TS16TS16并不知道傳送的內容

即信令和話路沒有固定關系,只不過利用TS16作為傳送信令的載體,時傳送信令消息的數據鏈路,

因此,選用哪個時隙做數據鏈路均可。 --- 這也是隨路信令和公共信道信令的一個本質區別。


4.列舉5種以上的電話新業務?




微軟亞洲技術中心的面試題!!!

1.進程和線程的差別。

線程是指進程內的一個執行單元,也是進程內的可調度實體.

與進程的區別:

(1)調度:線程作為調度和分配的基本單位,進程作為擁有資源的基本單位

(2)并發性:不僅進程之間可以并發執行,同一個進程的多個線程之間也可并發執行

(3)擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但可以訪問隸屬于

進程的資源.

(4)系統開銷:在創建或撤消進程時,由于系統都要為之分配和回收資源,導致系統的開銷

明顯大于創建或撤消線程時的開銷。

2.測試方法

人工測試:個人復查、抽查和會審

機器測試:黑盒測試和白盒測試0


2Heapstack的差別。

Heap是堆,stack是棧。

Stack的空間由操作系統自動分配/釋放,Heap上的空間手動分配/釋放。

Stack空間有限,Heap是很大的自由存儲區

C中的malloc函數分配的內存空間即在堆上,C++中對應的是new操作符。

程序在編譯期對變量和函數分配內存都在上進行,且程序運行過程中函數調用時參數的傳

遞也在棧上進行

3Windows下的內存是如何管理的?


4.介紹.Net.Net的安全性。


5.客戶端如何訪問.Net組件實現Web Service


6C/C++編譯器中虛表是如何完成的?


7.談談COM的線程模型。然后討論進程內/外組件的差別。


8.談談IA32下的分頁機制

小頁(4K)兩級分頁模式,大頁(4M)一級


9.給兩個變量,如何找出一個帶環單鏈表中是什么地方出現環的?

一個遞增一,一個遞增二,他們指向同一個接點時就是環出現的地方


10.在IA32中一共有多少種辦法從用戶態跳到內核態?

通過調用門,從ring3ring0,中斷從ring3ring0,進入vm86等等


11.如果只想讓程序有一個實例運行,不能運行兩個。像winamp(播放器)一樣,只能開一個窗口,怎樣實現?

用內存映射或全局原子(互斥變量)、查找窗口句柄..

FindWindow,互斥,寫標志到文件或注冊表,共享內存。. 

12.如何截取鍵盤的響應,讓所有的‘a’變成‘b’

鍵盤鉤子SetWindowsHookEx


 13ApartmentCOM中有什么用?為什么要引入?


 14.存儲過程是什么?有什么用?有什么優點?

我的理解就是一堆sql的集合,可以建立非常復雜的查詢,編譯運行,所以運行一次后,以后再運行速度比單獨執行SQL快很多


15Template有什么特點?什么時候用?


16.談談Windows DNA結構的特點和優點。



網絡編程中設計并發服務器,使用多進程 與 多線程 ,請問有什么區別?

1進程:子進程是父進程的復制品。子進程獲得父進程數據空間、堆和棧的復制品。

2線程:相對與進程而言,線程是一個更加接近與執行體的概念,它可以與同進程的其他

線程共享數據,但擁有自己的棧空間,擁有獨立的執行序列

兩者都可以提高程序的并發度,提高程序運行效率和響應時間。

線程和進程在使用上各有優缺點:線程執行開銷小,但不利于資源管理和保護;而進程正

相反。同時,線程適合于在SMP機器上運行,而進程則可以跨機器遷移。


思科

1. 用宏定義寫出swapxy

#define swap(x, y)\

x = x + y;\

y = x - y;\

x = x - y;


2.數組a[N],存放了1N-1個數,其中某個數重復一次。寫一個函數,找出被重復的數字

.時間復雜度必須為oN函數原型:

注意a[N]中存放的是1-N-1個數

int do_dup(int a[],int N)

{

? ? int temp[N]={0};

? ? for(int i=0;i<N;i++)

? ? ? if(temp[a[i]]!=0)

? ? ? ? ? return i;

}


3 一語句實現x是否為2的若干次冪的判斷

int i = 512;

cout << boolalpha << ((i & (i - 1)) ? false : true) << endl;

按位與運算符a&b,對b中為1的位如果a中也為1則保留,a中其余位全部置0,剩下的a即為結果

也可以理解為保留a中與b中位1對應的位,其余置0

其余按位運算符類似,將ab按位做相應運算,所得值即結果


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){

unsigned int _t = 0;

unsigned int _a = 1;

for(int i = 0; i < n; ++i){

_t |= _a;

_a = _a << 1;

}

//_t包含n1

_t = _t << p;//n1左移p

x ^= _t;

return x;

}


慧通:

什么是預編譯?何時需要預編譯:

1、總是使用不經常改動的大型代碼體。

2、程序由多個模塊組成,所有模塊都使用一組標準的包含文件和相同的編譯選項。在這

種情況下,可以將所有包含文件預編譯為一個預編譯頭。


char * const p;

char const * p

const char *p


上述三個有什么區別?

char * const p; //常量指針,p的值不可以修改

char const * p//指向常量的指針,指向的常量值不可以改

const char *p//char const *p


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是指針,它們指向相同的常量區域。



12. 以下代碼中的兩個sizeof用法有問題嗎?[C]

void UpperCase( char str[] ) // str 中的小寫字母轉換成大寫字母

{

for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )//sizeof(str)=4,為指針大小

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


一個32位的機器,該機器的指針是多少位?

指針是多少位只要看地址總線的位數就行了80386以后的機子都是32的數據總線。所以指針的位數就是4個字節了。

★★★★★★★★★★★

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],執行結果是25

&a+1不是首地址+1,系統會認為加一個a數組的偏移,是偏移了一個數組的大小(本例是5int

int *ptr=(int *)(&a+1);

ptr實際是&(a[5]),也就是a+5

原因如下:

&a是數組指針,其類型為 int (*)[5];而指針加1要根據指針類型加上一定的值,不同類型的指針+1之后增加的大小不同;a是長度為5int數組指針,所以要加 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].



1.請問以下代碼有什么問題:

int main()

{

char a;

char *str=&a;

strcpy(str,"hello");

printf(str);

return 0;

}

沒有為str分配內存空間,將會發生異常!

問題出在將一個字符串復制進一個字符變量指針所指地址。雖然可以正確輸出結果,但因

為越界進行內在讀寫而導致程序崩潰。


char* s="AAA";

printf("%s",s);

s[0]='B';

printf("%s",s);

有什么錯?

"AAA"是字符串常量。s是指針,指向這個字符串常量,所以聲明s的時候就有問題。

cosnt char* s="AAA";

然后又因為是常量,所以對是s[0]的賦值操作是不合法的。


1、寫一個標準宏,這個宏輸入兩個參數并返回較小的一個。

#define? Min(X, Y) ((X)>(Y)?(Y):(X));

//結尾沒有;------語法上并沒有限制宏后面必須沒有分號;

寫一個標準宏,這個宏輸入兩個參數并返回較大的一個

#define? MAX(X, Y) ((X)>(Y)?(X):(Y))


宏只是簡單的字符替換,這里是因為使用Min的地方通常會在后面加分號


2、嵌入式系統中經常要用到無限循環,你怎么用C編寫死循環。

while(1){}或者for(;;)


3、關鍵字static的作用是什么?

定義靜態變量


4、關鍵字const有什么含意?

表示常量不可以修改的變量


5、關鍵字volatile有什么含意?并舉出三個不同的例子?

(提示編譯器對象的值可能在編譯器未監測到的情況下改變。)

volatile關鍵字是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素更改,

比如:操作系統、硬件或者其它線程等。遇到這個關鍵字聲明的變量,編譯器對訪問該變量的代碼就不再進行優化,從而可以提供對特殊地址的穩定訪問。當要求使用volatile 聲明的變量的值的時候,系統總是重新從它所在的內存讀取數據,即使它前面的指令剛剛從該處讀取過數據。而且讀取的數據立刻被保存。volatile 指出 i是隨時可能發生變化的,每次使用它的時候必須從i的地址中讀取,因而編譯器生成的匯編代碼會重新從i的地址讀取數據放在b中。而優化做法是,由于編譯器發現兩次從i讀數據的代碼之間的代碼沒有對i進行過操作,它會自動把上次讀的數據放在b中。而不是重新從i里面讀。這樣以來,如果i是一個寄存器變量或者表示一個端口數據就容易出錯,所以說volatile可以保證對特殊地址的穩定訪問。 ? ? ? ? ? ? ? ? ? ? ? ? ?

vc6調試模式下沒有優化,關鍵字的作用看不出來,但發行模式則會起作用,故對于多線程共享的變量最好用volatile修飾


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.cc++中的struct有什么不同?

cc++struct的主要區別是c中的struct不可以含有成員函數,而c++中的struct可以。

c++structclass的主要區別在于默認的存取權限不同,struct默認為public,而class默認為private



4.#include <stdio.h>

#include <stdlib.h>

void getmemory(char *p)

{

p=(char *) malloc(100);

strcpy(p,"hello world");

}

int main( )

{

char *str=NULL;

getmemory(str);

printf("%s/n",str);

free(str);

return 0;

}

程序崩潰,getmemory中的malloc 不能返回動態內存, free()對str操作很危險


5.char szstr[10];

strcpy(szstr,"0123456789");

產生什么結果?為什么?

長度不一樣,會造成非法的OS


6.列舉幾種進程的同步機制,并比較其優缺點。

在主流的Linux內核中包含了幾乎所有現代的操作系統具有的同步機制,這些同步機制包括:原子操作信號量(semaphore讀寫信號量rw_semaphore)、spinlockBKL(Big Kernel Lock)rwlockbrlock(只包含在2.4內核中)、RCU(只包含在2.6內核中)和seqlock(只包含在2.6內核中)


7.進程之間通信的途徑

管道(pipe)和有名管道(named pipe)、消息隊列(mesage queue)、信號(signal)

信號量(semaphore)、共享存儲區(shared memory)、套接口(socket)


11.進程死鎖的原因

資源競爭及進程推進順序非法


12.死鎖的4個必要條件

互斥、請求保持、不可剝奪、環路


13.死鎖的處理

鴕鳥策略、預防策略、避免策略、檢測與解除死鎖

?? ? ? ?

15. 操作系統中進程調度策略有哪幾種?

FCFS(先來先服務),優先級,時間片輪轉,多級反饋


8.類的靜態成員和非靜態成員有何區別?

類的靜態成員每個類只有一個,非靜態成員每個對象一個


9.純虛函數如何定義?使用時應注意什么?

virtual void f()=0;

是接口,子類必須要實現


10.數組和鏈表的區別

數組:數據順序存儲,固定大小

鏈表:數據可以隨機存儲,大小可動態改變


12.ISO的七層模型是什么?tcp/udp是屬于哪一層?tcp/udp有何優缺點?

應用層

表示層

會話層

傳輸層

網絡層

數據鏈路層

物理層

tcp /udp屬于運輸層


TCP 服務提供了數據流傳輸、可靠性、有效流控制、全雙工操作和多路復用技術等。

TCP 不同, UDP 并不提供對 IP 協議的可靠機制、流控制以及錯誤恢復功能等。由于

UDP 比較簡單, UDP 頭包含很少的字節,比 TCP 負載消耗少。

TCP: 提供穩定的傳輸服務,有流量控制,缺點是包頭大,冗余性不好

UDP: 不提供穩定的服務,包頭小,開銷小



1(void *)ptr (*(void**))ptr的結果是否相同?其中ptr為同一個指針

.(void *)ptr (*(void**))ptr值是相同的


2int main()

{

int x=3;

printf("%d",x);

return 1;

}

問函數既然不會被其它函數調用,為什么要返回1

mian中,c標準認為0表示成功,非0表示錯誤。具體的值是某中具體出錯信息



1,要對絕對地址0x100000賦值,我們可以用(unsigned int*)0x100000 = 1234;

那么要是想讓程序跳轉到絕對地址是0x100000去執行,應該怎么做?

*((void (*)( ))0x100000 ) ( );

首先要將0x100000強制轉換成函數指針,

:

(void (*)())0x100000

然后再調用它:

*((void (*)())0x100000)();

typedef可以看得更直觀些:

typedef void(*)() voidFuncPtr;

*((voidFuncPtr)0x100000)();


2,已知一個數組table,用一個宏定義,求出數據的元素個數

#define NTBL

#define NTBL (sizeof(table)/sizeof(table[0]))


面試題: 線程與進程的區別和聯系? 線程是否具有相同的堆棧? dll是否有獨立的堆棧?


進程是死的,只是一些資源的集合,真正的程序執行都是線程來完成的,程序啟動的時候,操作系統就幫你創建了一個主線程。

每個線程有自己的堆棧。

DLL中有沒有獨立的堆棧,這個問題不好回答,或者說這個問題本身是否有問題。因為DLL

中的代碼是被某些線程所執行,只有線程擁有堆棧,如果DLL中的代碼是EXE中的線程所調用,那么這個時候是不是說這個DLL沒有自己獨立的堆棧?如果DLL中的代碼是由DLL自己創建的線程所執行,那么是不是說DLL有獨立的堆棧?


以上講的是堆棧,如果對于堆來說,每個DLL有自己的堆,所以如果是從DLL中動態分配的內存,最好是從DLL中刪除,如果你從DLL中分配內存,然后在EXE中,或者另外一個DLL中刪除,很有可能導致程序崩潰



unsigned short A = 10;

printf("~A = %u\n", ~A);

char c=128;

printf("c=%d\n",c);

輸出多少?并分析過程

第一題,~A 0xfffffff5,int值 為-11,但輸出的是uint。所以輸出4294967285

第二題,c0x80,輸出的是int,最高位為1,是負數,所以它的值就是0x00的補碼就是128,所以輸出-128

這兩道題都是在考察二進制向intuint轉換時的最高位處理。


分析下面的程序:

void GetMemory(char **p,int num)

{*p=(char *)malloc(num);

}int main()

{

char *str=NULL;

GetMemory(&str,100);

strcpy(str,"hello");

free(str);

if(str!=NULL)

{strcpy(str,"world");

}

printf("\n str is %s",str);

getchar();

}

問輸出結果是什么?? 輸出str is world

free 只是釋放的str指向的內存空間,它本身的值還是存在的.所以free之后,有一個好的習慣就是將str=NULL.此時str指向空間的內存已被回收,如果輸出語句之前還存在分配空間的操作的話,這段存儲空間是可能被重新分配給其他變量的,盡管這段程序確實是存在大大的問題(上面各位已經說得很清楚了),但是通常會打印出world來。

這是因為,進程中的內存管理一般不是由操作系統完成的,而是由庫函數自己完成的。

當你malloc一塊內存的時候,管理庫向操作系統申請一塊空間(可能會比你申請的大一些

),然后在這塊空間中記錄一些管理信息(一般是在你申請的內存前面一點),并將可用

內存的地址返回。但是釋放內存的時候,管理庫通常都不會將內存還給操作系統,因此你

是可以繼續訪問這塊地址的,只不過。。。。。。。。樓上都說過了,最好別這么干。

DL:C++中使用指針的引用也可以在其他函數內部申請空間,格式為int *&p,然后用法一樣,c不行



char a[10],strlen(a)為什么等于15?運行的結果


#include "stdio.h"

#include "string.h"


void main()

{


char aa[10];

printf("%d",strlen(aa));

}


sizeof()和初不初始化,沒有關系;

strlen()和初始化有關。



char (*str)[20];/*str是一個數組指針,即指向數組的指針.*/

char *str[20];/*str是一個指針數組,其元素為指針型數據.*/



1)給定結構struct A

{

char t:4;

char k:4;

unsigned short i:8;

unsigned long m;

};sizeof(A) = ?



給定結構struct A

{

char t:4; 4

char k:4; 4

unsigned short i:8; 8

unsigned long m; // 偏移2字節保證4字節對齊

}; // 8字節


2)下面的函數實現在一個數上加一個數,有什么錯誤?請改正。

int add_n ( int n )

{

static int i = 100;

i += n;

return i;

}

當你第二次調用時得不到正確的結果,難道你寫個函數就是為了調用一次?問題就出在 static



★★// 幫忙分析一下

#include<iostream.h>

#include <string.h>

#include <malloc.h>

#include <stdio.h>

#include <stdlib.h>

#include <memory.h>

typedef struct AA

{

int b1:5;

int b2:2;

}AA;

void main()

{

AA aa;

char cc[100];

strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");

memcpy(&aa,cc,sizeof(AA));

cout << aa.b1 <<endl;

cout << aa.b2 <<endl;

}

答案是 -16和1

首先sizeof(AA)的大小為4,b1b2分別占5bit2bit.

經過strcpymemcpy,aa4個字節所存放的值是:

0,1,2,3ASC碼,即00110000,00110001,00110010,00110011

所以,最后一步:顯示的是這4個字節的前5位,和之后的2位

分別為:10000,01

因為int是有正負之分  所以:答案是-16和1


求函數返回值,輸入x=9999;

int func x

{

int countx = 0;

while ( x )

{

countx ++;

x = x&(x-1);

}

return countx;

}

結果呢? 8


知道了這是統計9999的二進制數值中有多少個1的函數,且有

99999×102451225615


9×1024中含有1的個數為2

512中含有1的個數為1

256中含有1的個數為1

15中含有1的個數為4

故共有1的個數為8,結果為8

1000 - 1 = 0111,正好是原數取反。這就是原理。

用這種方法來求1的個數是很效率很高的。

不必去一個一個地移位。循環次數最少。


★★int a,b,c 請寫函數實現C=a+b ,不可以改變數據類型,如將c改為long int,關鍵是如何處理溢出問題

bool add (int a, int b,int *c)

{

*c=a+b;

return (a>0 && b>0 &&(*c<a || *c<b) || (a<0 && b<0 &&(*c>a || *c>b)));

}


分析:

struct bit

{ int a:3;

int b:2;

int c:3;

};

int main()

{

bit s;

char *c=(char*)&s;

cout<<sizeof(bit)<<endl;

*c=0x99;

cout << s.a <<endl <<s.b<<endl<<s.c<<endl;

int a=-1;

printf("%x",a);

return 0;

}

輸出為什么是

4? ? ? ? 1 ? ? ? ? -1 ? ? ? ? -4 ? ? ? ? ? ? ? ffffffff

因為0x99在內存中表示為 100 11 001 , a = 001, b = 11, c = 100

c為有符合數時, c = 100, 最高1為表示c為負數,負數在計算機用補碼表示,所以c =

-4;同理

b = -1;

c為有符合數時, c = 100,c = 4,同理 b = 3



位域 :

有些信息在存儲時,并不需要占用一個完整的字節, 而只需占幾個或一個二進制位。例如

在存放一個開關量時,只有01 兩種狀態, 用一位二進位即可。為了節省存儲空間,并

使處理簡便,C語言又提供了一種數據結構,稱為位域位段。所謂位域

把一個字節中的二進位劃分為幾個不同的區域, 并說明每個區域的位數。每個域有一個域

名,允許在程序中按域名進行操作。 這樣就可以把幾個不同的對象用一個字節的二進制位

域來表示。一、位域的定義和位域變量的說明位域定義與結構定義相仿,其形式為:

struct 位域結構名

{ 位域列表 };

其中位域列表的形式為: 類型說明符 位域名:位域長度

例如:

struct bs

{

int a:8;

int b:2;

int c:6;

};

位域變量的說明與結構變量說明的方式相同。 可采用先定義后說明,同時定義說明或者直

接說明這三種方式。例如:

struct bs

{

int a:8;

int b:2;

int c:6;

}data;

說明databs變量,共占兩個字節。其中位域a8位,位域b2位,位域c6位。對于位域的定義尚有以下幾點說明:


1. 一個位域必須存儲在同一個字節中,不能跨兩個字節。如一個字節所剩空間不夠存放另

一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。例如:


struct bs

{

unsigned a:4

unsigned :0 /*空域*/

unsigned b:4 /*從下一單元開始存放*/

unsigned c:4

}

在這個位域定義中,a占第一字節的4位,后4位填0表示不使用,b從第二字節開始,占用4位,c占用4位。


2. 由于位域不允許跨兩個字節,因此位域的長度不能大于一個字節的長度,也就是說不能

超過8位二進位。


  • 3. 位域可以無位域名,這時它只用來作填充或調整位置。無名的位域是不能使用的。

例如

struct k

{

int a:1

int :2? /*2位不能使用*/

int b:3

int c:2

};

從以上分析可以看出,位域在本質上就是一種結構類型, 不過其成員是按二進位分配的。



二、位域的使用位域的使用和結構成員的使用相同,其一般形式為: 位域變量名&#8226;

位域名 位域允許用各種格式輸出。

main(){

struct bs

{

unsigned a:1;

unsigned b:3;

unsigned c:4;

} bit,*pbit;

bit.a=1;

bit.b=7;

bit.c=15;

pri


改錯:

#include <stdio.h>


int main(void) {


int **p;

int arr[100];


p = &arr;


return 0;

}

解答:

搞錯了,是指針類型不同,

int **p; //二級指針

&arr; //得到的是指向第一維為100的數組的指針

#include <stdio.h>

int main(void) {

int **p, *q;

int arr[100];

q = arr;

p = &q;

return 0;

}



下面這個程序執行后會有什么錯誤或者效果:

#define MAX 255

int main()

{

unsigned char A[MAX],i;//i被定義為unsigned char

for (i=0;i<=MAX;i++)

A[i]=i;

}

解答:死循環加數組越界訪問(C/C++不進行數組越界檢查)

MAX=255

數組A的下標范圍為:0..MAX-1,這是其一..

其二.i循環到255,循環內執行:

A[255]=255;

這句本身沒有問題..但是返回for (i=0;i<=MAX;i++)語句時,

由于unsigned char的取值范圍在(0..255),i++以后i又為0..無限循環下去.


struct name1{

char str;

short x;

int num;

}


struct name2{

char str;

int num;

short x;

}


sizeof(struct name1)=8,sizeof(struct name2)=12


在第二個結構中,為保證num按四個字節對齊,char后必須留出3字節的空間;同時為保證整個結構的自然對齊(這里是4字節對齊),在x后還要補齊2個字節,這樣就是12字節。


什么情況下需要對齊 什么情況下不需要對齊???

intel

A.c B.c兩個c文件中使用了兩個相同名字的static變量,編譯的時候會不會有問題?這兩

static變量會保存到哪里(棧還是堆或者其他的)?

static的全局變量,表明這個變量僅在本模塊中有意義,不會影響其他模塊。

他們都放在數據區,但是編譯器對他們的命名是不同的。

如果要使變量在其他模塊也有意義的話,需要使用extern(外部聲明)關鍵字。


struct s1

{

int i: 8;

int j: 4;

int a: 3;

double b;

};


struct s2

{

int i: 8;

int j: 4;

double b;

int a:3;

};


printf("sizeof(s1)= %d\n", sizeof(s1));

printf("sizeof(s2)= %d\n", sizeof(s2));

result: 16, 24


第一個struct s1

{

int i: 8;

int j: 4;

int a: 3;

double b;

};

★★理論上是這樣的,首先是i在相對0的位置,占8位一個字節,然后,j就在相對一個字節的位置,由于一個位置的字節數是4位的倍數,因此不用對齊,就放在那里了,然后是a,要在3位的倍數關系的位置上,因此要移一位,在15位的位置上放下,目前總共是18位,折算過來是2字節2位的樣子,由于double8字節的,因此要在相對0要是8個字節的位置上放下,因此從18位開始到8個字節之間的位置被忽略,直接放在8字節的位置了,因此,總共是16字節。


第二個最后會對照是不是結構體內最大數據的倍數,不是的話,會補成是最大數據的倍數


1)讀文件file1.txt的內容(例如):

12

34

56

輸出到file2.txt

56

34

12

(逆序)

2)輸出和為一個給定整數的所有組合

例如n=5

5=1+45=2+3(相加的數不能重復)

則輸出

1423

望高手賜教!!


第一題,注意可增長數組的應用.

#include <stdio.h>

#include <stdlib.h>


int main(void)

{

int MAX = 10;

int *a = (int *)malloc(MAX * sizeof(int));

int *b;


FILE *fp1;

FILE *fp2;


fp1 = fopen("a.txt","r");

if(fp1 == NULL)

{printf("error1");

exit(-1);

}


fp2 = fopen("b.txt","w");

if(fp2 == NULL)

{printf("error2");

exit(-1);

}


int i = 0;

int j = 0;


while(fscanf(fp1,"%d",&a[i]) != EOF)

{

i++;

j++;

if(i >= MAX)

{

MAX = 2 * MAX;

b = (int*)realloc(a,MAX * sizeof(int));

if(b == NULL)

{

printf("error3");

exit(-1);

}

a = b;

}

}


for(;--j >= 0;)

fprintf(fp2,"%d\n",a[j]);


fclose(fp1);

fclose(fp2);


return 0;



}


第二題.

#include <stdio.h>


int main(void)

{

unsigned long int i,j,k;


printf("please input the number\n");

scanf("%d",&i);

if( i % 2 == 0)

j = i / 2;

else

j = i / 2 + 1;


printf("The result is \n");

for(k = 0; k < j; k++)

printf("%d = %d + %d\n",i,k,i - k);

return 0;

}


#include <stdio.h>

void main()

{

unsigned long int a,i=1;

scanf("%d",&a);

if(a%2==0)

{

for(i=1;i<a/2;i++)

printf("%d",a,a-i);

}

else

for(i=1;i<=a/2;i++)

printf(" %d, %d",i,a-i);

}


兄弟,這樣的題目若是做不出來實在是有些不應該, 給你一個遞歸反向輸出字符串的例子,

可謂是反序的經典例程.


void inverse(char *p)

{

if( *p = = '\0' )

return;

inverse( p+1 );

printf( "%c", *p );

}


int main(int argc, char *argv[])

{

inverse("abc\0");


return 0;

}


借簽了樓上的遞規反向輸出

#include <stdio.h>

void test(FILE *fread, FILE *fwrite)

{

char buf[1024] = {0};

if (!fgets(buf, sizeof(buf), fread))

return;

test( fread, fwrite );

fputs(buf, fwrite);

}

int main(int argc, char *argv[])

{

FILE *fr = NULL;

FILE *fw = NULL;

fr = fopen("data", "rb");

fw = fopen("dataout", "wb");

test(fr, fw);

fclose(fr);

fclose(fw);

return 0;

}


在對齊為4的情況下

struct BBB

{

long num

char *name;

short int data;

char ha;

short ba[5];

}*p;

p=0x1000000;

p+0x200=____;

(Ulong)p+0x200=____;

(char*)p+0x200=____;



解答:假設在32CPU上,

sizeof(long) = 4 bytes

sizeof(char *) = 4 bytes

sizeof(short int) = sizeof(short) = 2 bytes

sizeof(char) = 1 bytes


由于是4字節對齊,

sizeof(struct BBB) = sizeof(*p)

= 4 + 4 + 2 + 1 + 1/*補齊*/ + 2*5 + 2/*補齊*/ = 24 bytes (Dev-C++驗證)


p=0x1000000;

p+0x200=____;

= 0x1000000 + 0x200*24


(Ulong)p+0x200=____;

= 0x1000000 + 0x200


(char*)p+0x200=____;

= 0x1000000 + 0x200*4


你可以參考一下指針運算的細節



寫一段程序,找出數組中第k大小的數,輸出數所在的位置。例如{24347}中,第

一大的數是7,位置在4。第二大、第三大的數都是4,位置在13隨便輸出哪一個均可。函

數接口為:int find_orderk(const int* narry,const int n,const int k)

要求算法復雜度不能是O(n^2

謝謝!

可以先用快速排序進行排序,其中用另外一個進行地址查找

代碼如下,在VC++6.0運行通過。給分吧^-^


//快速排序


#include<iostream>


usingnamespacestd;


intPartition (int*L,intlow,int high)

{

inttemp = L[low];

intpt = L[low];


while (low < high)

{

while (low < high && L[high] >= pt)

--high;

L[low] = L[high];

while (low < high && L[low] <= pt)

++low;

L[low] = temp;

}

L[low] = temp;


returnlow;

}


voidQSort (int*L,intlow,int high)

{

if (low < high)

{

intpl = Partition (L,low,high);


QSort (L,low,pl - 1);

QSort (L,pl + 1,high);

}

}


Int main ()

{

Int narry[100],addr[100];

Int sum = 1,t;


cout << "Input number:" << endl;

cin >> t;


while (t != -1)

{

narry[sum] = t;

addr[sum - 1] = t;

sum++;


cin >> t;

}


sum -= 1;

QSort (narry,1,sum);


for (int i = 1; i <= sum;i++)

cout << narry[i] << '\t';

cout << endl;


intk;

cout << "Please input place you want:" << endl;

cin >> k;


intaa = 1;

intkk = 0;

for (;;)

{

if (aa == k)

break;

if (narry[kk] != narry[kk + 1])

{

aa += 1;

kk++;

}


}


cout << "The NO." << k << "number is:" << narry[sum - kk] << endl;

cout << "And it's place is:" ;

for (i = 0;i < sum;i++)

{

if (addr[i] == narry[sum - kk])

cout << i << '\t';

}



return0;

}


1、找錯

Void test1()

{

char string[10];

char* str1="0123456789";

strcpy(string, str1);// 溢出,應該包括一個存放'\0'的字符string[11]

}



Void test2()

{

char string[10], str1[10];

for(I=0; I<10;I++)

{

str1[i] ='a';

}

strcpy(string, str1);// Ii沒有聲明。

}


Void test3(char* str1)

{

char string[10];

if(strlen(str1)<=10)// 改成<10,字符溢出,將strlen改為sizeof也可以

{

strcpy(string, str1);

}

}


2.

void g(int**);

int main()

{

int line[10],i;

int *p=line; //p是地址的地址

for (i=0;i<10;i++)

{

*p=i;

g(&p);//數組對應的值加1

}

for(i=0;i<10;i++)

printf("%d\n",line[i]);

return 0;

}


void g(int**p)

{

(**p)++;

(*p)++;// 無效

}

輸出:

1

2

3

4

5

6

7

8

9

10

3. 寫出程序運行結果


int sum(int a)

{

auto int c=0;

static int b=3;

c+=1;

b+=2;

return(a+b+c);

}


void main()

{

int I;

int a=2;

for(I=0;I<5;I++)

{

printf("%d,", sum(a));

}

}

// static會保存上次結果,記住這一點,剩下的自己寫

輸出:8,10,12,14,16,



4.


int func(int a)

{

int b;

switch(a)

{

case 1: 30;

case 2: 20;

case 3: 16;

default: 0

}

return b;

}

func(1)=?

// b定義后就沒有賦值。


5:

int a[3];a[0]=0; a[1]=1; a[2]=2;

int *p, *q;

p=a;

q=&a[2];

a[q-p]=a[2]

解釋:指針一次移動一個int但計數為1


今天早上的面試題9道,比較難,向牛人請教,國內的一牛公司,坐落在北京北四環某大廈

1、線形表ab為兩個有序升序的線形表,編寫一程序,使兩個有序線形表合并成一個有序

升序線形表h

答案在清華大學 嚴蔚敏《數據結構第二版》第二章例題,數據結構當中,這個叫做:

路歸并排序

Linklist *unio(Linklist *p,Linklist *q){

linklist *R,*pa,*qa,*ra;

pa=p;

qa=q;

R=ra=p;

while(pa->next!=NULL&&qa->next!=NULL){

if(pa->data>qa->data){

ra->next=qa;

qa=qa->next;

}

else{

ra->next=pa;

pa=pa->next;

}

}

if(pa->next!=NULL)

ra->next=pa;

if(qa->next!=NULL)

ra->next==qa;

return R;

}

2、運用四色定理,為N個局域舉行配色,顏色為1234四種,另有數組adj[][N],如

adj[i][j]=1則表示i區域與j區域相鄰,數組color[N],如color[i]=1,表示i區域的顏色為

1號顏色。

四色填充

3、用遞歸算法判斷數組a[N]是否為一個遞增數組。

遞歸的方法,記錄當前最大的,并且判斷當前的是否比這個還大,大則繼續,否則返回false結束:

bool fun( int a[], int n )

{

if( n= =1 )

return true;

if( n= =2 )

return a[n-1] >= a[n-2];

return fun( a,n-1) && ( a[n-1] >= a[n-2] );

}


4、編寫算法,從10億個浮點數當中,選出其中最大的10000個。

用外部排序,在《數據結構》書上有

《計算方法導論》在找到第n大的數的算法上加工


5、編寫一unix程序,防止僵尸進程的出現.


同學的4道面試題,應聘的職位是搜索引擎工程師,后兩道超級難,(希望大家多給一些算

發)

1.給兩個數組和他們的大小,還有一動態開辟的內存,求交集,把交集放到動態內存dong

tai,并且返回交集個數

long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])

2.單連表的建立,把'a'--'z'26個字母插入到連表中,并且倒敘,還要打印!

方法1

typedef struct val

{ int date_1;

struct val *next;

}*p;


void main(void)

{ char c;


for(c=122;c>=97;c--)

{ p.date=c;

p=p->next;

}


p.next=NULL;

}

}


方法2

node *p = NULL;

node *q = NULL;


node *head = (node*)malloc(sizeof(node));

head->data = ' ';head->next=NULL;


node *first = (node*)malloc(sizeof(node));

first->data = 'a';first->next=NULL;head->next = first;

p = first;


int longth = 'z' - 'b';

int i=0;

while ( i<=longth )

{

node *temp = (node*)malloc(sizeof(node));

temp->data = 'b'+i;temp->next=NULL;q=temp;


head->next = temp; temp->next=p;p=q;

i++;

}


print(head);


3.可怕的題目終于來了

象搜索的輸入信息是一個字符串,統計300萬輸入信息中的最熱門的前十條,我們每次輸入

的一個字符串為不超過255byte,內存使用只有1G,

請描述思想,寫出算發(c語言),空間和時間復雜度,

4.國內的一些帖吧,如baidu,有幾十萬個主題,假設每一個主題都有上億的跟帖子,怎么

樣設計這個系統速度最好,請描述思想,寫出算發(c語言),空間和時間復雜度,



#include string.h

main(void)

{ char *src="hello,world";

char *dest=NULL;

dest=(char *)malloc(strlen(src));

int len=strlen(str);

char *d=dest;

char *s=src[len];

while(len--!=0)

d++=s--;

printf("%s",dest);

}


找出錯誤!!

#include "string.h"

#include "stdio.h"

#include "malloc.h"

main(void)

{

char *src="hello,world";

char *dest=NULL;

dest=(char *)malloc(sizeof(char)*(strlen(src)+1));

int len=strlen(src);

char *d=dest;

char *s=src+len-1;

while(len--!=0)

*d++=*s--;

*d='\0';

printf("%s",dest);

}


1. 簡述一個Linux驅動程序的主要流程與功能。


2. 請列舉一個軟件中,時間換空間或者空間換時間的例子。

void swap(int a,int b)

{

int c; c=a;a=b;b=a;

}

--->空優

void swap(int a,int b)

{

a=a+b;b=a-b;a=a-b;

}


6. 請問一下程序將輸出什么結果?

char *RetMenory(void)

{

char p[] = “hellow world”;

return p;

}

void Test(void)

{

char *str = NULL;

str = RetMemory();

printf(str);

}

RetMenory執行完畢,p資源被回收,指向未知地址。返回地址,str的內容應是不可預測的, 打印的應該是str的地址



寫一個函數,它的原形是int continumax(char *outputstr,char *intputstr)

功能:

在字符串中找出連續最長的數字串,并把這個串的長度返回,并把這個最長數字串付給其

中一個函數參數outputstr所指內存。例如:"abcd12345ed125ss123456789"的首地址傳給

intputstr后,函數將返回9outputstr所指的值為123456789

int continumax(char *outputstr, char *inputstr)

{

char *in = inputstr, *out = outputstr, *temp, *final;

int count = 0, maxlen = 0;


while( *in != '\0' )

{

if( *in > 47 && *in < 58 )

{

for(temp = in; *in > 47 && *in < 58 ; in++ )

count++;

}

else

in++;


if( maxlen < count )

{

maxlen = count;

count = 0;

final = temp;

}

}

for(int i = 0; i < maxlen; i++)

{

*out = *final;

out++;

final++;

}

*out = '\0';

return maxlen;

}


不用庫函數,C語言實現將一整型數字轉化為字符串

方法1

int getlen(char *s){

int n;

for(n = 0; *s != '\0'; s++)

n++;

return n;

}

void reverse(char s[])

{

int c,i,j;

for(i = 0,j = getlen(s) - 1; i < j; i++,j--){

c = s[i];

s[i] = s[j];

s[j] = c;

}

}

void itoa(int n,char s[])

{

int i,sign;

if((sign = n) < 0)

n = -n;

i = 0;

do{/*以反序生成數字*/

s[i++] = n%10 + '0';/*get next number*/

}while((n /= 10) > 0);/*delete the number*/


if(sign < 0)

s[i++] = '-';


s[i] = '\0';

reverse(s);

}


方法2:

#include <iostream>

using namespace std;


void itochar(int num);


void itochar(int num)

{

int i = 0;

int j ;

char stra[10];

char strb[10];

while ( num )

{

stra[i++]=num%10+48;

num=num/10;

}

stra[i] = '\0';

for( j=0; j < i; j++)

{

strb[j] = stra[i-j-1];

}

strb[j] = '\0';

cout<<strb<<endl;


}

int main()

{

int num;

cin>>num;

itochar(num);

return 0;

}


前幾天面試,有一題想不明白,請教大家!

typedef struct

{

int a:2;

int b:2;

int c:1;

}test;


test t;

t.a = 1;

t.b = 3;

t.c = 1;


printf("%d",t.a);

printf("%d",t.b);

printf("%d",t.c);


謝謝!

t.a01,輸出就是1

t.b11,輸出就是-1

t.c1,輸出也是-1

3個都是有符號數int嘛。

這是位擴展問題

01

11

1

編譯器進行符號擴展



求組合數: 求n個數(1....n)中k個數的組合....

如:combination(5,3)

要求輸出:543542541532531521432431421321

#include<stdio.h>


int pop(int *);

int push(int );

void combination(int ,int );


int stack[3]={0};

top=-1;


int main()

{

int n,m;

printf("Input two numbers:\n");

while( (2!=scanf("%d%*c%d",&n,&m)) )

{

fflush(stdin);

printf("Input error! Again:\n");

}

combination(n,m);

printf("\n");

}

void combination(int m,int n)

{

int temp=m;

push(temp);

while(1)

{

if(1==temp)

{

if(pop(&temp)&&stack[0]==n) //當棧底元素彈出&&為可能取的最小值,循環退出

break;

}

else if( push(--temp))

{

printf("%d%d%d ",stack[0],stack[1],stack[2]);//§&auml;¨ì¤@?

pop(&temp);

}

}

}

int push(int i)

{

stack[++top]=i;

if(top<2)

return 0;

else

return 1;

}

int pop(int *i)

{

*i=stack[top--];

if(top>=0)

return 0;

else

return 1;

}


1、用指針的方法,將字符串“ABCD1234efgh”前后對調顯示

#include <stdio.h>

#include <string.h>

int main()

{

char str[] = "ABCD1234efgh";

int length = strlen(str);

char * p1 = str;

char * p2 = str + length - 1;

while(p1 < p2)

{

char c = *p1;

*p1 = *p2;

*p2 = c;

++p1;

--p2;

}

printf("str now is %s\n",str);

return 0;

}

2、有一分數序列:1/2,1/4,1/6,1/8……,用函數調用的方法,求此數列前20項的和

#include <stdio.h>

double getValue()

{

double result = 0;

int i = 2;

while(i < 42)

{

result += 1.0 / i;//一定要使用1.0做除數,不能用1,否則結果將自動轉化成整數,即

0.000000

i += 2;

}

return result;

}

int main()

{

printf("result is %f\n", getValue());

system("pause");

return 0;

}




Top


?回復人:free131(白日?做夢!) ( ) 信譽:100 2006-4-17 10:18:33 得分:0



?

有一個數組a[1000]存放0--1000;要求每隔二個數刪掉一個數,到末尾時循環至開頭繼續進

行,求最后一個被刪掉的數的原始下標位置。

7個數為例:

{0,1,2,3,4,5,6,7} 0-->1-->2(刪除)-->3-->4-->5(刪除)-->6-->7-->0(刪除),如此

循環直到最后一個數被刪除。

方法1:數組

#include <iostream>

using namespace std;

#define null 1000


int main()

{

int arr[1000];

for (int i=0;i<1000;++i)

arr[i]=i;

int j=0;

int count=0;

while(count<999)

{

while(arr[j%1000]==null)

j=(++j)%1000;

j=(++j)%1000;

while(arr[j%1000]==null)

j=(++j)%1000;

j=(++j)%1000;

while(arr[j%1000]==null)

j=(++j)%1000;

arr[j]=null;

++count;

}

while(arr[j]==null)

j=(++j)%1000;


cout<<j<<endl;

return 0;

}


方法2:鏈表

#include<iostream>

using namespace std;

#define null 0

struct node

{

int data;

node* next;

};

int main()

{

node* head=new node;

head->data=0;

head->next=null;

node* p=head;

for(int i=1;i<1000;i++)

{

node* tmp=new node;

tmp->data=i;

tmp->next=null;

head->next=tmp;

head=head->next;

}

head->next=p;

while(p!=p->next)

{

p->next->next=p->next->next->next;

p=p->next->next;

}

cout<<p->data;

return 0;

}

方法3:通用算法

#include <stdio.h>

#define MAXLINE 1000 //元素個數

/*

MAXLINE 元素個數

a[] 元素數組

R[] 指針場

suffix 下標

index 返回最后的下標序號

values 返回最后的下標對應的值

start 從第幾個開始

K 間隔

*/

int find_n(int a[],int R[],int K,int& index,int& values,int s=0) {

int suffix;

int front_node,current_node;

suffix=0;

if(s==0) {

current_node=0;

front_node=MAXLINE-1;

}

else {

current_node=s;

front_node=s-1;

}

while(R[front_node]!=front_node) {

printf("%d\n",a[current_node]);

R[front_node]=R[current_node];

if(K==1) {

current_node=R[front_node];

continue;

}

for(int i=0;i<K;i++){

front_node=R[front_node];

}

current_node=R[front_node];

}

index=front_node;

values=a[front_node];


return 0;

}

int main(void) {

int a[MAXLINE],R[MAXLINE],suffix,index,values,start,i,K;

suffix=index=values=start=0;

K=2;


for(i=0;i<MAXLINE;i++) {

a[i]=i;

R[i]=i+1;

}

R[i-1]=0;

find_n(a,R,K,index,values,2);

printf("the value is %d,%d\n",index,values);

return 0;

}


試題:

void test2()

{

char string[10], str1[10];

int i;

for(i=0; i<10; i++)

{

str1[i] = 'a';

}

strcpy( string, str1 );

}



解答:對試題2,如果面試者指出字符數組str1不能在數組內結束可以給3分;如果面試者

指出strcpy(string, str1)調用使得從str1內存起復制到string內存起所復制的字節數具有不確定性可以給7分,在此基礎上指出庫函數strcpy工作方式的給10分;

str1不能在數組內結束:因為str1的存儲為:{a,a,a,a,a,a,a,a,a,a},沒有'\0'(字符串結

束符),所以不能結束

strcpy( char *s1,char *s2)他的工作原理是,掃描s2指向的內存,逐個字符付到s1所指

向的內存,直到碰到'\0',因為str1結尾沒有'\0',所以具有不確定性,不知道他后面還會

付什么東東。

(把字符數組str1中的字符串拷貝到字符數組str2中。串結束標志“\0”也一同拷貝。)


正確應如下

void test2()

{

char string[10], str1[10];

int i;

for(i=0; i<9; i++)

{

str1[i] = 'a'+i; //abcdefghi賦值給字符數組

}

str[i]='\0';//加上結束符

strcpy( string, str1 );

}


第二個code題是實現strcmp

int StrCmp(const char *str1, const char *str2)

做是做對了,沒有抄稿,比較亂

int StrCmp(const char *str1, const char *str2)

{

assert(str1 && srt2);

while (*str1 && *str2 && *str1 == *str2) {

str1++, str2++;

}

if (*str1 && *str2)

return (*str1-*str2);

elseif (*str1 && *str2==0)

return 1;

elseif (*str1 = = 0 && *str2)

return -1;

else

return 0;

}


int StrCmp(const char *str1, const char *str2)

{

//省略判斷空指針(自己保證)

while(*str1 && *str1++ = = *str2++);

return *str1-*str2;

}

第三個code題是實現子串定位

int FindSubStr(const char *MainStr, const char *SubStr)

做是做對了,沒有抄搞,比較亂

int MyStrstr(const char* MainStr, const char* SubStr)

{

const char *p;

const char *q;

const char * u = MainStr;


//assert((MainStr!=NULL)&&( SubStr!=NULL));//用斷言對輸入進行判斷

while(*MainStr) //內部進行遞增

{

p = MainStr;

q = SubStr;

while(*q && *p && *p++ == *q++);

if(!*q )

{

return MainStr - u +1 ;//MainStr指向當前起始位,u指向

}

MainStr ++;

}

return -1;

}


分析:

int arr[] = {6,7,8,9,10};

int *ptr = arr;

*(ptr++)+=123;

printf(“ %d %d ”, *ptr, *(++ptr));


輸出:8 8


過程:對于*(ptr++)+=123;先做加法6+123,然后++,指針指向7;對于printf(“ %d %d

”, *ptr, *(++ptr));從后往前執行,指針先++,指向8,然后輸出8,緊接著再輸出8







華為全套完整試題


高級題

6、已知一個單向鏈表的頭,請寫出刪除其某一個結點的算法,要求,先找到此結點,然后

刪除。

slnodetype *Delete(slnodetype *Head,int key){}if(Head->number==key)

{

Head=Pointer->next;

free(Pointer);

break;

}

Back = Pointer;

Pointer=Pointer->next;

if(Pointer->number==key)

{

Back->next=Pointer->next;

free(Pointer);

break;

}

void delete(Node* p)

{

if(Head = Node)


while(p)

}


有一個16位的整數,每4位為一個數,寫函數求他們的和。

解釋:

整數1101010110110111

1101+0101+1011+0111

感覺應該不難,當時對題理解的不是很清楚,所以寫了一個函數,也不知道對不對。

疑問:

既然是16位的整數,11010101101101112進制的,那么函數參數怎么定義呢,請大蝦指教

答案:用十進制做參數,計算時按二進制考慮。

/* 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,2,....一直到n的無序數組,求排序算法,并且要求時間復雜度為O(n),空間復雜度O(1)

,使用交換,而且一次只能交換兩個數.華為

#include<iostream.h>


int main()

{

int a[] = {10,6,9,5,2,8,4,7,1,3};

int len = sizeof(a) / sizeof(int);

int temp;


for(int i = 0; i < len; )

{

temp = a[a[i] - 1];

a[a[i] - 1] = a[i];

a[i] = temp;


if ( a[i] == i + 1)

i++;

}

for (int j = 0; j < len; j++)

cout<<a[j]<<",";


return 0;

}


慧通

1 寫出程序把一個鏈表中的節點順序倒排

typedef struct linknode

{

int data;

struct linknode *next;

}node;

//將一個鏈表逆置

node *reverse(node *head)

{

node *p,*q,*r;

p=head;

q=p->next;

while(q!=NULL)

{

r=q->next;

q->next=p;

p=q;

q=r;

}


head->next=NULL;

head=p;

return head;

}


2 寫出程序刪除鏈表中的所有節點

void del_all(node *head)

{

node *p;

while(head!=NULL)

{

p=head->next;

free(head);

head=p;

}

cout<<"釋放空間成功!"<<endl;

}


3兩個字符串,s,t;t字符串插入到s字符串中,s字符串有足夠的空間存放t字符串

void insert(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';

}



分析下面的代碼:

char *a = "hello";

char *b = "hello";

if(a= =b)

printf("YES");

else

printf("NO");


這個簡單的面試題目,我選輸出 no(對比的應該是指針地址吧),可在VCYES CNOlz的呢,是一個常量字符串。位于靜態存儲區,它在程序生命期內恒定不變。如果編譯器優化的話,會有可能ab同時指向同一個hello的。則地址相同。如果編譯器沒有優化,那么就是兩個不同的地址,則不同


寫一個函數,功能:完成內存之間的拷貝

memcpy source code:

270 void* memcpy( void *dst, const void *src, unsigned int len )

271 {

272 register char *d;

273 register char *s;

27

275 if (len == 0)

276 return dst;

277

278 if (is_overlap(dst, src, len, len))

279 complain3("memcpy", dst, src, len);

280

281 if ( dst > src ) {

282 d = (char *)dst + len - 1;

283 s = (char *)src + len - 1;

284 while ( len >= 4 ) {

285 *d-- = *s--;

286 *d-- = *s--;

287 *d-- = *s--;

288 *d-- = *s--;

289 len -= 4;

290 }

291 while ( len-- ) {

292 *d-- = *s--;

293 }

294 } else if ( dst < src ) {

295 d = (char *)dst;

296 s = (char *)src;

297 while ( len >= 4 ) {

298 *d++ = *s++;

299 *d++ = *s++;

300 *d++ = *s++;

301 *d++ = *s++;

302 len -= 4;

303 }

304 while ( len-- ) {

305 *d++ = *s++;

306 }

307 }

308 return dst;

309 }

公司考試這種題目主要考你編寫的代碼是否考慮到各種情況,是否安全(不會溢出)

各種情況包括:

1、參數是指針,檢查指針是否有效

2、檢查復制的源目標和目的地是否為同一個,若為同一個,則直接跳出

3、讀寫權限檢查

4、安全檢查,是否會溢出

memcpy拷貝一塊內存,內存的大小你告訴它

strcpy是字符串拷貝,遇到'\0'結束


/* memcpy ─── 拷貝不重疊的內存塊 */

void memcpy(void* pvTo, void* pvFrom, size_t size)

{

void* pbTo = (byte*)pvTo;

void* pbFrom = (byte*)pvFrom;

ASSERT(pvTo != NULL && pvFrom != NULL); //檢查輸入指針的有效性

ASSERT(pbTo>=pbFrom+size || pbFrom>=pbTo+size);//檢查兩個指針指向的內存是否重疊


while(size-->0)

*pbTo++ == *pbFrom++;

return(pvTo);

}



華為面試題:怎么判斷鏈表中是否有環?

bool CircleInList(Link* pHead)

{

if(pHead = = NULL || pHead->next = = NULL)//無節點或只有一個節點并且無自環

return (false);

if(pHead->next = = pHead)//自環

return (true);

Link *pTemp1 = pHead;//step 1

Link *pTemp = pHead->next;//step 2

while(pTemp != pTemp1 && pTemp != NULL && pTemp->next != NULL)

{

pTemp1 = pTemp1->next;

pTemp = pTemp->next->next;

}

if(pTemp = = pTemp1)

return (true);

return (false);

}


兩個字符串,s,t;t字符串插入到s字符串中,s字符串有足夠的空間存放t字符串

void insert(char *s, char *t, int i)

{

memcpy(&s[strlen(t)+i],&s[i],strlen(s)-i);

memcpy(&s[i],t,strlen(t));

s[strlen(s)+strlen(t)]='\0';

}


1。編寫一個 C 函數,該函數在一個字符串中找到可能的最長的子字符串,且該字符串是

由同一字符組成的。

char * search(char *cpSource, char ch)

{

char *cpTemp=NULL, *cpDest=NULL;

int iTemp, iCount=0;

while(*cpSource)

{

if(*cpSource == ch)

{

iTemp = 0;

cpTemp = cpSource;

while(*cpSource == ch)

++iTemp, ++cpSource;

if(iTemp > iCount)

iCount = iTemp, cpDest = cpTemp;

if(!*cpSource)

break;

}

++cpSource;

}

return cpDest;

}

2。請編寫一個 C 函數,該函數在給定的內存區域搜索給定的字符,并返回該字符所在位

置索引值。

int search(char *cpSource, int n, char ch)

{

int i;

for(i=0; i<n && *(cpSource+i) != ch; ++i);

return i;

}


一個單向鏈表,不知道頭節點,一個指針指向其中的一個節點,問如何刪除這個指針指向的

節點?

將這個指針指向的next節點值copy到本節點,將next指向next->next,并隨后刪除原next指向的節點。



#include <stdio.h>

void foo(int m, int n)

{

printf("m=%d, n=%d\n", m, n);

}


int main()

{

int b = 3;

foo(b+=3, ++b);

printf("b=%d\n", b);

return 0;

}


輸出:m=7,n=4,b=7(VC6.0)

這種方式和編譯器中得函數調用關系相關即先后入棧順序。不過不同

編譯器得處理不同。也是因為C標準中對這種方式說明為未定義,所以

各個編譯器廠商都有自己得理解,所以最后產生得結果完全不同。

因為這樣,所以遇見這種函數,我們首先要考慮我們得編譯器會如何處理

這樣得函數,其次看函數得調用方式,不同得調用方式,可能產生不同得

結果。最后是看編譯器優化。



2.寫一函數,實現刪除字符串str1中含有的字符串str2.

第二個就是利用一個KMP匹配算法找到str2然后刪除(用鏈表實現的話,便捷于數組)



/*雅虎筆試題(字符串操作)

給定字符串AB,輸出AB中的最大公共子串。

比如A="aocdfe" B="pmcdfa" 則輸出"cdf"

*/

//Author: azhen

#include<stdio.h>

#include<stdlib.h>

#include<string.h>


char *commanstring(char shortstring[], char longstring[])

{

int i, j;


char *substring=malloc(256);


if(strstr(longstring, shortstring)!=NULL) //如果……,那么返回shortstring

return shortstring;


for(i=strlen(shortstring)-1;i>0; i--) //否則,開始循環計算

{

for(j=0; j<=strlen(shortstring)-i; j++){

memcpy(substring, &shortstring[j], i);

substring[i]='\0';

if(strstr(longstring, substring)!=NULL)

return substring;

}

}

return NULL;

}



main()

{

char *str1=malloc(256);

char *str2=malloc(256);

char *comman=NULL;


gets(str1);

gets(str2);


if(strlen(str1)>strlen(str2)) //將短的字符串放前面

comman=commanstring(str2, str1);

else

comman=commanstring(str1, str2);


printf("the longest comman string is: %s\n", comman);

}



11.寫一個函數比較兩個字符串str1str2的大小,若相等返回0,若str1大于str2返回1,若str1小于str2返回-1


int strcmp ( const char * src,const char * dst)

{

int ret = 0 ;

while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)

{

++src;

++dst;

}

if ( ret < 0 )

ret = -1 ;

else if ( ret > 0 )

ret = 1 ;

return( ret );

}


3,1000!的未尾有幾個0(用素數相乘的方法來做,如72=2*2*2*3*3;

求出1->1000,能被5整除的數的個數n1,能被25整除的數的個數n2,能被125整除的數的個

n3,

能被625整除的數的個數n4.

1000!末尾的零的個數=n1+n2+n3+n4;

#include<stdio.h>

#define NUM 1000


int find5(int num){

int ret=0;

while(num%5==0){

num/=5;

ret++;

}

return ret;

}

int main(){

int result=0;

int i;

for(i=5;i<=NUM;i+=5)

{

result+=find5(i);

}

printf(" the total zero number is %d\n",result);

return 0;

}


1. 有雙向循環鏈表結點定義為:

struct node

{ int data;

struct node *front,*next;

};


有兩個雙向循環鏈表AB,知道其頭指針為:pHeadA,pHeadB,請寫一函數將兩鏈表中data值相同的結點刪除


BOOL DeteleNode(Node *pHeader, DataType Value)

{

if (pHeader == NULL) return;


BOOL bRet = FALSE;

Node *pNode = pHead;

while (pNode != NULL)

{

if (pNode->data == Value)

{

if (pNode->front == NULL)

{

pHeader = pNode->next;

pHeader->front = NULL;

}

else

{

if (pNode->next != NULL)

{

pNode->next->front = pNode->front;

}

pNode->front->next = pNode->next;

}


Node *pNextNode = pNode->next;

delete pNode;

pNode = pNextNode;


bRet = TRUE;

//不要breakreturn, 刪除所有

}

else

{

pNode = pNode->next;

}

}


return bRet;

}


void DE(Node *pHeadA, Node *pHeadB)

{

if (pHeadA == NULL || pHeadB == NULL)

{

return;

}


Node *pNode = pHeadA;

while (pNode != NULL)

{

if (DeteleNode(pHeadB, pNode->data))

{

if (pNode->front == NULL)

{

pHeadA = pNode->next;

pHeadA->front = NULL;

}

else

{

pNode->front->next = pNode->next;

if (pNode->next != NULL)

{

pNode->next->front = pNode->front;

}

}

Node *pNextNode = pNode->next;

delete pNode;

pNode = pNextNode;

}

else

{

pNode = pNode->next;

}

}

}


2. 編程實現:找出兩個字符串中最大公共子字符串,"abccade","dgcadde"的最大子串為

"cad"


int GetCommon(char *s1, char *s2, char **r1, char **r2)

{

int len1 = strlen(s1);

int len2 = strlen(s2);

int maxlen = 0;


for(int i = 0; i < len1; i++)

{

for(int j = 0; j < len2; j++)

{

if(s1[i] == s2[j])

{

int as = i, bs = j, count = 1;

while(as + 1 < len1 && bs + 1 < len2 && s1[++as] == s2[++bs])

count++;


if(count > maxlen)

{

maxlen = count;

*r1 = s1 + i;

*r2 = s2 + j;

}

}

}

}

3. 編程實現:把十進制數(long)分別以二進制和十六進制形式輸出,不能使用printf

列庫函數


char* test3(long num) {

char* buffer = (char*)malloc(11);

buffer[0] = '0';

buffer[1] = 'x';

buffer[10] = '\0';


char* temp = buffer + 2;

for (int i=0; i < 8; i++) {

temp[i] = (char)(num<<4*i>>28);

temp[i] = temp[i] >= 0 ? temp[i] : temp[i] + 16;

temp[i] = temp[i] < 10 ? temp[i] + 48 : temp[i] + 55;

}

return buffer;

}


輸入N, 打印 N*N 矩陣

比如 N = 3,打印:


1 2 3

8 9 4

7 6 5


N = 4,打印:


1 2 3 4

12 13 14 5

11 16 15 6

10 9 8 7

解答:

1 #define N 15

int s[N][N];

void main()

{

int k = 0, i = 0, j = 0;

int a = 1;

for( ; k < (N+1)/2; k++ )

{

while( j < N-k ) s[i][j++] = a++; i++; j--;

while( i < N-k ) s[i++][j] = a++; i--; j--;

while( j > k-1 ) s[i][j--] = a++; i--; j++;

while( i > k ) s[i--][j] = a++; i++; j++;

}

for( i = 0; i < N; i++ )

{

for( j = 0; j < N; j++ )

cout << s[i][j] << '\t';

cout << endl;

}

}

2 define MAX_N 100

int matrix[MAX_N][MAX_N];


/*

*x,y):第一個元素的坐標

* start:第一個元素的值

* n:矩陣的大小

*/

void SetMatrix(int x, int y, int start, int n) {

int i, j;


if (n <= 0) //遞歸結束條件

return;

if (n == 1) { //矩陣大小為1

matrix[x][y] = start;

return;

}

for (i = x; i < x + n-1; i++) //矩陣上部

matrix[y][i] = start++;


for (j = y; j < y + n-1; j++) //右部

matrix[j][x+n-1] = start++;


for (i = x+n-1; i > x; i--) //底部

matrix[y+n-1][i] = start++;


for (j = y+n-1; j > y; j--) //左部

matrix[j][x] = start++;


SetMatrix(x+1, y+1, start, n-2); //遞歸

}


void main() {

int i, j;

int n;


scanf("%d", &n);

SetMatrix(0, 0, 1, n);


//打印螺旋矩陣

for(i = 0; i < n; i++) {

for (j = 0; j < n; j++)

printf("%4d", matrix[i][j]);

printf("\n");

}

}



斐波拉契數列遞歸實現的方法如下:

int Funct( int n )

{

if(n==0) return 1;

if(n==1) return 1;

retrurn Funct(n-1) + Funct(n-2);

}

請問,如何不使用遞歸,來實現上述函數?

請教各位高手!

解答:int Funct( int n ) // n 為非負整數

{

int a=0;

int b=1;

int c;

if(n==0) c=1;

else if(n==1) c=1;

else for(int i=2;i<=n;i++) //應該n2開始算起

{

c=a+b;

a=b;

b=c;

}

return c;

}

解答:

現在大多數系統都是將低字位放在前面,而結構體中位域的申明一般是先聲明高位。

100 的二進制是 001 100 100

低位在前 高位在后

001----s3

100----s2

100----s1

所以結果應該是 1

如果先申明的在低位則:

001----s1

100----s2

100----s3

結果是 4

1、原題跟little-endianbig-endian沒有關系

2、原題跟位域的存儲空間分配有關,到底是從低字節分配還是從高字節分配,從Dev C++

VC7.1上看,都是從低字節開始分配,并且連續分配,中間不空,不像譚的書那樣會留空

3、原題跟編譯器有關,編譯器在未用堆棧空間的默認值分配上有所不同,Dev C++未用空

間分配為

01110111bVC7.1下為11001100b,所以在Dev C++下的結果為5,在VC7.1下為1


注:PC一般采用little-endian,即高高低低,但在網絡傳輸上,一般采用big-endian,即

高低低高,華為是做網絡的,所以可能考慮big-endian模式,這樣輸出結果可能為4




判斷一個字符串是不是回文

int IsReverseStr(char *aStr)

{

int i,j;

int found=1;

if(aStr==NULL)

return -1;

j=strlen(aStr);

for(i=0;i<j/2;i++)

if(*(aStr+i)!=*(aStr+j-i-1))

{

found=0;

break;

}

return found;

}

Josephu 問題為:設編號為12… nn個人圍坐一圈,約定編號為k1<=k<=n)的人從

1開始報數,數到m 的那個人出列,它的下一位又從1開始報數,數到m的那個人又出列,依

次類推,直到所有人出列為止,由此產生一個出隊編號的序列。

數組實現:

#include <stdio.h>

#include <malloc.h>

int Josephu(int n, int m)

{

int flag, i, j = 0;

int *arr = (int *)malloc(n * sizeof(int));

for (i = 0; i < n; ++i)

arr[i] = 1;

for (i = 1; i < n; ++i)

{

flag = 0;

while (flag < m)

{

if (j == n)

j = 0;

if (arr[j])

++flag;

++j;

}

arr[j - 1] = 0;

printf("%4d個出局的人是:%4d\n", i, j);

}

free(arr);

return j;

}

int main()

{

int n, m;

scanf("%d%d", &n, &m);

printf("最后勝利的是%d號!\n", Josephu(n, m));

system("pause");

return 0;

}

鏈表實現:

#include <stdio.h>

#include <malloc.h>

typedef struct Node

{

int index;

struct Node *next;

}JosephuNode;

int Josephu(int n, int m)

{

int i, j;

JosephuNode *head, *tail;

head = tail = (JosephuNode *)malloc(sizeof(JosephuNode));

for (i = 1; i < n; ++i)

{

tail->index = i;

tail->next = (JosephuNode *)malloc(sizeof(JosephuNode));

tail = tail->next;

}

tail->index = i;

tail->next = head;


for (i = 1; tail != head; ++i)

{

for (j = 1; j < m; ++j)

{

tail = head;

head = head->next;

}

tail->next = head->next;

printf("%4d個出局的人是:%4d\n", i, head->index);

free(head);

head = tail->next;

}

i = head->index;

free(head);

return i;

}

int main()

{

int n, m;

scanf("%d%d", &n, &m);

printf("最后勝利的是%d號!\n", Josephu(n, m));

system("pause");

return 0;

}


已知strcpy函數的原型是:

char * strcpy(char * strDest,const char * strSrc);

1.不調用庫函數,實現strcpy函數。

2.解釋為什么要返回char *

解說:

1.strcpy的實現代碼

char * strcpy(char * strDest,const char * strSrc)

{

if ((strDest==NULL)||(strSrc==NULL)) file://[/1]

throw "Invalid argument(s)"; //[2]

char * strDestCopy=strDest; file://[/3]

while ((*strDest++=*strSrc++)!='\0'); file://[/4]

return strDestCopy;

}

錯誤的做法:

[1]

(A)不檢查指針的有效性,說明答題者不注重代碼的健壯性。

(B)檢查指針的有效性時使用((!strDest)||(!strSrc))(!(strDest&&strSrc)),說明答題者對C語言中類型的隱式轉換沒有深刻認識。在本例中char *轉換為bool即是類型隱式轉換,這種功能雖然靈活,但更多的是導致出錯概率增大和維護成本升高。所以C++專門增加了booltruefalse三個關鍵字以提供更安全的條件表達式。

(C)檢查指針的有效性時使用((strDest==0)||(strSrc==0)),說明答題者不知道使用常量的好處。直接使用字面常量(如本例中的0)會減少程序的可維護性。0雖然簡單,但程序中可能出現很多處對指針的檢查,萬一出現筆誤,編譯器不能發現,生成的程序內含邏輯錯誤,很難排除。而使用NULL代替0,如果出現拼寫錯誤,編譯器就會檢查出來。

[2]

(A)return new string("Invalid argument(s)"); 說明答題者根本不知道返回值的用途,并且他對內存泄漏也沒有警惕心。從函數中返回函數體內分配的內存是十分危險的做法,他把釋放內存的義務拋給不知情的調用者,絕大多數情況下,調用者不會釋放內存,這導致內存泄漏。

(B)return 0;,說明答題者沒有掌握異常機制。調用者有可能忘記檢查返回值,調用者還可能無法檢查返回值(見后面的鏈式表達式)。妄想讓返回值肩負返回正確值和異常值的雙重功能,其結果往往是兩種功能都失效。應該以拋出異常來代替返回值,這樣可以減輕調用者的負擔、使錯誤不會被忽略、增強程序的可維護性。

[3]

(A)忘記保存原始的strDest值,說明答題者邏輯思維不嚴密

[4]

(A)循環寫成while (*strDest++=*strSrc++); [1](B)

(B)循環寫成while (*strSrc!='\0') *strDest++=*strSrc++;,說明答題者對邊界條件的檢查不力。循環體結束后,strDest字符串的末尾沒有正確地加上'\0'

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458576.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458576.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458576.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WindowsAPI詳解——GetCurrentDirectory 獲得程序當前目錄

每個Windows程序都有一個自己的當前目錄&#xff0c;默認是程序exe文件所在的目錄。系統在給程序加載動態鏈接庫文件(DLL)時先在程序當前目錄里查找要加載的DLL&#xff0c;如果在此目錄下沒有找到系統便會去Windows目錄下查找。在這兒我們主要將如何獲得程序的當前目錄&#x…

20151210小問題2

1、各瀏覽器下 scrollTop的差異 IE6/7/8&#xff1a; 對于沒有doctype聲明的頁面里可以使用 document.body.scrollTop 來獲取 scrollTop高度 &#xff1b; 對于有doctype聲明的頁面則可以使用 document.documentElement.scrollTop&#xff1b; Safari: safari 比較特別&#x…

限制MySQL Binlog的傳輸速率

最近一臺核心庫備庫完成恢復后打開slave&#xff0c;導致主庫傳送binlog&#xff0c;瞬間占滿網絡&#xff0c;觸發故障。 為了做一些限制&#xff0c; 給mysql在發送binlog的函數(mysql_binlog_send)里每隔一段時間sleep一次&#xff0c; 增加了兩個參數&#xff1a; master_s…

sprintf用法詳解

printf可能是許多程序員在開始學習C語言時接觸到的第二個函數&#xff08;我猜第一個是main&#xff09;&#xff0c;說起來&#xff0c;自然是老朋友了&#xff0c;可是&#xff0c;你對這個老朋友了解多嗎&#xff1f;你對它的那個孿生兄弟sprintf了解多嗎&#xff1f;在將各…

掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax 發出異步請求

轉http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro2/ 掌握 Ajax&#xff0c;第 2 部分: 使用 JavaScript 和 Ajax 發出異步請求 在 Web 請求中使用 XMLHttpRequest 多數 Web 應用程序都使用請求/響應模型從服務器上獲得完整的 HTML 頁面。常常是點擊一個按鈕&#xff0…

Provisioning Services 7.8 入門系列教程之十一 通過版本控制自動更新虛擬磁盤

續Provisioning Services 7.8 入門系列教程之十 通過類自動更新虛擬磁盤從前兩的兩種更新方式可以看出&#xff0c;它們有一個共同的特點&#xff0c;即需要產生&#xff08;復制&#xff09;完成的虛擬磁盤副本&#xff0c;然后進行相關的升級操作。這兩種方法在實際生產中&am…

OC面試題

什么是KVC和KVO&#xff1f; 答&#xff1a;KVC(Key-Value-Coding)內部的實現&#xff1a;一個對象在調用setValue的時候&#xff0c; &#xff08;1&#xff09;首先根據方法名找到運行方法的時候所需要的環境參數。 &#xff08;2&#xff09;他會從自己isa指針結合環境參數&…

【算法】QuickSort

快速排序&#xff0c;時間復雜度O(N*logN)&#xff0c;要能熟練掌握&#xff01; 以下主要參考http://blog.csdn.net/morewindows/article/details/6684558&#xff0c; 感謝原博主&#xff01; 該方法的基本思想是&#xff1a; 1&#xff0e;先從數列中取出一個數作為基準數。…

串口之GetCommState、SetCommState函數詳解

GetCommState 讀取串口設置(波特率,校驗,停止位,數據位等).函數聲明&#xff1a;BOOL GetCommState(HANDLE hFile,LPDCB lpDCB);GetCommState函數的第一個參數hFile是由CreateFile函數返回指向已打開串行口的句柄。第二個參數指向設備控制塊DCB。如果函數調用成功&#xff0c;則…

登錄失敗時記住訪問的地址

登錄失敗時記住訪問的地址 使用spring MVC 訪問時,在攔截器中記錄訪問的地址: Java代碼 String path request.getRequestURI();//"/demo_channel_terminal/news/list" System.out.println("您無權訪問:" path); //用于登錄成功…

串口之GetCommTimeouts、SetCommTimeouts函數詳解

Windows系統利用此函數獲取特定的通訊設備讀寫時的超時參數設定&#xff0c;GetCommTimeouts函數聲明如下&#xff1a;BOOL GetCommTimeouts(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts);GetCommTimeouts函數的第一個參數hFile是由CreateFile函數返回指向已打開串行口的句柄。…

GUN/LINUX命令之 cp mv install

1. cp命令 復制copy命令的簡寫 SYNOPSIS cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION]... -t DIRECTORY SOURCE... cp SOURCE DEST 后者如果是目錄那么源文件就復制到文件夾里面并且保持著原來的名字&#xff1b;如果D…

Tomcat - Maven plugin: 運行找不到webapp

2019獨角獸企業重金招聘Python工程師標準>>> The tomcat7-maven-plugin allows running the current project as a Web application and additional <webapps> can be specified that will be simultaneously loaded into tomcat. My project is not a Web ap…

面試題3

1. 你如何理解 iOS 內存管理 1. new alloc copy retain這些對象我們都要主動的release或者 autorelease 2. 如果是類方法創建的對象,那么系統自動釋放池自動在適當的 時候會幫我們 release 3. ARC xcode 自動會幫我們人工智能的添加 release autorelease 操 作 2. C語言里的數…

基于MQTT協議進行應用開發

來自&#xff1a;http://www.cnblogs.com/secondtononewe/p/6073089.html 官方協議有句如下的話來形容MQTT的設計思想&#xff1a; “It is designed for connections with remote locations where a "small code footprint" is required or the network bandwidth i…

SortedDictionaryTKey,TValue正序與反序排序及Dicttionary相關

SortedDictionary<TKey,TValue>能對字典排序 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace SortDictionary {class Program{static void Main(string[] args){TestDictionarySort();…

DOS窗口的編碼頁從UTF-8調回GBK

2019獨角獸企業重金招聘Python工程師標準>>> 之前在DOS窗口操作MySQL數據庫的時候&#xff0c;將編碼頁從GBK設置成了UTF-8&#xff0c;解決了在DOS窗口顯示MySQL數據庫中的表中的中文字符出現亂碼的問題。但是除此之外&#xff0c;DOS窗口顯示的其他中文字符都是亂…

UIBezierPath

學習UIBezierPath畫圖 筆者在寫本篇文章之前&#xff0c;也沒有系統學習過貝塞爾曲線&#xff0c;只是曾經某一次的需求需要使用到&#xff0c;才臨時百度看了一看而且使用最基本的功能。現在總算有時間停下來好好研究研究這個神奇而偉大的貝塞爾先生&#xff01; 筆者在學習時…

系統架構設計理論與原則

一、無共享架構 1、無共享架構 無共享架構是一種分布式計算架構&#xff0c;這種架構中不存在集中存儲的狀態&#xff0c;系統中每個節點都是獨立自治的&#xff0c;整個系統中沒有資源競爭&#xff0c;這種架構具有非常強的擴張性&#xff0c;目前在web應用中被廣泛使用。 無共…

VS2010 教程:創建一個 WPF 應用程序 (第一節)

來自&#xff1a;https://msdn.microsoft.com/zh-cn/library/ff629048.aspx [原文發表地址] VS2010 Tutorial: Build a WPF App (Step 1) [原文發表時間] Friday, May 22, 2009 8:00 AM 這篇文章里&#xff0c;我將使用VS2010 Beta 1創建一個WPF 應用程序。并且 我將展示這個產…