前言
在一次作業下碰到了 argv 與的操作,看到課本
UNIX Systems Programming: Communication, Concurrency and Threads: Communication, Concurrency and Threads (2nd Edition) 2nd Edition
對於 argv 的操作為下
1 | int main(int argc, char* argv[]) { } |
回想起以前常常都是使用以下這種用法
1 | int main(int argc, char** argv) { } |
於是開始研究了 C 語言的 argv 到底傳了什麼東西給 main function
正文
在記憶體中 argv 是一個指標,指向 char 陣列,每一陣列的內容就是不同的 argv 字串,如下圖所示。
所以當 main 在接收 argv 這個指標時,它只是一個指向字元陣列的指標,需要對它進一步操作,例如:
1 |
|
編譯:gcc app.c
output:
1 | ./a.out |
把結果對印至上圖,如同以下:
如果將陣列的第二格位置與第一格相減,可以發現長度為 8
0x7fffffffe5c0 - 0x7fffffffe5b8 = 8
而這個 8 就是 ./a.out
這個字串的長度 (.
, /
, a
, .
, o
, u
, t
, \0
)
結論
如此一來,兩種寫法的關係就清晰多了。
1 | int main(int argc, char** argv) { } |
這個寫法只不過是 pointer to pointer 的概念,與另外一種可以說是沒有分別。
不相信的話可以做個小實驗:
1 |
|
編譯:gcc app2.c
output:
1 | ./a.out |
與上述第一種寫法完全相同!
(實際上 OS 有一種 ASLR 的機制讓每一次執行程式的 virtual memory 都不同,所以做這個實驗時,記得先暫時關閉 ASLR。)
所以依照個人習慣,想要用哪一種寫法都可以 👏