12個滑稽的C語言面試問答——《12個有趣的C語言問答》評析(3)


前文鏈接:http://www.cnblogs.com/pmer/p/3322429.html

 

5,atexit with _exit

Q:在以下代碼,atexit()方法並沒有被調用,你知道為什么嗎?  

#include<stdio.h>

void func(void)
{
    printf("\n Cleanup function called \n");
    return;
}

int main(void)
{
    int i = 0;

    atexit(func);

    for(;i<0xffffff;i++);

    _exit(0);
}

A:這是因為使用了 _exit() 方法。此方法並沒有調用清除數據相關的方法,比如 atexit()等。

Answer: This behavior is due to the use of function _exit(). This function does not call the clean-up functions like atexit() etc. If atexit() is required to be called then exit() or ‘return’ should be used.

評:

  這個Answer沒什么問題。不過_exit()函數只是一個系統函數而非編譯器提供的庫函數。C99之后增加了這個庫函數,名為_Exit()。【感謝madoldman網友指正】

  這里稍微解釋一下atexit()。這個函數的功能是注冊在程序結束時自動調用的函數。一旦程序調用exit()函數或main()通過renturn語句結束程序,通過atexit()注冊的函數將得到調用執行。可以注冊多個函數,最后調用的次序與注冊次序是相反的。

  與_Exit()類似,調用abort()函數結束程序時,atexit()注冊的函數同樣也不會被調用執行。

 

6,void* 與 C 結構體

Q:能否設計一個方法接受任意類型的參數然后返回整數?同時是否有辦法傳遞多個這樣的參數?

A:一個能接受任意類型參數的方法像下面這個樣子:

 int func(void *ptr)

如果需要傳遞多個參數,那么我們可以傳遞一個包含這些參數的結構體

Answer: A function that can accept any type of argument looks like :
  int func(void *ptr)
if more than one argument needs to be passed to this function then this function could be called with a structure object where-in the structure members can be populated with the arguments that need to be passed.

評:

  接受“任意類型的參數”( 原文:Can you design a function that can accept any type of argument and returns an integer?  )的函數在C語言中是不存在的,這個問題的要求本身就很扯蛋。

  從后面的Answer看,問題的意思是任意種類的指針類型,但是從實用的角度來說,int func(void *ptr)這種函數基本沒有任何意義,幾乎不可能存在。因為函數僅僅接受一個void *類型的參數,根本就不可能對這個參數做什么有實際意義的操作(唯一有意義的例外是free() )。理由很簡單,void *類型的指針只有賦值和類型轉換這兩種運算。

  正因為如此,所以凡是接受void *類型參數的函數,通常必定還要有一個size_t類型的參數。例如

void *memset(void *s, int c, size_t n);

  至於“如果需要傳遞多個參數,那么我們可以傳遞一個包含這些參數的結構體”,則更是一種異想天開的天方夜譚,沒有半點可操作性。

 

7,* 與 ++ 操作符

Q:以下代碼將輸出什么?為什么?

#include<stdio.h>

int main(void)
{
    char *ptr = "Linux";
    printf("\n [%c] \n",*ptr++);
    printf("\n [%c] \n",*ptr);

    return 0;
}

A:以上的輸出將是:

 

  因為++與 * 的優先級一樣,所以 *ptr++ 將會從右向左操作。按照這個邏輯,ptr++ 會先執行然后執行*ptr。所以第一個結果是’L'。也因為 ++ 被執行了,所以下一個printf() 結果是’i'。

Answer: The output of the above would be : 

[L] 

[i]

Since the priority of both ‘++’ and ‘*’ are same so processing of ‘*ptr++’ takes place from right to left. Going by this logic, ptr++ is evaluated first and then *ptr. So both these operations result in ‘L’. Now since a post fix ‘++’ was applied on ptr so the next printf() would print ‘i’.

 

評:

  中譯本這回漏掉了原文中的一些東西——程序的輸出。

  Answer中解釋說 ++ 和 * 的優先級一樣是錯誤的。后綴++運算符的優先級高於一元*運算符。

  “ptr++ 會先執行然后執行*ptr”這個解釋同樣荒唐,無法自圓其說。因為既然先執行ptr++,那么ptr應該指向了L后面的i,然后執行*ptr應該得到i,但實際上得到的卻是L。顯然,這個推理過程中有毛病,作者自己都沒搞清楚究竟是怎么回事。這個推理過程中的毛病就是所謂的“先執行”、“后執行”的說法。

 (未完待續)

續文鏈接:http://www.cnblogs.com/pmer/p/3327262.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM