C puzzles詳解【13-15題】

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   ar   strong   資料   div   

第十三題

  int CountBits(unsigned int x)  {      int count=0;      while(x)      {          count++;          x = x&(x-1);      }      return count;  }

知識點講解

  • 位元運算

關於位元運算的一些例子參考:

http://www.ugcs.caltech.edu/~wnoise/base2.html

題目講解

x&(x-1)常見的兩種應用:

1)計算x二進位形式中1的個數,每迴圈一次,將x二進位形式最右邊的1變成0;

2)判斷x是否是2的冪,若x&(x-1)==0,x為2的冪。

 

第十四題

Are the following two function prototypes same?   int foobar(void);  int foobar();The following programs should be of some help in finding the answer: (Compile and run both the programs and see what happens) Program 1:   #include <stdio.h>  void foobar1(void)  {   printf("In foobar1\n");  }  void foobar2()  {   printf("In foobar2\n");  }  int main()  {     char ch = ‘a‘;     foobar1();     foobar2(33, ch);     return 0;  }Program 2:   #include <stdio.h>  void foobar1(void)  {   printf("In foobar1\n");  }  void foobar2()  {   printf("In foobar2\n");  }  int main()  {     char ch = ‘a‘;     foobar1(33, ch);     foobar2();     return 0;  }

知識點講解

  • foo()和foo(void)是不一樣的

調用foo()時,可以傳入任意個數,任意類型的參數,編譯器不會關心傳給foo的參數,傳入的參數對foo函數的執行沒有影響;

調用foo(void)時,不可傳入參數,否則編譯不通過;

void foo() {}是定義無參數函數的一種過時的用法,故日常編寫代碼時,若函數沒有參數,最好寫成foo(void)的形式。

題目講解

Program 1能編譯通過,運行後正常列印兩個字串;

Program 2編譯不通過,提示foobar1參數過多。

 

第十五題

What‘s the output of the following program and why?   #include <stdio.h>  int main()  {   float a = 12.5;   printf("%d\n", a);   printf("%d\n", *(int *)&a);   return 0;  }

知識點講解

  • printf中的%f讀取sizeof(double)個位元組;
#include <stdio.h>int main(){        int a = 10, b = 20, c = 30;        printf("%f, %d\n", a, b, c);        return 0;}

輸出:0.000000, 30

調用printf時,雙引號後面的所有參數從右往左依次入棧,然後將棧中的資料根據雙引號中的格式從低地址向高地址依次讀取並列印出來。

上述代碼調用printf時,c,b,a依次入棧,%f讀取sizeof(double)=8個位元組,

即a,b所佔的地區,轉換成浮點數為0.000000,%d繼續讀取下面4個位元組,即c所佔的地區,轉換為整型數為30。

  • printf中傳入的float型參數自動轉換成double型;
#include <stdio.h>int main(){        float a = 1.2;        int b = 10;        printf("%x, %x, %d\n", a, b);        return 0;}

輸出:40000000, 3ff33333, 10

調用printf時,參數a被轉為double型後再傳入printf,printf的前兩個%x讀取的是a所佔的8個位元組,%d讀取的是b所佔的4個位元組。

gcc –S test.c命令可以產生彙編代碼,上例的彙編代碼主體如下:

main:        pushl   %ebp        movl    %esp, %ebp        andl    $-16, %esp        subl    $32, %esp        movl    $0x3f99999a, %eax        movl    %eax, 28(%esp)        movl    $10, 24(%esp)        flds    28(%esp)        movl    $.LC1, %eax        movl    24(%esp), %edx        movl    %edx, 12(%esp)        fstpl   4(%esp)        movl    %eax, (%esp)        call    printf        movl    $0, %eax        leave        ret

“flds    28(%esp)”,flds將28(%esp)地址處的單精確度浮點數即0x3f99999a載入到浮點寄存器,“fstpl   4(%esp)”即將浮點寄存器中的浮點數轉換成double型後放到4(%esp)處。

  • printf中的%c讀取4個位元組,printf的char型參數先轉換為int再入棧;
#include <stdio.h>int main(){        char a = 97;        int b = 20;        printf("%c, %d\n", a, b);        return 0;}

輸出:a, 20

上述c代碼的彙編代碼主體為:

main:        pushl   %ebp        movl    %esp, %ebp        andl    $-16, %esp        subl    $32, %esp        movb    $97, 31(%esp)        movl    $20, 24(%esp)        movsbl  31(%esp), %edx        movl    $.LC0, %eax        movl    24(%esp), %ecx        movl    %ecx, 8(%esp)        movl    %edx, 4(%esp)        movl    %eax, (%esp)        call    printf        movl    $0, %eax        leave        ret

“movl    %edx, 4(%esp)”在棧中壓了4個位元組。

  • sizeof(‘a’)=4;
#include <stdio.h>int main(){        char a = ‘a‘;        printf("%d, %d\n", sizeof(a), sizeof(‘a‘));        return 0;}

sizeof求類型的大小,sizeof(a)即sizeof(char),sizeof(‘a’)即sizeof(int),‘a’自動轉換為int型。

題目講解

“printf("%d\n", a);”,a轉換為double型再入棧,%d讀取double型資料的低4個位元組;

“printf("%d\n", *(int *)&a);”float佔4個位元組,*(int *)&a將a在記憶體中存放值轉換為整型數後再傳入printf。

浮點數在記憶體中如何表示參考第九題講解。

C puzzles詳解【13-15題】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.