簡體   English   中英

指向char指針與char指針的指針數組的指針(或char ** argv vs. char *(* argv)[])

[英]Pointer to array of pointer to char vs. pointer to pointer to char (or char** argv vs. char* (*argv)[])

今天,我與一位同事討論了他(對我而言)不尋常的“主要”功能簽名。 他喜歡這樣聲明:

int main(int argc, char* (*argv)[]) {
   printf("at index 0: %s\n", (*argv)[0]);
}

而我通常編寫以下代碼:

int main(int argc, char** argv)
{
    printf("at index 0: %s\n", argv[0]);
}

有時我寫“ char * argv []”,以便更清楚地表明argv是指向chars的指針數組。

第一個示例中的代碼確實帶有警告編譯

warning: second argument of ‘main’ should be ‘char **’

但它有效。 我的問題是代碼為什么能正常工作,因為我曾預計會由於取消引用argv而導致崩潰。 編譯器是否知道函數簽名不同,並且在這里允許(* argv)作為一種“無操作”?

為了理解正在發生的事情,我編寫了以下示例,令我驚訝的是,該示例也沒有崩潰也不會輸出“ first”(但編譯器會發出警告):

#include <stdio.h>

int my_function(int argc, char* (*argv)[])
{
    printf("at index 0: %s\n", (*argv)[0]);
}

int main(void)
{
    char* stringArr[] = { "frist",
                          NULL };
    size_t stringArrSz = sizeof(stringArr)/sizeof(*stringArr);

    return my_function(stringArrSz, stringArr);
}

我曾期望我需要傳遞“&stringArr”(使用地址運算符)來使代碼運行。 當然,它也可以工作,並且可以修復編譯器警告。

如果我的問題不清楚,請告訴我,我們將不勝感激!

我的問題是代碼為什么能正常工作,因為我曾預計會由於取消引用argv而導致崩潰。 編譯器是否知道函數簽名不同,並且在這里允許(* argv)作為一種“無操作”?

“看起來像預期的那樣工作”是不確定行為的可能結果之一。

有效的指針值仍在從運行時環境傳遞給argv ,因此我不希望代碼僅由於訪問argv[0]而崩潰,無論它如何聲明。

當您嘗試訪問argv[1]argv[2]等時,會變得有趣的地方。盡管C語言本身並不保證指向不同對象類型的指針具有相同的大小,但實際上,它們在大多數現代語言中都可以做到。像x86這樣的x86 ; IOW, sizeof (T *) == sizeof (T **) == sizeof ( T *** ) 因此,對於該平台上的每種類型, p + 1應產生相同的字節偏移。

但是,您的同事卻在調情災難。 類型確實很重要,如果您在不同指針類型具有不同大小的系統上工作,則將argv聲明為char *(*)[]而不是char *[]char **可能會產生一些意外的后果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM