預處理器將您的代碼擴展爲open_file(&file, "test.txt");
。
"test.txt"
是一個字符串文字。編譯器將其嵌入到二進制可執行文件中。當你加載你的程序時它被加載到內存中。
我們來分析一下這個簡單的例子:
#include <stdio.h>
int main(int argc, char **argv) {
printf("hello, wolrd!\n");
return 0;
}
我們可以爲生成彙編:gcc -S hello.c
:
.file "hello.c"
.section .rodata
.LC0:
.string "hello, wolrd!"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $.LC0, %edi
call puts
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
正如你所看到的,字符串被放置在.rodata
- 只讀數據部分。您可以獲取該字符串的內存地址,並嘗試訪問它:
#include <stdio.h>
int main(int argc, char **argv) {
const char *s1 = "hello, world!\n"; // both strings are identical
char *s2 = "hello, world!\n";
printf(s1); // Read-only access - OK
s2[0] = 'x'; // Write to .rodata - SEGFAULT (crash) here
return 0; // we never reach here
}
順便說一下,指針s1
和s2
應該是相同的。編譯器能夠優化相同的字符串並只存儲一次。
我不明白這個問題。你定義了一個被預處理器替代的宏,所以你的調用實際上是'open_file(&file,「test.txt」);' - 你不想讓它工作嗎? – UnholySheep
預期的行爲是什麼?什麼是實際行爲? – merlin2011
一切都很好。我希望它以這種方式工作,但我想知道爲什麼我可以有一個字符串作爲參數,而不是包含文件名的字符數組。我也想知道字符串的存儲位置(堆棧也許?)。最後是這種類型的參數符合ANSI-C嗎? – AceOmn