誰說C語言很簡單?

前兩天,Neo寫了一篇《語言的歧義》其使用C語言討論了一些語言的歧義。大家應該也順便了解了一下C語言中的很多不可思異的東西,可能也是你從未注意到的東西。

是的,C語言并不簡單,讓我們來看看下面這些示例:

  1. 為什么下面的代碼會返回0?(這題應該很簡單吧)

  2. int x;
      return x == (1 && x)

本題主要是關于C/C++中變量初始化的問題。

    為什么下面的代碼會返回0而不是-1?

return ((1 - sizeof(int)) >> 32)

答案:sizeof 是一個unsigned的類型,所以……

代碼作用域是一件很詭異的事,下面這個函數返回值是什么?

int x = 5;
int f() {
  int x = 3;
  {
    extern int x;
    return x;
  }
}

答案:5

 

  1. 函數和函數指針可以相互轉換。下面的語句哪些是合法的?

int (*pf)(void);
int f(void)
{
   pf = &f; // 沒問題
   pf = ***f; // 取址?
   pf(); // 函數指針可以調用?   (****pf)();  // 這又是什么?
   (***************f)(); // 這個夠變態了吧?}

答案:全部合法。

 

  1. 初始化可能是ISO C中最難的部分了。無論是MSVC 還是GCC 都沒有完全實現。GCC 可能更接近標準。在下面的代碼中,i.nested.y 和i.nested.z的最終值是什么?

struct {
   int x;
   struct {
       int y, z;
   } nested;
} i = { .nested.y = 5, 6, .x = 1, 2 }

答案:2和6

 

  1. 下面這個示例是C語言的痛,main函數返回值是什么?

  2. 答案:1(你知道為什么嗎?)

     

 

typedef struct
{
  char *key;
  char *value;
} T1;
typedef struct
{
  long type;
  char *value;
} T3;
T1 a[] =
{
  {
    "",
    ((char *)&((T3) {1, (char *) 1}))
  }
};
int main() {
   T3 *pt3 = (T3*)a[0].value;
   return pt3->value;
}
  1. 下面這個例就更變態了。在GCC的文檔中,這個語法是合法的,但是不知道為什么GCC并沒有實現。下面的代碼返回 2.

return ((int []){1,2,3,4})[1];

 

  1.  在下面的這個示例中,有一個“bar” 函數及其函數指針 “pbar” 的兩個拷貝(static 類型一般作用于語句塊或文件域).


  2. int foo() {
         static bar();
         static (*pbar)() = bar;
      }
      static bar() {
        return 1;
      }
      static (*pbar)() = 0
  3. 下面的這個函數返回值是什么?取決于編譯器是先處理unsigned long轉型,還是負號。
  4. unsigned long foo() {
        return (unsigned long) - 1 / 8;
      }

 

 

    如果是: ((unsigned long) - 1) / 8,那將是一個很大的數。
    如果是: (unsigned long) (- 1 / 8 ), 那將是 0

轉自:http://coolshell.cn/articles/873.html

原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/2257

(0)
s19930811s19930811
上一篇 2016-03-20 11:59
下一篇 2016-03-20 12:00

相關推薦

  • linux磁盤管理

    硬盤接口類型:         IDE:并口,133M/s;100個IO/s        SCSI:并口,UltraSCSI320,320M/s UltraSCSI640 640M/s 150-200IO/s&nbsp…

    Linux干貨 2016-08-29
  • Linux bash中命令執行狀態返回值

    Linux bash中命令執行狀態返回值 在操作系統中,命令的執行后輸出的內容為命令執行結果輸出,而這個命令本身是否執行成功,它是通過命令執行狀態返回值來標識的。 常用的值: 0 表示命令執行成功非0 表示命令執行失敗 bash中獲取命令執行狀態返回值的方法 在剛執行完一條指令后,使用echo $?取得上一條指令的命令執行狀態返回值,示例如下:  …

    Linux干貨 2016-11-06
  • 馬哥教育網絡21期+第一周練習博客

    一、描述計算機的組成及其功能。   計算機設備是由運算器、控制器、存儲器、輸入設備和輸出設備組成。它們的功能和對應設備分別如下: 運算器(arithmetic unit):在計算機中執行各種算術和邏輯運算操作的部件。運算器包括寄存器、執行部件和控制電路3個部      &nbsp…

    Linux干貨 2016-07-12
  • 8月5日課堂筆記

    bash基礎及shell編程初步 bash的特性及bash腳本編程初步    操作系統硬件, 內核把底層硬件的復雜性給隱藏起來,統一輸出為一種系統調用,系統調用非常底層,把系統調用封裝成了庫。讓程序運行起來。用戶在創建時有一個默認shell。終點設備用來當做標準輸入和輸出。  要想與主機交互,需要一個【終端】,附著在終端接口程序:  &n…

    Linux干貨 2016-08-07
  • 關于IO的同步,異步,阻塞,非阻塞

    上次寫了一篇文章:Unix IO 模型學習。恰巧在這次周會的時候,@fp1203 (goldendoc成員之一) 正好在講解poll和epoll的底層實現。中途正好討論了網絡IO的同步、異步、阻塞、非阻塞的概念,當時講下來,大家的理解各不相同,各執己見。搜索了網絡上的一些文章,觀點也各不相同,甚至連wiki也將異步和非阻塞當成一個概念在解釋。  &…

    Linux干貨 2015-04-02
  • N22-第四周

    1、復制/etc/skel目錄到/home/tuser1,要求/home/tuser1及其內部文件的屬組和其它用戶均沒有任何訪問權限。 ~]# cp -r /etc/skel /home/tuser1~]# ll -d /home/tuser1drwxr-xr-x. 3 root root 74 Aug 31 10:13 /home/tuser1~]# ch…

    Linux干貨 2016-09-07
欧美性久久久久