Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C—中使用#定义值作为函数参数;它为什么有效?_C_File_Fopen - Fatal编程技术网

在C—中使用#定义值作为函数参数;它为什么有效?

在C—中使用#定义值作为函数参数;它为什么有效?,c,file,fopen,C,File,Fopen,在我上一个个人C项目中,我玩了一些文件。我尝试过的一件事是使用#define值作为参数。最后是一段代码片段,以便您了解我的意思 我的问题是:它为什么起作用?数据存储在哪里?它符合ANSI C标准吗 #include <stdio.h> #define FILE_NAME "test.txt" void open_file(FILE**, char*); int main(int argc, char *argv[]) { FILE* file; open_file(&

在我上一个个人C项目中,我玩了一些文件。我尝试过的一件事是使用
#define
值作为参数。最后是一段代码片段,以便您了解我的意思

我的问题是:它为什么起作用?数据存储在哪里?它符合ANSI C标准吗

#include <stdio.h>
#define FILE_NAME "test.txt"

void open_file(FILE**, char*);

int main(int argc, char *argv[])
{
   FILE* file;
   open_file(&file, FILE_NAME);
   return 0;
}

void open_file(FILE** file, char* filename)
{
   *(file)=fopen(filename, "r");
}
#包括
#定义文件名“test.txt”
作废打开的文件(文件**,字符*);
int main(int argc,char*argv[])
{
文件*文件;
打开文件(&文件,文件名);
返回0;
}
作废打开文件(文件**文件,字符*文件名)
{
*(文件)=fopen(文件名,“r”);
}

为什么我可以将文本作为参数而不是存储文件名的字符数组?

预处理器将代码扩展为
打开的文件(&file,“test.txt”)

“test.txt”
是字符串文本。编译器将其嵌入到二进制可执行文件中。当您加载程序时,它会加载到内存中

让我们分析一下这个简单的例子:

#include <stdio.h>

int main(int argc, char **argv) {
        printf("hello, wolrd!\n");
        return 0;
}
如您所见,字符串被放置在
.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
}
#包括
int main(int argc,字符**argv){
const char*s1=“你好,世界!\n”;//两个字符串完全相同
char*s2=“你好,世界!\n”;
printf(s1);//只读访问-确定
s2[0]=“x”;//在此处写入.rodata-SEGFAULT(崩溃)
返回0;//我们永远无法到达这里
}

顺便说一句,指针
s1
s2
应该相同。编译器能够优化相同的字符串并只存储一次。

我不理解这个问题。您定义了一个被预处理器替换的宏,因此您的调用实际上是
open_文件(&file,“test.txt”)-您不想这样做吗?预期的行为是什么?实际的行为是什么?一切都很好。我希望它以这种方式工作,但我想知道为什么我可以使用字符串作为参数,而不是包含文件名的char数组。我还想知道字符串存储在哪里(可能是堆栈?)。最后是符合ANSI-C的参数类型?“为什么我可以用字符串作为参数而不是字符数组”字符串是字符数组,我知道。我指的是文本。srythx,这就是我想知道的。所以它存储在内存中,但我没有变量名来访问它,除非我声明一个pionter并用这个字符串初始化它。现在有趣的是,字符串是只读的,但是您可以使用指向非常量字符串的指针来访问它,从而触发崩溃。这是使用
s2
字符串显示的。这不是一个bug,它是C语言的一个特性。有人开玩笑说C是“高级汇编”——你可以看到原因。链接到以获取有关字符串文字的更多信息(仅用于完成)
#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
}