• <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>
            posts - 297,  comments - 15,  trackbacks - 0

            C++面試題


            1.是不是一個父類寫了一個virtual 函數,如果子類覆蓋它的函數不加virtual ,也能實現多態?

            virtual修飾符會被隱形繼承的。

            private 也被集成,只事派生類沒有訪問權限而已

            virtual可加可不加

            子類的空間里有父類的所有變量(static除外)

            同一個函數只存在一個實體(inline除外)

            子類覆蓋它的函數不加virtual ,也能實現多態。

            在子類的空間里,有父類的私有變量。私有變量不能直接訪問。


            --------------------------------------------------------------------------
            2.輸入一個字符串,將其逆序后輸出。(使用C++,不建議用偽碼)

            #include <iostream>
            using namespace std;


            void main()
            {
              char a[50];memset(a,0,sizeof(a));
              int i=0,j;
              char t;
              cin.getline(a,50,'\n');
              for(i=0,j=strlen(a)-1;i<strlen(a)/2;i++,j--)
              {
               t=a[i];
                  a[i]=a[j];
               a[j]=t;
              }
              cout<<a<<endl; 
            }

            //第二種

            string str;
            cin>>str;
            str.replace;
            cout<<str;


            --------------------------------------------------------------------------
            3.請簡單描述Windows內存管理的方法。

            內存管理是操作系統中的重要部分,兩三句話恐怕誰也說不清楚吧~~
            我先說個大概,希望能夠拋磚引玉吧

            當程序運行時需要從內存中讀出這段程序的代碼。代碼的位置必須在物理內存中才能被運行,由于現在的操作系統中有非常多的程序運行著,內存中不能夠完全放下,所以引出了虛擬內存的概念。把哪些不常用的程序片斷就放入虛擬內存,當需要用到它的時候在load入主存(物理內存)中。這個就是內存管理所要做的事。內存管理還有另外一件事需要做:計算程序片段在主存中的物理位置,以便CPU調度。

            內存管理有塊式管理,頁式管理,段式和段頁式管理?,F在常用段頁式管理

            塊式管理:把主存分為一大塊、一大塊的,當所需的程序片斷不在主存時就分配一塊主存空間,把程 序片斷load入主存,就算所需的程序片度只有幾個字節也只能把這一塊分配給它。這樣會造成很大的浪費,平均浪費了50%的內存空間,但時易于管理。

            頁式管理:把主存分為一頁一頁的,每一頁的空間要比一塊一塊的空間小很多,顯然這種方法的空間利用率要比塊式管理高很多。

            段式管理:把主存分為一段一段的,每一段的空間又要比一頁一頁的空間小很多,這種方法在空間利用率上又比頁式管理高很多,但是也有另外一個缺點。一個程序片斷可能會被分為幾十段,這樣很多時間就會被浪費在計算每一段的物理地址上(計算機最耗時間的大家都知道是I/O吧)。

            段頁式管理:結合了段式管理和頁式管理的優點。把主存分為若干頁,每一頁又分為若干段。好處就很明顯,不用我多說了吧。

            各種內存管理都有它自己的方法來計算出程序片斷在主存中的物理地址,其實都很相似。

            這只是一個大概而已,不足以說明內存管理的皮毛。無論哪一本操作系統書上都有詳細的講解


            --------------------------------------------------------------------------
            4.
            #include "stdafx.h"
            #define SQR(X) X*X

            int main(int argc, char* argv[])
            {
             int a = 10;
             int k = 2;
             int m = 1;

             a /= SQR(k+m)/SQR(k+m);
             printf("%d\n",a);

             return 0;
            }
            這道題目的結果是什么啊?

            define 只是定義而已,在編擇時只是簡單代換X*X而已,并不經過算術法則的

            a /= (k+m)*(k+m)/(k+m)*(k+m);
            =>a /= (k+m)*1*(k+m);
            =>a = a/9;
            =>a = 1;
            上面的錯了,該是
            a=a/(k+m*k+m/k+m*k+m)
                         a=a/(2+1*2+1/2+1*2+1)
            注意,因為k,m為int型,所以1/2=0,即a=a/7=1(都為int型)
            gcc下檢查過,如果大家都為float型的話結果為10/7.5=1.33333

            --------------------------------------------------------------------------
            5.
            const 符號常量;
            (1)const char *p
            (2)char const *p
            (3)char * const p
            說明上面三種描述的區別;


            如果const位于星號的左側,則const就是用來修飾指針所指向的變量,即指針指向為常量;
            如果const位于星號的右側,const就是修飾指針本身,即指針本身是常量。

            (1)const char *p

            一個指向char類型的const對象指針,p不是常量,我們可以修改p的值,使其指向不同的char,但是不能改變它指向非char對象,如:
            const char *p;
            char c1='a';
            char c2='b';
            p=&c1;//ok
            p=&c2;//ok
            *p=c1;//error

            (2)char const *p
            (3)char * const p

            這兩個好象是一樣的,此時*p可以修改,而p不能修改。

            (4)const char * const p
            這種是地址及指向對象都不能修改。

            --------------------------------------------------------------------------
            6.下面是C語言中兩種if語句判斷方式。請問哪種寫法更好?為什么?
             int n;
             if (n == 10) // 第一種判斷方式
             if (10 == n) // 第二種判斷方式

            如果少了個=號,編譯時就會報錯,減少了出錯的可能行,可以檢測出是否少了=

            --------------------------------------------------------------------------
            7.下面的代碼有什么問題?
            void DoSomeThing(...)
            {
             char* p;
             ...
             p = malloc(1024);  // 分配1K的空間
             if (NULL == p)
              return;
             ...
             p = realloc(p, 2048); // 空間不夠,重新分配到2K
             if (NULL == p)
              return;
             ...
            }

            A:
            p = malloc(1024);     應該寫成: p = (char *) malloc(1024);
                    沒有釋放p的空間,造成內存泄漏。


            --------------------------------------------------------------------------
            8.下面的代碼有什么問題?并請給出正確的寫法。
            void DoSomeThing(char* p)
            {
             char str[16];
             int n;
             assert(NULL != p);
             sscanf(p, "%s%d", str, n);
             if (0 == strcmp(str, "something"))
             {
              ...
             }
            }

            A:
            sscanf(p, "%s%d", str, n);   這句該寫成: sscanf(p, "%s%d", str, &n);

            --------------------------------------------------------------------------
            9.下面代碼有什么錯誤?
            Void test1()
            {
             char string[10];
             char *str1="0123456789";
             strcpy(string, str1);
            }

            數組越界

            --------------------------------------------------------------------------
            10.下面代碼有什么問題?
            Void test2()
            {
              char string[10], str1[10];
              for(i=0; i<10;i++)
              {
                 str1[i] ='a';
              }
              strcpy(string, str1);
            }

            數組越界

            --------------------------------------------------------------------------
            11.下面代碼有什么問題?
            Void test3(char* str1)
            {
              char string[10];
              if(strlen(str1)<=10)
              {
                strcpy(string, str1);
              }
            }

            ==數組越界
            ==strcpy拷貝的結束標志是查找字符串中的\0 因此如果字符串中沒有遇到\0的話 會一直復制,直到遇到\0,上面的123都因此產生越界的情況
             
            建議使用 strncpy 和 memcpy

            --------------------------------------------------------------------------
            12.下面代碼有什么問題?

            #define MAX_SRM 256

            DSN get_SRM_no()
            {
              static int SRM_no; //是不是這里沒賦初值?
              int I;
              for(I=0;I<MAX_SRM;I++,SRM_no++)
              {
                SRM_no %= MAX_SRM;
                if(MY_SRM.state==IDLE)
                {
                  break;
                }
              }
              if(I>=MAX_SRM)
                return (NULL_SRM);
              else
                return SRM_no;
            }

            系統會初始化static int變量為0,但該值會一直保存,所謂的不可重入...

            --------------------------------------------------------------------------
            13.寫出運行結果:
            {// test1
                char str[] = "world"; cout << sizeof(str) << ": ";
                char *p    = str;     cout << sizeof(p) << ": ";
                char i     = 10;      cout << sizeof(i) << ": ";
                void *pp   = malloc(10);  cout << sizeof(p) << endl;
            }

            6:4:1:4

            --------------------------------------------------------------------------
            14.寫出運行結果:
            {// test2
                union V {
             struct X {
              unsigned char s1:2;
              unsigned char s2:3;
              unsigned char s3:3;
             } x;

             unsigned char c;
                } v;

                v.c = 100;
                printf("%d", v.x.s3);

            }

            3

            --------------------------------------------------------------------------
            15.用C++寫個程序,如何判斷一個操作系統是16位還是32位的?不能用sizeof()函數

            A1:
            16位的系統下,
            int i = 65536;
            cout << i; // 輸出0;
            int i = 65535;
            cout << i; // 輸出-1;

            32位的系統下,
            int i = 65536;
            cout << i; // 輸出65536;
            int i = 65535;
            cout << i; // 輸出65535;

            A2:

            int a = ~0;
            if( a>65536 )
            {
                cout<<"32 bit"<<endl;
            }
            else
            {
                cout<<"16 bit"<<endl;
            }


            --------------------------------------------------------------------------
            16.C和C++有什么不同?

            從機制上:c是面向過程的(但c也可以編寫面向對象的程序);c++是面向對象的,提供了類。但是,
            c++編寫面向對象的程序比c容易

            從適用的方向:c適合要求代碼體積小的,效率高的場合,如嵌入式;c++適合更上層的,復雜的;  llinux核心大部分是c寫的,因為它是系統軟件,效率要求極高。

            從名稱上也可以看出,c++比c多了+,說明c++是c的超集;那為什么不叫c+而叫c++呢,是因為c++比
            c來說擴充的東西太多了,所以就在c后面放上兩個+;于是就成了c++

            C語言是結構化編程語言,C++是面向對象編程語言。
            C++側重于對象而不是過程,側重于類的設計而不是邏輯的設計。

            --------------------------------------------------------------------------
            17.在不用第三方參數的情況下,交換兩個參數的值
            #include <stdio.h>

            void main()
            {
                    int i=60;
                    int j=50;
                    i=i+j;
                    j=i-j;
                    i=i-j;
                    printf("i=%d\n",i);
                    printf("j=%d\n",j);
            }

            方法二:
            i^=j;
            j^=i;
            i^=j;

            方法三:
            // 用加減實現,而且不會溢出
            a = a+b-(b=a)

            --------------------------------------------------------------------------
            18.有關位域的面試題(為什么輸出的是一個奇怪的字符)

            a.t = 'b';效果相當于 a.t= 'b' & 0xf;

            'b' --> 01100010
            'b' & 0xf -->>00000010
            所以輸出Ascii碼為2的特殊字符


            char t:4;就是4bit的字符變量,同樣
            unsigned short i:8;就是8bit的無符號短整形變量

            --------------------------------------------------------------------------
            19.int i=10, j=10, k=3; k*=i+j; k最后的值是?

            60

            --------------------------------------------------------------------------
            20.進程間通信的方式有?

            進程間通信的方式有 共享內存, 管道 ,Socket ,消息隊列 , DDE等

            --------------------------------------------------------------------------
            21.
            struct A
            {
            char t:4;
            char k:4;
            unsigned short i:8;
            unsigned long m;
            }
            sizeof(A)=?(不考慮邊界對齊)

            7

            struct CELL             // Declare CELL bit field
            {
               unsigned character  : 8;  // 00000000 ????????
               unsigned foreground : 3;  // 00000??? 00000000
               unsigned intensity  : 1;  // 0000?000 00000000
               unsigned background : 3;  // 0???0000 00000000
               unsigned blink      : 1;  // ?0000000 00000000
            } screen[25][80];       // Array of bit fields
            二、位結構
                位結構是一種特殊的結構, 在需按位訪問一個字節或字的多個位時, 位結構
            比按位運算符更加方便。
                位結構定義的一般形式為:
                 struct位結構名{
                      數據類型 變量名: 整型常數;
                      數據類型 變量名: 整型常數;
                 } 位結構變量;
                其中: 數據類型必須是int(unsigned或signed)。 整型常數必須是非負的整
            數, 范圍是0~15, 表示二進制位的個數, 即表示有多少位。
                變量名是選擇項, 可以不命名, 這樣規定是為了排列需要。
                例如: 下面定義了一個位結構。
                 struct{
                      unsigned incon: 8;  /*incon占用低字節的0~7共8位*/
                      unsigned txcolor: 4;/*txcolor占用高字節的0~3位共4位*/
                      unsigned bgcolor: 3;/*bgcolor占用高字節的4~6位共3位*/
                      unsigned blink: 1;  /*blink占用高字節的第7位*/
                 }ch;
                位結構成員的訪問與結構成員的訪問相同。
                例如: 訪問上例位結構中的bgcolor成員可寫成:
                  ch.bgcolor
             
                注意:
                1. 位結構中的成員可以定義為unsigned, 也可定義為signed,  但當成員長
            度為1時, 會被認為是unsigned類型。因為單個位不可能具有符號。
                2. 位結構中的成員不能使用數組和指針, 但位結構變量可以是數組和指針,
            如果是指針, 其成員訪問方式同結構指針。
                3. 位結構總長度(位數), 是各個位成員定義的位數之和,  可以超過兩個字
            節。
                4. 位結構成員可以與其它結構成員一起使用。
                例如:
                 struct info{
                      char name[8];
                      int age;
                      struct addr address;
                      float pay;
                      unsigned state: 1;
                      unsigned pay: 1;
                      }workers;
                上例的結構定義了關于一個工人的信息。其中有兩個位結構成員, 每個位結
            構成員只有一位, 因此只占一個字節但保存了兩個信息, 該字節中第一位表示工
            人的狀態, 第二位表示工資是否已發放。由此可見使用位結構可以節省存貯空間。


            --------------------------------------------------------------------------
            22.下面的函數實現在一個固定的數上加上一個數,有什么錯誤,改正
            int add_n(int n)
            {
              static int i=100;
              i+=n;
              return i;
            }

            答:
            因為static使得i的值會保留上次的值。
            去掉static就可了

            --------------------------------------------------------------------------
            23.下面的代碼有什么問題?
            class A
            {
            public:
              A() { p=this; }
              ~A() { if(p!=NULL) { delete p; p=NULL; } }

              A* p;
            };

            答:
            會引起無限遞歸

            --------------------------------------------------------------------------
            24.
            union a {
             int a_int1;
             double a_double;
             int a_int2;
            };

            typedef struct
            {
             a a1;
             char y;
            } b;

            class c
            {
             double c_double;
             b b1;
             a a2;

            };

            輸出cout<<sizeof(c)<<endl;的結果?

            答:
            VC6環境下得出的結果是32

            另:
            我(sun)在VC6.0+win2k下做過試驗:
            short - 2
            int-4
            float-4
            double-8
            指針-4

            sizeof(union),以結構里面size最大的為union的size

            解析C語言中的sizeof

            一、sizeof的概念 
              sizeof是C語言的一種單目操作符,如C語言的其他操作符++、--等。它并不是函數。sizeof操作符以字節形式給出了其操作數的存儲大小。操作數可以是一個表達式或括在括號內的類型名。操作數的存儲大小由操作數的類型決定?!?

            二、sizeof的使用方法 
              1、用于數據類型 

              sizeof使用形式:sizeof(type) 

              數據類型必須用括號括住。如sizeof(int)?!?

              2、用于變量 

              sizeof使用形式:sizeof(var_name)或sizeof var_name 

              變量名可以不用括號括住。如sizeof (var_name),sizeof var_name等都是正確形式。帶括號的用法更普遍,大多數程序員采用這種形式。 

              注意:sizeof操作符不能用于函數類型,不完全類型或位字段。不完全類型指具有未知存儲大小的數據類型,如未知存儲大小的數組類型、未知內容的結構或聯合類型、void類型等?!?

              如sizeof(max)若此時變量max定義為int max(),sizeof(char_v) 若此時char_v定義為char char_v [MAX]且MAX未知,sizeof(void)都不是正確形式?!?

            三、sizeof的結果 
              sizeof操作符的結果類型是size_t,它在頭文件

            中typedef為unsigned int類型。該類型保證能容納實現所建立的最大對象的字節大小。 

              1、若操作數具有類型char、unsigned char或signed char,其結果等于1?!?

              ANSI C正式規定字符類型為1字節?!?

              2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、float、double、long double類型的sizeof 在ANSI C中沒有具體規定,大小依賴于實現,一般可能分別為2、2、2、2、4、4、4、8、10。 

              3、當操作數是指針時,sizeof依賴于編譯器。例如Microsoft C/C++7.0中,near類指針字節數為2,far、huge類指針字節數為4。一般Unix的指針字節數為4。 

              4、當操作數具有數組類型時,其結果是數組的總字節數?!?

              5、聯合類型操作數的sizeof是其最大字節成員的字節數。結構類型操作數的sizeof是這種類型對象的總字節數,包括任何墊補在內?!?

              讓我們看如下結構: 

              struct {char b; double x;} a; 

              在某些機器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9?!?

              這是因為編譯器在考慮對齊問題時,在結構中插入空位以控制各成員對象的地址對齊。如double類型的結構成員x要放在被4整除的地址?!?

              6、如果操作數是函數中的數組形參或函數類型的形參,sizeof給出其指針的大小。 

            四、sizeof與其他操作符的關系 
              sizeof的優先級為2級,比/、%等3級運算符優先級高。它可以與其他操作符一起組成表達式。如i*sizeof(int);其中i為int類型變量?!?

            五、sizeof的主要用途 
              1、sizeof操作符的一個主要用途是與存儲分配和I/O系統那樣的例程進行通信。例如: 

              void *malloc(size_t size), 

              size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)?!?

              2、sizeof的另一個的主要用途是計算數組中元素的個數。例如: 

              void * memset(void * s,int c,sizeof(s))?!?

            六、建議 
              由于操作數的字節數在實現時可能出現變化,建議在涉及到操作數字節大小時用sizeof來代替常量計算。


            =============================================================
            本文主要包括二個部分,第一部分重點介紹在VC中,怎么樣采用sizeof來求結構的大小,以及容易出現的問題,并給出解決問題的方法,第二部分總結出VC中sizeof的主要用法。

            1、 sizeof應用在結構上的情況

            請看下面的結構:

            struct MyStruct

            {

            double dda1;

            char dda;

            int type

            };

            對結構MyStruct采用sizeof會出現什么結果呢?sizeof(MyStruct)為多少呢?也許你會這樣求:

            sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13

            但是當在VC中測試上面結構的大小時,你會發現sizeof(MyStruct)為16。你知道為什么在VC中會得出這樣一個結果嗎?

            其實,這是VC對變量存儲的一個特殊處理。為了提高CPU的存儲速度,VC對一些變量的起始地址做了"對齊"處理。在默認情況下,VC規定各成員變量存放的起始地址相對于結構的起始地址的偏移量必須為該變量的類型所占用的字節數的倍數。下面列出常用類型的對齊方式(vc6.0,32位系統)。

            類型
            對齊方式(變量存放的起始地址相對于結構的起始地址的偏移量)

            Char
            偏移量必須為sizeof(char)即1的倍數

            int
            偏移量必須為sizeof(int)即4的倍數

            float
            偏移量必須為sizeof(float)即4的倍數

            double
            偏移量必須為sizeof(double)即8的倍數

            Short
            偏移量必須為sizeof(short)即2的倍數


            各成員變量在存放的時候根據在結構中出現的順序依次申請空間,同時按照上面的對齊方式調整位置,空缺的字節VC會自動填充。同時VC為了確保結構的大小為結構的字節邊界數(即該結構中占用最大空間的類型所占用的字節數)的倍數,所以在為最后一個成員變量申請空間后,還會根據需要自動填充空缺的字節。

            下面用前面的例子來說明VC到底怎么樣來存放結構的。

            struct MyStruct

            {

            double dda1;

            char dda;

            int type

            };

            為上面的結構分配空間的時候,VC根據成員變量出現的順序和對齊方式,先為第一個成員dda1分配空間,其起始地址跟結構的起始地址相同(剛好偏移量0剛好為sizeof(double)的倍數),該成員變量占用sizeof(double)=8個字節;接下來為第二個成員dda分配空間,這時下一個可以分配的地址對于結構的起始地址的偏移量為8,是sizeof(char)的倍數,所以把dda存放在偏移量為8的地方滿足對齊方式,該成員變量占用sizeof(char)=1個字節;接下來為第三個成員type分配空間,這時下一個可以分配的地址對于結構的起始地址的偏移量為9,不是sizeof(int)=4的倍數,為了滿足對齊方式對偏移量的約束問題,VC自動填充3個字節(這三個字節沒有放什么東西),這時下一個可以分配的地址對于結構的起始地址的偏移量為12,剛好是sizeof(int)=4的倍數,所以把type存放在偏移量為12的地方,該成員變量占用sizeof(int)=4個字節;這時整個結構的成員變量已經都分配了空間,總的占用的空間大小為:8+1+3+4=16,剛好為結構的字節邊界數(即結構中占用最大空間的類型所占用的字節數sizeof(double)=8)的倍數,所以沒有空缺的字節需要填充。所以整個結構的大小為:sizeof(MyStruct)=8+1+3+4=16,其中有3個字節是VC自動填充的,沒有放任何有意義的東西。

            下面再舉個例子,交換一下上面的MyStruct的成員變量的位置,使它變成下面的情況:

            struct MyStruct

            {

            char dda;

            double dda1;  

            int type

            };

            這個結構占用的空間為多大呢?在VC6.0環境下,可以得到sizeof(MyStruc)為24。結合上面提到的分配空間的一些原則,分析下VC怎么樣為上面的結構分配空間的。(簡單說明)

            struct MyStruct

            {

              char dda;//偏移量為0,滿足對齊方式,dda占用1個字節;

            double dda1;//下一個可用的地址的偏移量為1,不是sizeof(double)=8

                         //的倍數,需要補足7個字節才能使偏移量變為8(滿足對齊

                         //方式),因此VC自動填充7個字節,dda1存放在偏移量為8

                         //的地址上,它占用8個字節。

            int type;//下一個可用的地址的偏移量為16,是sizeof(int)=4的倍

                       //數,滿足int的對齊方式,所以不需要VC自動填充,type存

                       //放在偏移量為16的地址上,它占用4個字節。

            };//所有成員變量都分配了空間,空間總的大小為1+7+8+4=20,不是結構

               //的節邊界數(即結構中占用最大空間的類型所占用的字節數sizeof

               //(double)=8)的倍數,所以需要填充4個字節,以滿足結構的大小為

               //sizeof(double)=8的倍數。


            所以該結構總的大小為:sizeof(MyStruc)為1+7+8+4+4=24。其中總的有7+4=11個字節是VC自動填充的,沒有放任何有意義的東西。


            VC對結構的存儲的特殊處理確實提高CPU存儲變量的速度,但是有時候也帶來了一些麻煩,我們也屏蔽掉變量默認的對齊方式,自己可以設定變量的對齊方式。

            VC中提供了#pragma pack(n)來設定變量以n字節對齊方式。n字節對齊就是說變量存放的起始地址的偏移量有兩種情況:第一、如果n大于等于該變量所占用的字節數,那么偏移量必須滿足默認的對齊方式,第二、如果n小于該變量的類型所占用的字節數,那么偏移量為n的倍數,不用滿足默認的對齊方式。結構的總大小也有個約束條件,分下面兩種情況:如果n大于所有成員變量類型所占用的字節數,那么結構的總大小必須為占用空間最大的變量占用的空間數的倍數;

            否則必須為n的倍數。下面舉例說明其用法。

            #pragma pack(push) //保存對齊狀態

            #pragma pack(4)//設定為4字節對齊

            struct test

            {

              char m1;

              double m4;

              int  m3;

            };

            #pragma pack(pop)//恢復對齊狀態

            以上結構的大小為16,下面分析其存儲情況,首先為m1分配空間,其偏移量為0,滿足我們自己設定的對齊方式(4字節對齊),m1占用1個字節。接著開始為m4分配空間,這時其偏移量為1,需要補足3個字節,這樣使偏移量滿足為n=4的倍數(因為sizeof(double)大于n),m4占用8個字節。接著為m3分配空間,這時其偏移量為12,滿足為4的倍數,m3占用4個字節。這時已經為所有成員變量分配了空間,共分配了16個字節,滿足為n的倍數。如果把上面的#pragma pack(4)改為#pragma pack(16),那么我們可以得到結構的大小為24。(請讀者自己分析)

            2、 sizeof用法總結

            在VC中,sizeof有著許多的用法,而且很容易引起一些錯誤。下面根據sizeof后面的參數對sizeof的用法做個總結。

            A.  參數為數據類型或者為一般變量。例如sizeof(int),sizeof(long)等等。這種情況要注意的是不同系統系統或者不同編譯器得到的結果可能是不同的。例如int類型在16位系統中占2個字節,在32位系統中占4個字節。

            B.  參數為數組或指針。下面舉例說明.

            int a[50];  //sizeof(a)=4*50=200; 求數組所占的空間大小

            int *a=new int[50];// sizeof(a)=4; a為一個指針,sizeof(a)是求指針

                               //的大小,在32位系統中,當然是占4個字節。

            C.  參數為結構或類。Sizeof應用在類和結構的處理情況是相同的。但有兩點需要注意,第一、結構或者類中的靜態成員不對結構或者類的大小產生影響,因為靜態變量的存儲位置與結構或者類的實例地址無關。

            第二、沒有成員變量的結構或類的大小為1,因為必須保證結構或類的每一

            個實例在內存中都有唯一的地址。

            下面舉例說明,

            Class Test{int a;static double c};//sizeof(Test)=4.

            Test *s;//sizeof(s)=4,s為一個指針。

            Class test1{ };//sizeof(test1)=1;

            D.  參數為其他。下面舉例說明。

               int func(char s[5]);

               {

                 cout<<sizeof(s);//這里將輸出4,本來s為一個數組,但由于做為函

                                 //數的參數在傳遞的時候系統處理為一個指針,所

                                 //以sizeof(s)實際上為求指針的大小。

                 return 1;

            }

            sizeof(func("1234"))=4//因為func的返回類型為int,所以相當于

                                 //求sizeof(int).


            以上為sizeof的基本用法,在實際的使用中要注意分析VC的分配變量的分配策略,這樣的話可以避免一些錯誤。


            --------------------------------------------------------------------------
            25.i最后等于多少?
            int i = 1;
            int j = i++;
            if((i>j++) && (i++ == j)) i+=j;

            答:
            i = 5

            --------------------------------------------------------------------------
            26.
            unsigned short array[]={1,2,3,4,5,6,7};
            int i = 3;
            *(array + i) = ?

            答:
            4

            --------------------------------------------------------------------------
            27.
            class A
            {
              virtual void func1();
              void func2();
            }
            Class B: class A
            {
              void func1(){cout << "fun1 in class B" << endl;}
              virtual void func2(){cout << "fun2 in class B" << endl;}
            }
            A, A中的func1和B中的func2都是虛函數.
            B, A中的func1和B中的func2都不是虛函數.
            C, A中的func2是虛函數.,B中的func1不是虛函數.
            D, A中的func2不是虛函數,B中的func1是虛函數.

            答:
            A

            --------------------------------------------------------------------------
            28.
            數據庫:抽出部門,平均工資,要求按部門的字符串順序排序,不能含有"human resource"部門,

            employee結構如下:employee_id, employee_name, depart_id,depart_name,wage

            答:
            select depart_name, avg(wage)
            from employee
            where depart_name <> 'human resource'
            group by depart_name
            order by depart_name

            --------------------------------------------------------------------------
            29.
            給定如下SQL數據庫:Test(num INT(4)) 請用一條SQL語句返回num的最小值,但不許使用統計功能,如MIN,MAX等

            答:
            select top 1 num
            from Test
            order by num desc

            --------------------------------------------------------------------------
            30.
            輸出下面程序結果。

            #include <iostream.h>

            class A
            {
            public:
             virtual void print(void)
             {
                cout<<"A::print()"<<endl;
             }
            };
            class B:public A
            {
            public:
             virtual void print(void)
             {
               cout<<"B::print()"<<endl;
             };
            };
            class C:public B
            {
            public:
             virtual void print(void)
             {
              cout<<"C::print()"<<endl;
             }
            };
            void print(A a)
            {
               a.print();
            }
            void main(void)
            {
               A a, *pa,*pb,*pc;
               B b;
               C c;
              
               pa=&a;
               pb=&b;
               pc=&c;
              
               a.print();
               b.print();
               c.print();
              
               pa->print();
               pb->print();
               pc->print();
              
               print(a);
               print(b);
               print(c);
            }

            A:
            A::print()
            B::print()
            C::print()
            A::print()
            B::print()
            C::print()
            A::print()
            A::print()
            A::print()

            --------------------------------------------------------------------------
            31.
            試編寫函數判斷計算機的字節存儲順序是開序(little endian)還是降序(bigendian)

            答:
            bool IsBigendian()
            {
             unsigned short usData = 0x1122;
             unsigned char  *pucData = (unsigned char*)&usData;

             return (*pucData == 0x22);
            }

            --------------------------------------------------------------------------
            32.簡述Critical Section和Mutex的不同點

            答:
            對幾種同步對象的總結
            1.Critical Section
            A.速度快
            B.不能用于不同進程
            C.不能進行資源統計(每次只可以有一個線程對共享資源進行存取)

            2.Mutex
            A.速度慢
            B.可用于不同進程
            C.不能進行資源統計

            3.Semaphore
            A.速度慢
            B.可用于不同進程
            C.可進行資源統計(可以讓一個或超過一個線程對共享資源進行存取)

            4.Event
            A.速度慢
            B.可用于不同進程
            C.可進行資源統計


            --------------------------------------------------------------------------
            33.一個數據庫中有兩個表:
            一張表為Customer,含字段ID,Name;
            一張表為Order,含字段ID,CustomerID(連向Customer中ID的外鍵),Revenue;
            寫出求每個Customer的Revenue總和的SQL語句。

            建表
            create table customer
            (
            ID int primary key,Name char(10)
            )

            go

            create table [order]
            (
            ID int primary key,CustomerID  int foreign key references customer(id) , Revenue float
            )

            go

            --查詢
            select Customer.ID, sum( isnull([Order].Revenue,0) )
            from customer full join [order]
            on( [order].customerid=customer.id )
            group by customer.id

            --------------------------------------------------------------------------
            34.請指出下列程序中的錯誤并且修改
            void GetMemory(char *p){
              p=(char *)malloc(100);
            }
            void Test(void){
              char *str=NULL;
              GetMemory=(str);
              strcpy(str,"hello world");
              printf(str);
            }

            A:錯誤--參數的值改變后,不會傳回
            GetMemory并不能傳遞動態內存,Test函數中的 str一直都是 NULL。
            strcpy(str, "hello world");將使程序崩潰。

            修改如下:
            char *GetMemory(){
              char *p=(char *)malloc(100);
              return p;
            }
            void Test(void){
              char *str=NULL;
              str=GetMemory(){
              strcpy(str,"hello world");
              printf(str);
            }

            方法二:void GetMemory2(char **p)變為二級指針.
            void GetMemory2(char **p, int num)
            {
             *p = (char *)malloc(sizeof(char) * num);
            }

            --------------------------------------------------------------------------
            35.程序改錯
            class mml
            {
              private:
                static unsigned int x;
              public:
                mml(){ x++; }
                mml(static unsigned int &) {x++;}
                ~mml{x--;}
              pulic:
                virtual mon() {} = 0;
                static unsigned int mmc(){return x;}
                ......                     
             
            };
            class nnl:public mml
            {
              private:
                static unsigned int y;
              public:
                nnl(){ x++; }
                nnl(static unsigned int &) {x++;}
                ~nnl{x--;}
              public:
                virtual mon() {};
                 static unsigned int nnc(){return y;}
                ......                  
            };

            代碼片斷:
            mml* pp = new nnl;
            ..........
            delete pp;


            A:
            基類的析構函數應該為虛函數
            virtual ~mml{x--;}

            --------------------------------------------------------------------------
            36.101個硬幣100真、1假,真假區別在于重量。請用無砝碼天平稱兩次給出真幣重還是假幣重的結論。

            答:
            101個先取出2堆,
            33,33
            第一次稱,如果不相等,說明有一堆重或輕
            那么把重的那堆拿下來,再放另外35個中的33
            如果相等,說明假的重,如果不相等,新放上去的還是重的話,說明假的輕(不可能新放上去的輕)

            第一次稱,如果相等的話,這66個肯定都是真的,從這66個中取出35個來,與剩下的沒稱過的35個比
            下面就不用說了

            方法二:
            第3題也可以拿A(50),B(50)比一下,一樣的話拿剩下的一個和真的比一下。
            如果不一樣,就拿其中的一堆。比如A(50)再分成兩堆25比一下,一樣的話就在
            B(50)中,不一樣就在A(50)中,結合第一次的結果就知道了。

            --------------------------------------------------------------------------
            37.static變量和static 函數各有什么特點?

            答:
            static變量:在程序運行期內一直有效,如果定義在函數外,則在編譯單元內可見,如果在函數內,在在定義的block內可見;
            static函數:在編譯單元內可見;

            --------------------------------------------------------------------------
            38.用C 寫一個輸入的整數,倒著輸出整數的函數,要求用遞歸方法 ;

            答:
            void fun( int a )
            {
             printf( "%d", a%10 );
             a /= 10;
             if( a <=0 )return;

             fun( a );
            }

            --------------------------------------------------------------------------
            39.寫出程序結果:
            void Func(char str[100])
            {
              printf("%d\n", sizeof(str));
            }

            答:
            4
            分析:
            指針長度

            --------------------------------------------------------------------------
            40.int id[sizeof(unsigned long)];
                這個對嗎?為什么??

            答:

            這個 sizeof是編譯時運算符,編譯時就確定了
            可以看成和機器有關的常量。


            本文主要包括二個部分,第一部分重點介紹在VC中,怎么樣采用sizeof來求結構的大小,以及容易出現的問題,并給出解決問題的方法,第二部分總結出VC中sizeof的主要用法。

            1、 sizeof應用在結構上的情況

            請看下面的結構:

            struct MyStruct

            {

            double dda1;

            char dda;

            int type

            };

            對結構MyStruct采用sizeof會出現什么結果呢?sizeof(MyStruct)為多少呢?也許你會這樣求:

            sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13

            但是當在VC中測試上面結構的大小時,你會發現sizeof(MyStruct)為16。你知道為什么在VC中會得出這樣一個結果嗎?

            其實,這是VC對變量存儲的一個特殊處理。為了提高CPU的存儲速度,VC對一些變量的起始地址做了"對齊"處理。在默認情況下,VC規定各成員變量存放的起始地址相對于結構的起始地址的偏移量必須為該變量的類型所占用的字節數的倍數。下面列出常用類型的對齊方式(vc6.0,32位系統)。

            類型
            對齊方式(變量存放的起始地址相對于結構的起始地址的偏移量)

            Char
            偏移量必須為sizeof(char)即1的倍數

            int
            偏移量必須為sizeof(int)即4的倍數

            float
            偏移量必須為sizeof(float)即4的倍數

            double
            偏移量必須為sizeof(double)即8的倍數

            Short
            偏移量必須為sizeof(short)即2的倍數


            各成員變量在存放的時候根據在結構中出現的順序依次申請空間,同時按照上面的對齊方式調整位置,空缺的字節VC會自動填充。同時VC為了確保結構的大小為結構的字節邊界數(即該結構中占用最大空間的類型所占用的字節數)的倍?/textarea>

             

            Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=574158

            posted on 2009-12-05 23:25 chatler 閱讀(666) 評論(1)  編輯 收藏 引用 所屬分類: interview

            FeedBack:
            # re: 全面整理的C++面試題
            2009-12-13 00:39 | chatler
            4。分析一下
            #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,b1和b2分別占5bit和2bit.
            經過strcpy和memcpy后,aa的4個字節所存放的值是:
            0,1,2,3的ASC碼,即00110000,00110001,00110010,00110011
            所以,最后一步:顯示的是這4個字節的前5位,和之后的2位
            分別為:10000,和01
            因為int是有正負之分  所以是-16和1

            5。求函數返回值,輸入x=9999;
            int func ( x )
            {
            int countx = 0;
            while ( x )
            {
            countx ++;
            x = x&(x-1);
            }
            return countx;
            }
            結果呢?

            答案:知道了這是統計9999的二進制數值中有多少個1的函數,且有
            9999=9×1024+512+256+15

            9×1024中含有1的個數為2;
            512中含有1的個數為1;
            256中含有1的個數為1;
            15中含有1的個數為4;
            故共有1的個數為8,結果為8。
            1000 - 1 = 0111,正好是原數取反。這就是原理。
            用這種方法來求1的個數是很效率很高的。
            不必去一個一個地移位。循環次數最少。

            6。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 &&(*ca || *c>b)));
            }
            這里,第三個或條件沒看明白,覺得邏輯上出現不了啊。

            7。分析:
            struct bit
            { int a:3;
            int b:2;
            int c:3;
            };
            int main()
            {
            bit s;
            char *c=(char*)&s;
            cout< *c=0x99;
            cout << s.a < int a=-1;
            printf("%x",a);
            return 0;
            }
            輸出為什么是?

            答案:4
            1
            -1
            -4
            ffffffff
            因為0x99在內存中表示為 100 11 001 , a = 001, b = 11, c = 100(在vc環境中,一般是由右到左進行分配的)
            當c為有符合數時, c = 100, 最高1為表示c為負數,負數在計算機用補碼表示,所以c = -4;同理
            b = -1;
            當c為有符合數時, c = 100,即 c = 4,同理 b = 3

            8。改錯:
            #include

            int main(void) {

            int **p;
            int arr[100];

            p = &arr;

            return 0;
            }

            答案:搞錯了,是指針類型不同,
            int **p; //二級指針
            &arr; //得到的是指向第一維為100的數組的指針
            應該這樣寫#include
            int main(void) {
            int **p, *q;
            int arr[100];
            q = arr;
            p = &q;
            return 0;

            9。下面這個程序執行后會有什么錯誤或者效果:
            #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了..無限循環下去.

            11。struct name1{
            char str;
            short x;
            int num;
            }

            struct name2{
            char str;
            int num;
            short x;
            }

            sizeof(struct name1)=??,sizeof(struct name2)=??

            答案:sizeof(struct name1)=8,sizeof(struct name2)=12
            在第二個結構中,為保證num按四個字節對齊,char后必須留出3字節的空間;同時為保證整個結構的自然對齊(這里是4字節對齊),在x后還要補齊2個字節,這樣就是12字節。
              
            回復  更多評論
              
            <2010年8月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            www久久久天天com| 国产午夜久久影院| 狠狠色婷婷综合天天久久丁香| 亚洲国产成人久久综合野外| 国产2021久久精品| 成人亚洲欧美久久久久| 国产精品亚洲综合专区片高清久久久| 久久精品天天中文字幕人妻| 久久人人爽爽爽人久久久| 亚洲国产精品久久电影欧美| 天天爽天天狠久久久综合麻豆| 香蕉久久夜色精品升级完成| 久久99国产综合精品| 久久精品国产影库免费看| 91久久成人免费| 久久人人爽人人爽人人片AV东京热 | 国产情侣久久久久aⅴ免费| 久久综合给合久久狠狠狠97色| 久久久婷婷五月亚洲97号色| 久久福利青草精品资源站免费 | 一本色道久久88加勒比—综合| 99久久www免费人成精品| 久久久久人妻精品一区三寸蜜桃| 蜜臀久久99精品久久久久久 | 无码人妻久久一区二区三区免费丨| 人妻精品久久无码专区精东影业| 99久久99久久久精品齐齐| 国内精品伊人久久久久网站| 欧美久久久久久| 久久精品国产亚洲av麻豆色欲| 久久综合综合久久狠狠狠97色88| 亚洲国产精品成人AV无码久久综合影院| 少妇被又大又粗又爽毛片久久黑人| 久久久久青草线蕉综合超碰| 久久久91精品国产一区二区三区| 性做久久久久久久久| 久久精品亚洲日本波多野结衣| 国产精品免费久久久久影院| 欧美大香线蕉线伊人久久| 久久精品亚洲男人的天堂| 久久偷看各类wc女厕嘘嘘|