• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            風(fēng)雨兼程

            ring my bells
            posts - 49, comments - 14, trackbacks - 0, articles - 0

            C,C++經(jīng)典筆試題

            Posted on 2008-04-23 10:39 silentneil 閱讀(980) 評(píng)論(1)  編輯 收藏 引用
            1       編程基礎(chǔ)
            1.1    基本概念
            1.         的理解:const char*, char const*, char*const的區(qū)別問(wèn)題幾乎是C++面試中每次    都會(huì)有的題目。 事實(shí)上這個(gè)概念誰(shuí)都有只是三種聲明方式非常相似很容易記混。 Bjarne在他的The C++ Programming Language里面給出過(guò)一個(gè)助記的方法: 把一個(gè)聲明從右向左讀。 const
            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;
            同上因?yàn)镃++里面沒(méi)有const*的運(yùn)算符,所以const只能屬于前面的類型。
            2.         指針c
            int *p[n];-----指針數(shù)組,每個(gè)元素均為指向整型數(shù)據(jù)的指針。
            int (*)p[n];------p為指向一維數(shù)組的指針,這個(gè)一維數(shù)組有n個(gè)整型數(shù)據(jù)。
            int *p();----------函數(shù)帶回指針,指針指向返回的值。
            int (*)p();------p為指向函數(shù)的指針。
            3.         數(shù)組越界問(wèn)題
            下面這個(gè)程序執(zhí)行后會(huì)有什么錯(cuò)誤或者效果:
             #define MAX 255
            int main()
            {
                unsigned char A[MAX],i;
                for (i=0;i<=MAX;i++)
                    A[i]=i;
            }
            解答:MAX=255,數(shù)組A的下標(biāo)范圍為:0..MAX-1,這是其一,其二 當(dāng)i循環(huán)到255時(shí),循環(huán)內(nèi)執(zhí)行: A[255]=255;這句本身沒(méi)有問(wèn)題,但是返回for (i=0;i<=MAX;i++)語(yǔ)句時(shí),由于unsigned char的取值范圍在(0..255),i++以后i又為0了..無(wú)限循環(huán)下去.
            注:char類型為一個(gè)字節(jié),取值范圍是[-128,127],unsigned char [0 ,255]
            4.         和strcpy 的根本區(qū)別?  C++:memset ,memcpy
            #include "memory.h"
            memset用來(lái)對(duì)一段內(nèi)存空間全部設(shè)置為某個(gè)字符,一般用在對(duì)定義的字符串進(jìn)行初始化為‘ '或‘\0';例:char a[100];memset(a, '\0', sizeof(a));
            memcpy用來(lái)做內(nèi)存拷貝,你可以拿它拷貝任何數(shù)據(jù)類型的對(duì)象,可以指定拷貝的數(shù)據(jù)長(zhǎng)度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),會(huì)造成b的內(nèi)存地址溢出。
            strcpy就只能拷貝字符串了,它遇到'\0'就結(jié)束拷貝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串長(zhǎng)度(第一個(gè)‘\0'之前)是否超過(guò)50位,如超過(guò),則會(huì)造成b的內(nèi)存地址溢出。
            strcpy
            原型:extern char *strcpy(char *dest,char *src);
            用法:#include
            功能:把src所指由NULL結(jié)束的字符串復(fù)制到dest所指的數(shù)組中。
            說(shuō)明:src和dest所指內(nèi)存區(qū)域不可以重疊且dest必須有足夠的空間來(lái)容納src的字符串。
            返回指向dest的指針。
            memcpy
            原型:extern void *memcpy(void *dest, void *src, unsigned int count);
            用法:#include
            功能:由src所指內(nèi)存區(qū)域復(fù)制count個(gè)字節(jié)到dest所指內(nèi)存區(qū)域。
            說(shuō)明:src和dest所指內(nèi)存區(qū)域不能重疊,函數(shù)返回指向dest的指針。
            Memset
            原型:extern void *memset(void *buffer, char c, int count);
            用法:#include
            功能:把buffer所指內(nèi)存區(qū)域的前count個(gè)字節(jié)設(shè)置成字符c。
            說(shuō)明:返回指向buffer的指針。
            5.         是干什么用的ASSERT()
            ASSERT ()是一個(gè)調(diào)試程序時(shí)經(jīng)常使用的宏,在程序運(yùn)行時(shí)它計(jì)算括號(hào)內(nèi)的表達(dá)式,如果表達(dá)式為FALSE (0), 程序?qū)?bào)告錯(cuò)誤,并終止執(zhí)行。如果表達(dá)式不為0,則繼續(xù)執(zhí)行后面的語(yǔ)句。這個(gè)宏通常原來(lái)判斷程序中是否出現(xiàn)了明顯非法的數(shù)據(jù),如果出現(xiàn)了終止程序以免導(dǎo)致嚴(yán)重后果,同時(shí)也便于查找錯(cuò)誤。例如,變量n在程序中不應(yīng)該為0,如果為0可能導(dǎo)致錯(cuò)誤,你可以這樣寫程序:
            ......
            ASSERT( n != 0);
            k = 10/ n;
            ......
            ASSERT只有在Debug版本中才有效,如果編譯為Release版本則被忽略。
            assert()的功能類似,它是ANSI C標(biāo)準(zhǔn)中規(guī)定的函數(shù),它與ASSERT的一個(gè)重要區(qū)別是可以用在Release版本中。
            6.         ("pause");系統(tǒng)的暫停程序,按任意鍵繼續(xù),屏幕會(huì)打印,"按任意鍵繼續(xù)。。。。。" 省去了使用getchar();system
            7.         請(qǐng)問(wèn)C++的類和C里面的struct有什么區(qū)別?
            c++中的類具有成員保護(hù)功能,并且具有繼承,多態(tài)這類oo特點(diǎn),而c里的struct沒(méi)有
            8.         請(qǐng)講一講析構(gòu)函數(shù)和虛函數(shù)的用法和作用?
            析構(gòu)函數(shù)也是特殊的類成員函數(shù),它沒(méi)有返回類型,沒(méi)有參數(shù),不能隨意調(diào)用,也沒(méi)有重載。知識(shí)在類對(duì)象生命期結(jié)束的時(shí)候,由系統(tǒng)自動(dòng)調(diào)用釋放在構(gòu)造函數(shù)中分配的資源。這種在運(yùn)行時(shí),能依據(jù)其類型確認(rèn)調(diào)用那個(gè)函數(shù)的能力稱為多態(tài)性,或稱遲后聯(lián)編。另:析構(gòu)函數(shù)一般在對(duì)象撤消前做收尾工作,比如回收內(nèi)存等工作,虛擬函數(shù)的功能是使子類可以用同名的函數(shù)對(duì)父類函數(shù)進(jìn)行重載,并且在調(diào)用時(shí)自動(dòng)調(diào)用子類重載函數(shù),如果是純虛函數(shù),則純粹是為了在子類重載時(shí)有個(gè)統(tǒng)一的命名而已。
            9.         全局變量和局部變量有什么區(qū)別?實(shí)怎么實(shí)現(xiàn)的?操作系統(tǒng)和編譯器是怎么知道的?
            全局變量的生命周期是整個(gè)程序運(yùn)行的時(shí)間,而局部變量的生命周期則是局部函數(shù)或過(guò)程調(diào)用的時(shí)間段。其實(shí)現(xiàn)是由編譯器在編譯時(shí)采用不同內(nèi)存分配方法。全局變量在main函數(shù)調(diào)用后,就開始分配,如果是靜態(tài)變量則是在main函數(shù)前就已經(jīng)初始化了。而局部變量則是在用戶棧中動(dòng)態(tài)分配的(還是建議看編譯原理中的活動(dòng)記錄這一塊)
            10.     是多少尉的系統(tǒng)?在數(shù)據(jù)總線上是怎么實(shí)現(xiàn)的?8086
            8086系統(tǒng)是16位系統(tǒng),其數(shù)據(jù)總線是20位。
            1.2    程序設(shè)計(jì)
            1.         編寫用C語(yǔ)言實(shí)現(xiàn)的求n階階乘問(wèn)題的遞歸算法:
            long int fact(int n)
            {
                int x;
                long int y;
                if(n<0) 
                {
                   printf("error!");
                }
                if(n==0)
                   return 1;
                x=n-1;
                y=fact(x);
                return (n*y);
            }
            2.         二分查找算法:
            1)        遞歸方法實(shí)現(xiàn):
            int BSearch(elemtype a[],elemtype x,int low,int high)
            /*在下屆為low,上界為high的數(shù)組a中折半查找數(shù)據(jù)元素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)        非遞歸方法實(shí)現(xiàn):
            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.         遞歸計(jì)算如下遞歸函數(shù)的值(斐波拉契):
            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);
            }
            4.         交換兩個(gè)數(shù),不用第三塊兒內(nèi)存:
            int a = ……;
            int b = ……;
            a = a + b;
            b = a - b;
            a = a - b;
            5.         冒泡排序:
            void BubbleSort(elemtype x[],int 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;
                            }
            }
            }
            6.         語(yǔ)言 文件讀寫c
            #include "stdio.h"
            main()
            {
                    FILE *fp;
                    char ch,filename[10];
                    scanf("%s",filename);
                    if((fp=fopen(filename,"w")==NULL)
                    {
            printf("cann't open file\n");
            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()
            {
                   WORDwVersionRequested;
                   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);
                   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("%s\n",recvBuf);
                        closesocket(sockConn);
                        WSACleanup();
                   }
            }
            注:這是Server端;File->New->Win32 Console Application,工程名:TcpSrv;然后,F(xiàn)ile->New->C++ Source File,文件名:TcpSrv;在該工程的Setting的Link的Object/library modules項(xiàng)要加入ws2_32.lib
            #include <Winsock2.h>
            #include <stdio.h>
            void main()
            {
                    WORDwVersionRequested;
                    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 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_family=AF_INET;
                    addrSrv.sin_porthtons(6000);
                    connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
            char recvBuf[100];
            recv(sockClient,recvBuf,100,0);
            printf("%s\n",recvBuf);
            send(sockClient,"This is zhangsan",strlen("This is zhangsan")+1,0);
                    closesocket(sockClient);
                    WSACleanup();
            }
            注:這是Client端;File->New->Win32 Console Application,工程名:TcpClient;然后,F(xiàn)ile->New->C++ Source File,文件名:TcpClient;同理,在該工程的Setting的Link的Object/library modules項(xiàng)要加入ws2_32.lib
            8.         類的知識(shí)
            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;
            h1.print();
            human h2  = f1(h1);
            h2.print();
            return 0;
            }
            輸出:
            1
            1
            0
            0
            -1
            -2
            ----------------------------
            分析:
            human h1;       //調(diào)用構(gòu)造函數(shù),---hum_num = 1;
            h1.print();     //輸出:"human is 1"
            human h2  = f1(h1); //再調(diào)用f1(h1)的過(guò)程中,由于函數(shù)參數(shù)是按值傳遞對(duì)象,調(diào)用默認(rèn)的復(fù)制構(gòu)造函數(shù),它并沒(méi)有對(duì)hum_num++,所以hum_num 仍= 1,所以x.print()輸出:"human is 1";   在推出f1函數(shù)時(shí),要銷毀X,調(diào)用析構(gòu)函數(shù)(human_num--),輸出:"human is 0"(,由于該函數(shù)返回一個(gè)human 對(duì)象,所以又調(diào)用默認(rèn)構(gòu)造函數(shù),創(chuàng)建一個(gè)臨時(shí)對(duì)象(human_num = 0;),把臨時(shí)對(duì)象賦給h2,又調(diào)用默認(rèn)構(gòu)造函數(shù)(  human_num = 0);   h2.print();   //輸出: human is 0;
            //在退出main()函數(shù)是,先銷毀h2,調(diào)用析構(gòu)函數(shù)(human_num--),輸出"human_num is -1" 然后銷毀h1,調(diào)用析構(gòu)函數(shù)(--),輸出"human_num is -2"
            1.3    Windows的消息機(jī)制
            1.         的消息機(jī)制1Windows
                   Windows是一個(gè)消息(Message)驅(qū)動(dòng)系統(tǒng)。Windows的消息提供了應(yīng)用程序之間、應(yīng)用程序與Windows系統(tǒng)之間進(jìn)行通信的手段。應(yīng)用程序想要實(shí)現(xiàn)的功能由消息來(lái)觸發(fā),并且靠對(duì)消息的響應(yīng)和處理來(lái)完成。
                   Windows系統(tǒng)中有兩種消息隊(duì)列:系統(tǒng)消息隊(duì)列和應(yīng)用程序消息隊(duì)列。計(jì)算機(jī)的所有輸入設(shè)備由Windows監(jiān)控。當(dāng)一個(gè)事件發(fā)生時(shí),Windows先將輸入的消息放入系統(tǒng)消息隊(duì)列中,再將消息拷貝到相應(yīng)的應(yīng)用程序消息隊(duì)列中。應(yīng)用程序的消息處理程序?qū)⒎磸?fù)檢測(cè)消息隊(duì)列,并把檢測(cè)到的每個(gè)消息發(fā)送到相應(yīng)的窗口函數(shù)中。這便是一個(gè)事件從發(fā)生至到達(dá)窗口函數(shù)必須經(jīng)歷的過(guò)程。
                   必須注意的是,消息并非是搶占性的,無(wú)論事件的緩急,總是按照到達(dá)的先后派對(duì),依次處理(一些系統(tǒng)消息除外),這樣可能使一些實(shí)時(shí)外部事件得不到及時(shí)處理。
            2.         的消息機(jī)制2Windows
                   Windows中的消息是放在對(duì)應(yīng)的進(jìn)程的消息隊(duì)列里的。可以通過(guò)GetMessage取得,并且對(duì)于一般的消息,此函數(shù)返回非零值,但是對(duì)于WM_QUIT消息,返回零。可以通過(guò)這個(gè)特征,結(jié)束程序。當(dāng)取得消息之后,應(yīng)該先轉(zhuǎn)換消息,再分發(fā)消息。所謂轉(zhuǎn)換,就是把鍵盤碼的轉(zhuǎn)換,所謂分發(fā),就是把消息分發(fā)給對(duì)應(yīng)的窗口,由對(duì)應(yīng)的窗口處理消息,這樣對(duì)應(yīng)窗體的消息處理函數(shù)就會(huì)被調(diào)用。兩個(gè)函數(shù)可以實(shí)現(xiàn)這兩個(gè)功能:TranslateMessage和 DispatchMessage。
                   另外,需要注意,當(dāng)我們點(diǎn)擊窗口的關(guān)閉按鈕關(guān)閉窗口時(shí),程序并沒(méi)有自動(dòng)退出,而是向程序發(fā)送了一個(gè)WM_DESTROY消息(其實(shí)過(guò)程是這樣的,首先向程序發(fā)送WM_CLOSE消息,默認(rèn)的處理程序是調(diào)用DestroyWindow銷毀窗體,從而引發(fā)WM_DESTROY消息),此時(shí)在窗體中我們要響應(yīng)這個(gè)消息,如果需要退出程序,那么就要向程序發(fā)送WM_QUIT消息(通過(guò)PostQuitMessage實(shí)現(xiàn))。一個(gè)窗體如果想要調(diào)用自己的消息處理函數(shù),可以使用SendMessage向自己發(fā)消息。
                   如上所述,大部分(注意是大部分)的消息是這樣傳遞的:首先放到進(jìn)程的消息隊(duì)列中,之后由GetMessage取出,轉(zhuǎn)換后,分發(fā)給對(duì)應(yīng)的窗口。這種消息成為存儲(chǔ)式消息。存儲(chǔ)式消息基本上是使用者輸入的結(jié)果,以擊鍵(如WM_KEYDOWN和WM_KEYUP訊息)、擊鍵產(chǎn)生的字符(WM_CHAR)、鼠標(biāo)移動(dòng)(WM_MOUSEMOVE)和鼠標(biāo)按鈕(WM_LBUTTONDOWN)的形式給出。存儲(chǔ)式消息還包含時(shí)鐘消息(WM_TIMER)、更新消息(WM_PAINT)和退出消息(WM_QUIT)。但是也有的消息是直接發(fā)送給窗口的,它們被稱為非存儲(chǔ)式消息。例如,當(dāng)WinMain調(diào)用 CreateWindow時(shí),Windows將建立窗口并在處理中給窗口消息處理函數(shù)發(fā)送一個(gè)WM_CREATE消息。當(dāng)WinMain調(diào)用 ShowWindow時(shí),Windows將給窗口消息處理函數(shù)發(fā)送WM_SIZE和WM_SHOWWINDOW消息。當(dāng)WinMain調(diào)用 UpdateWindow時(shí),Windows將給窗口消息處理函數(shù)發(fā)送WM_PAINT消息。

            2       網(wǎng)絡(luò)知識(shí)
            2.1    OSI和TCP/IP
            1.         的七層網(wǎng)絡(luò)結(jié)構(gòu)圖(功能及特點(diǎn))OSI
            1)   物理層:為數(shù)據(jù)鏈路層提供物理連接,在其上串行傳送比特流,即所傳送數(shù)據(jù)的單位是比特。此外,該層中還具有確定連接設(shè)備的電氣特性和物理特性等功能。
            2)   數(shù)據(jù)鏈路層:負(fù)責(zé)在網(wǎng)絡(luò)節(jié)點(diǎn)間的線路上通過(guò)檢測(cè)、流量控制和重發(fā)等手段,無(wú)差錯(cuò)地傳送以幀為單位的數(shù)據(jù)。為做到這一點(diǎn),在每一幀中必須同時(shí)帶有同步、地址、差錯(cuò)控制及流量控制等控制信息。
            3)   網(wǎng)絡(luò)層:為了將數(shù)據(jù)分組從源(源端系統(tǒng))送到目的地(目標(biāo)端系統(tǒng)),網(wǎng)絡(luò)層的任務(wù)就是選擇合適的路由和交換節(jié)點(diǎn),使源的傳輸層傳下來(lái)的分組信息能夠正確無(wú)誤地按照地址找到目的地,并交付給相應(yīng)的傳輸層,即完成網(wǎng)絡(luò)的尋址功能。
            4)   傳輸層:傳輸層是高低層之間銜接的接口層。數(shù)據(jù)傳輸?shù)膯挝皇菆?bào)文,當(dāng)報(bào)文較長(zhǎng)時(shí)將它分割成若干分組,然后交給網(wǎng)絡(luò)層進(jìn)行傳輸。傳輸層是計(jì)算機(jī)網(wǎng)絡(luò)協(xié)議分層中的最關(guān)鍵一層,該層以上各層將不再管理信息傳輸問(wèn)題。
            5)   會(huì)話層:該層對(duì)傳輸?shù)膱?bào)文提供同步管理服務(wù)。在兩個(gè)不同系統(tǒng)的互相通信的應(yīng)用進(jìn)程之間建立、組織和協(xié)調(diào)交互。例如,確定是雙工還是半雙工工作。
            6)   表示層:該層的主要任務(wù)是把所傳送的數(shù)據(jù)的抽象語(yǔ)法變換為傳送語(yǔ)法,即把不同計(jì)算機(jī)內(nèi)部的不同表示形式轉(zhuǎn)換成網(wǎng)絡(luò)通信中的標(biāo)準(zhǔn)表示形式。此外,對(duì)傳送的數(shù)據(jù)加密(或解密)、正文壓縮(或還原)也是表示層的任務(wù)。
            7)   應(yīng)用層:該層直接面向用戶,是OSI中的最高層。它的主要任務(wù)是為用戶提供應(yīng)用的接口,即提供不同計(jì)算機(jī)間的文件傳送、訪問(wèn)與管理,電子郵件的內(nèi)容處理,不同計(jì)算機(jī)通過(guò)網(wǎng)絡(luò)交互訪問(wèn)的虛擬終端功能等。
            2.         (功能及特點(diǎn))TCP/IP
            1)   網(wǎng)絡(luò)接口層:這是TCP/IP協(xié)議的最低一層,包括有多種邏輯鏈路控制和媒體訪問(wèn)協(xié)議。網(wǎng)絡(luò)接口層的功能是接收IP數(shù)據(jù)報(bào)并通過(guò)特定的網(wǎng)絡(luò)進(jìn)行傳輸,或從網(wǎng)絡(luò)上接收物理幀,抽取出IP數(shù)據(jù)報(bào)并轉(zhuǎn)交給網(wǎng)際層。
            2)   網(wǎng)際網(wǎng)層(IP層):該層包括以下協(xié)議:IP(網(wǎng)際協(xié)議)、ICMP(Internet Control Message Protocol,因特網(wǎng)控制報(bào)文協(xié)議)、ARP(Address Resolution Protocol,地址解析協(xié)議)、RARP(Reverse Address Resolution Protocol,反向地址解析協(xié)議)。該層負(fù)責(zé)相同或不同網(wǎng)絡(luò)中計(jì)算機(jī)之間的通信,主要處理數(shù)據(jù)報(bào)和路由。在IP層中,ARP協(xié)議用于將IP地址轉(zhuǎn)換成物理地址,RARP協(xié)議用于將物理地址轉(zhuǎn)換成IP地址,ICMP協(xié)議用于報(bào)告差錯(cuò)和傳送控制信息。IP協(xié)議在TCP/IP協(xié)議組中處于核心地位。
            3)   傳輸層:該層提供TCP(傳輸控制協(xié)議)和UDP(User Datagram Protocol,用戶數(shù)據(jù)報(bào)協(xié)議)兩個(gè)協(xié)議,它們都建立在IP協(xié)議的基礎(chǔ)上,其中TCP提供可靠的面向連接服務(wù),UDP提供簡(jiǎn)單的無(wú)連接服務(wù)。傳輸層提供端到端,即應(yīng)用程序之間的通信,主要功能是數(shù)據(jù)格式化、數(shù)據(jù)確認(rèn)和丟失重傳等。
            4)   應(yīng)用層:TCP/IP協(xié)議的應(yīng)用層相當(dāng)于OSI模型的會(huì)話層、表示層和應(yīng)用層,它向用戶提供一組常用的應(yīng)用層協(xié)議,其中包括:Telnet、SMTP、DNS等。此外,在應(yīng)用層中還包含有用戶應(yīng)用程序,它們均是建立在TCP/IP協(xié)議組之上的專用程序。
            3.         參考模型和TCP/IP參考模型的區(qū)別:OSI
            1)   OSI模型有7層,TCP/IP只有4層;
            2)   OSI先于協(xié)議出現(xiàn),因此不會(huì)偏向于任何一組特定的協(xié)議,通用性更強(qiáng),但有些功能不知該放哪一層上,因此不得不加入一些子層;TCP/IP后于協(xié)議出現(xiàn),僅是將已有協(xié)議的一個(gè)描述,因此兩者配合的非常好;但他不適合其他的協(xié)議棧,不容易描述其他非TCP/IP的網(wǎng)絡(luò);
            3)   OSI中網(wǎng)絡(luò)層同時(shí)支持無(wú)連接和面向連接的通信,但在傳輸層上只支持面向連接的通信;TCP/IP中網(wǎng)絡(luò)層只支持無(wú)連接通信,傳輸層同時(shí)支持兩種通信;
            4)   在技術(shù)發(fā)生變化時(shí),OSI模型比TCP/IP模型中的協(xié)議更容易被替換。
            4.         請(qǐng)你詳細(xì)的解釋一下IP協(xié)議的定義,在哪個(gè)層上面,主要有什么作用? TCP與UDP呢? 
            解:與IP協(xié)議配套使用的還有三個(gè)協(xié)議:
            ARP-地址解析協(xié)議
            RARP-逆地址解析協(xié)議
            ICMP-因特網(wǎng)控制報(bào)文協(xié)議ICMP
            IP協(xié)議-網(wǎng)際協(xié)議
            IP地址、IP包頭
            2.2    交換機(jī)和路由器
            1.         請(qǐng)問(wèn)交換機(jī)和路由器分別的實(shí)現(xiàn)原理是什么?分別在哪個(gè)層次上面實(shí)現(xiàn)的?
            將網(wǎng)絡(luò)互相連接起來(lái)要使用一些中間設(shè)備(或中間系統(tǒng)),ISO的術(shù)語(yǔ)稱之為中繼(relay)系統(tǒng)。根據(jù)中繼系統(tǒng)所在的層次,可以有以下五種中繼系統(tǒng):
            1)       物理層(即常說(shuō)的第一層、層L1)中繼系統(tǒng),即轉(zhuǎn)發(fā)器(repeater)。
            2)       數(shù)據(jù)鏈路層(即第二層,層L2),即網(wǎng)橋或橋接器(bridge)。
            3)       網(wǎng)絡(luò)層(第三層,層L3)中繼系統(tǒng),即路由器(router)。
            4)       網(wǎng)橋和路由器的混合物橋路器(brouter)兼有網(wǎng)橋和路由器的功能。
            5)       在網(wǎng)絡(luò)層以上的中繼系統(tǒng),即網(wǎng)關(guān)(gateway).
            當(dāng)中繼系統(tǒng)是轉(zhuǎn)發(fā)器時(shí),一般不稱之為網(wǎng)絡(luò)互聯(lián),因?yàn)檫@僅僅是把一個(gè)網(wǎng)絡(luò)擴(kuò)大了,而這仍然是一個(gè)網(wǎng)絡(luò)。高層網(wǎng)關(guān)由于比較復(fù)雜,目前使用得較少。因此一般討論網(wǎng)絡(luò)互連時(shí)都是指用交換機(jī)和路由器進(jìn)行互聯(lián)的網(wǎng)絡(luò)。本文主要闡述交換機(jī)和路由器及其區(qū)別。 
            2.         第二層交換機(jī)和路由器的區(qū)別:
            傳統(tǒng)交換機(jī)從網(wǎng)橋發(fā)展而來(lái),屬于OSI第二層即數(shù)據(jù)鏈路層設(shè)備。它根據(jù)MAC地址尋址,通過(guò)站表選擇路由,站表的建立和維護(hù)由交換機(jī)自動(dòng)進(jìn)行。路由器屬于OSI第三層即網(wǎng)絡(luò)層設(shè)備,它根據(jù)IP地址進(jìn)行尋址,通過(guò)路由表路由協(xié)議產(chǎn)生。因特網(wǎng)的路由選擇協(xié)議:內(nèi)部網(wǎng)關(guān)協(xié)議IGP和外部網(wǎng)關(guān)協(xié)議EGP
            3.         第三層交換機(jī)和路由器的區(qū)別:
            在第三層交換技術(shù)出現(xiàn)之前,幾乎沒(méi)有必要將路由功能器件和路由器區(qū)別開來(lái),他們完全是相同的:提供路由功能正在路由器的工作,然而,現(xiàn)在第三層交換機(jī)完全能夠執(zhí)行傳統(tǒng)路由器的大多數(shù)功能。
            綜上所述,交換機(jī)一般用于LAN-WAN的連接,交換機(jī)歸于網(wǎng)橋,是數(shù)據(jù)鏈路層的設(shè)備,有些交換機(jī)也可實(shí)現(xiàn)第三層的交換。路由器用于WAN-WAN之間的連接,可以解決異性網(wǎng)絡(luò)之間轉(zhuǎn)發(fā)分組,作用于網(wǎng)絡(luò)層。他們只是從一條線路上接受輸入分組,然后向另一條線路轉(zhuǎn)發(fā)。這兩條線路可能分屬于不同的網(wǎng)絡(luò),并采用不同協(xié)議。相比較而言,路由器的功能較交換機(jī)要強(qiáng)大,但速度相對(duì)也慢,價(jià)格昂貴,第三層交換機(jī)既有交換機(jī)線速轉(zhuǎn)發(fā)報(bào)文能力,又有路由器良好的控制功能,因此得以廣播應(yīng)用。

            3       高質(zhì)量編程C/C++
            一、請(qǐng)?zhí)顚態(tài)OOL , float, 指針變量與“零值”比較的 if 語(yǔ)句。(10 分)
            請(qǐng)寫出 BOOL flag 與“零值”比較的 if 語(yǔ)句。(3 分)
            標(biāo)準(zhǔn)答案:
            if ( flag )
            if ( !flag )
            如下寫法均屬不良風(fēng)格,不得分。
            if (flag == TRUE)
            if (flag == 1 )
            if (flag == FALSE)
            if (flag == 0)

            請(qǐng)寫出 float x 與“零值”比較的 if 語(yǔ)句。(4 分)
            標(biāo)準(zhǔn)答案示例:
            const float EPSINON = 0.00001;
            if ((x >= - EPSINON) && (x <= EPSINON)
            不可將浮點(diǎn)變量用“==”或“!=”與數(shù)字
            比較,應(yīng)該設(shè)法轉(zhuǎn)化成“>=”或“<=”此
            類形式。
            如下是錯(cuò)誤的寫法,不得分。
            if (x == 0.0)
            if (x != 0.0)

            請(qǐng)寫出 char *p 與“零值”比較的 if 語(yǔ)句。(3 分)
            標(biāo)準(zhǔn)答案:
            if (p == NULL)
            if (p != NULL)
            如下寫法均屬不良風(fēng)格,不得分。
            if (p == 0)
            if (p != 0)
            if (p)
            if (!)
            二、以下為Windows NT 下的32 位C++程序,請(qǐng)計(jì)算sizeof 的值(10 分)
            void Func ( char str[100])
            {
                請(qǐng)計(jì)算
                sizeof( str ) = 4 (2 分)
            }
            char str[] = “Hello” ;
            char *p = str ;
            int n = 10;
            請(qǐng)計(jì)算
            sizeof (str ) = 6 (2 分)
            sizeof ( p ) = 4 (2 分)
            sizeof ( n ) = 4 (2 分)
            void *p = malloc( 100 );
            請(qǐng)計(jì)算
            sizeof ( p ) = 4 (2 分)
            三、簡(jiǎn)答題(25 分)
            1、頭文件中的 ifndef/define/endif 干什么用?(5 分)
            答:防止該頭文件被重復(fù)引用。

            2、#include <filename.h> 和 #include “filename.h” 有什么區(qū)別?(5 分)
            答:對(duì)于#include <filename.h> ,編譯器從標(biāo)準(zhǔn)庫(kù)路徑開始搜索 filename.h
            對(duì)于#include “filename.h” ,編譯器從用戶的工作路徑開始搜索 filename.h

            3、const 有什么用途?(請(qǐng)至少說(shuō)明兩種)(5 分)
            答:(1)可以定義 const 常量,(2)const 可以修飾函數(shù)的參數(shù)、返回值,甚至函數(shù)的定義體。被const 修飾的東西都受到強(qiáng)制保護(hù),可以預(yù)防意外的變動(dòng),能提高程序的健壯性。
            4、在C++ 程序中調(diào)用被 C 編譯器編譯后的函數(shù),為什么要加 extern “C”? (5 分)
            答:C++語(yǔ)言支持函數(shù)重載,C 語(yǔ)言不支持函數(shù)重載。函數(shù)被C++編譯后在庫(kù)中的名字
            與C 語(yǔ)言的不同。假設(shè)某個(gè)函數(shù)的原型為: void foo(int x, int y);該函數(shù)被C 編譯器編譯后在庫(kù)中的名字為_foo ,而C++編譯器則會(huì)產(chǎn)生像_foo_int_int 之類的名字。C++提供了C 連接交換指定符號(hào)extern“C”來(lái)解決名字匹配問(wèn)題。
            5、請(qǐng)簡(jiǎn)述以下兩個(gè)for 循環(huán)的優(yōu)缺點(diǎn)(5 分)
            for (i=0; i<N; i++)
            {
                if (condition)
                    DoSomething();
                else
                    DoOtherthing();
            }
            if (condition)
            {
                for (i=0; i<N; i++)
                    DoSomething();
            }
            else
            {
                for (i=0; i<N; i++)
                DoOtherthing();
            }
            優(yōu)點(diǎn):程序簡(jiǎn)潔
            缺點(diǎn):多執(zhí)行了N-1 次邏輯判斷,并且
            打斷了循環(huán)“流水線”作業(yè),使得編譯
            器不能對(duì)循環(huán)進(jìn)行優(yōu)化處理,降低了效
            率。
            優(yōu)點(diǎn):循環(huán)的效率高
            缺點(diǎn):程序不簡(jiǎn)潔
            四、有關(guān)內(nèi)存的思考題(每小題5 分,共20 分)
            void GetMemory(char *p)
            {
               p = (char *)malloc(100);
            }
            void Test(void)
            {
                char *str = NULL;
                GetMemory(str);
                strcpy(str, "hello world");
                printf(str);
            }
            請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果?
            答:程序崩潰。
            因?yàn)镚etMemory 并不能傳遞動(dòng)態(tài)內(nèi)存,
            Test 函數(shù)中的 str 一直都是 NULL。
            strcpy(str, "hello world");將使程序崩
            潰。
            char *GetMemory(void)
            {
                char p[] = "hello world";
                return p;
            }
            void Test(void)
            {
                char *str = NULL;
                str = GetMemory();
                printf(str);
            }
            請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果?
            答:可能是亂碼。
            因?yàn)镚etMemory 返回的是指向“棧內(nèi)存”
            的指針,該指針的地址不是 NULL,但其原
            現(xiàn)的內(nèi)容已經(jīng)被清除,新內(nèi)容不可知。
            void GetMemory2(char **p, int num)
            {
                *p = (char *)malloc(num);
            }
            void Test(void)
            {
                char *str = NULL;
                GetMemory(&str, 100);
                strcpy(str, "hello");
                printf(str);
            }
            請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果?
            答:(1)能夠輸出hello;(2)內(nèi)存泄漏

            void Test(void)
            {
                char *str = (char *) malloc(100);
                strcpy(str, “hello”);
                free(str);
                if(str != NULL)
                {
                    strcpy(str, “world”);
                    printf(str);
                }
            }
            請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果?
            答:篡改動(dòng)態(tài)內(nèi)存區(qū)的內(nèi)容,后果難以預(yù)
            料,非常危險(xiǎn)。
            因?yàn)閒ree(str);之后,str 成為野指針,
            if(str != NULL)語(yǔ)句不起作用。
            五、編寫strcpy 函數(shù)(10 分)
            已知strcpy 函數(shù)的原型是
            char *strcpy(char *strDest, const char *strSrc);
            其中strDest 是目的字符串,strSrc 是源字符串。
            (1)不調(diào)用C++/C 的字符串庫(kù)函數(shù),請(qǐng)編寫函數(shù) strcpy
            char *strcpy(char *strDest, const char *strSrc);
            {
                assert((strDest!=NULL) && (strSrc !=NULL)); // 2分
                char *address = strDest; // 2分
                while( (*strDest++ = * strSrc++) != ‘\0’ ) // 2分
                NULL ;
                return address ; // 2分
            }
            (2)strcpy 能把strSrc 的內(nèi)容復(fù)制到strDest,為什么還要char * 類型的返回值?
            答:為了實(shí)現(xiàn)鏈?zhǔn)奖磉_(dá)式。 // 2 分
            例如 int length = strlen( strcpy( strDest, “hello world”) );
            六、編寫類String 的構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值函數(shù)(25 分)
            已知類String 的原型為:
            class String
            {
                public:
                String(const char *str = NULL); // 普通構(gòu)造函數(shù)
                String(const String &other); // 拷貝構(gòu)造函數(shù)
                ~ String(void); // 析構(gòu)函數(shù)
                String & operate =(const String &other); // 賦值函數(shù)
                private:
                char *m_data; // 用于保存字符串
            };
            請(qǐng)編寫String 的上述4 個(gè)函數(shù)。
            標(biāo)準(zhǔn)答案:
            // String 的析構(gòu)函數(shù)
            String::~String(void) // 3 分
            {
                delete [] m_data;
                // 由于m_data 是內(nèi)部數(shù)據(jù)類型,也可以寫成 delete m_data;
            }

            // String 的普通構(gòu)造函數(shù)
            String::String(const char *str) // 6 分
            {
                if(str==NULL)
                {
                    m_data = new char[1]; // 若能加 NULL 判斷則更好
                    *m_data = ‘\0’;
                }
                else
                {
                    int length = strlen(str);
                    m_data = new char[length+1]; // 若能加 NULL 判斷則更好
                    strcpy(m_data, str);
                 }
            }

            // 拷貝構(gòu)造函數(shù)
            String::String(const String &other) // 3 分
            {
                int length = strlen(other.m_data);
                m_data = new char[length+1]; // 若能加 NULL 判斷則更好
                strcpy(m_data, other.m_data);
            }

            // 賦值函數(shù)
            String & String::operate =(const String &other) // 13 分
            {
                // (1) 檢查自賦值 // 4 分
                if(this == &other)
                return *this;
                // (2) 釋放原有的內(nèi)存資源 // 3 分
                delete [] m_data;
                // (3)分配新的內(nèi)存資源,并復(fù)制內(nèi)容 // 3 分
                int length = strlen(other.m_data);
                m_data = new char[length+1]; // 若能加 NULL 判斷則更好
                strcpy(m_data, other.m_data);
                // (4)返回本對(duì)象的引用 // 3 分
                return *this;
            }

            Feedback

            # re: C,C++經(jīng)典筆試題  回復(fù)  更多評(píng)論   

            2008-04-23 13:28 by 北航-劉玉龍
            受教了,感謝

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久频这里精品99香蕉久| 久久婷婷国产剧情内射白浆| 久久精品国产亚洲av日韩| 伊人久久大香线蕉综合Av | 久久久久国产一级毛片高清板| 无码日韩人妻精品久久蜜桃| 波多野结衣久久精品| 久久国产亚洲精品| 波多野结衣久久一区二区| 国产精品无码久久久久久| 日本精品久久久久中文字幕| 久久久久久久99精品免费观看| 久久综合日本熟妇| 久久久久人妻一区精品性色av| 精品免费久久久久久久| 久久精品免费大片国产大片| 免费久久人人爽人人爽av| 精品乱码久久久久久久| 亚洲国产成人久久综合区| 久久婷婷五月综合色奶水99啪| A级毛片无码久久精品免费| 97久久婷婷五月综合色d啪蜜芽| 久久99国产精品二区不卡| 欧美午夜A∨大片久久| 久久精品九九亚洲精品| 伊人精品久久久久7777| 久久精品人人做人人爽电影| 久久综合88熟人妻| 久久久久亚洲精品无码网址| 国产成人无码久久久精品一| 精品久久久久久中文字幕大豆网 | 一本久久综合亚洲鲁鲁五月天| 精品精品国产自在久久高清| 伊人久久大香线蕉综合Av| 色综合合久久天天给综看| 精品无码人妻久久久久久| 精品久久久久香蕉网| 亚洲综合日韩久久成人AV| 人妻精品久久久久中文字幕69 | 国产真实乱对白精彩久久| 26uuu久久五月天|