好朋友。我发现fopen的返回值有以下两种不同的方式:
1.
int main()
{
FILE* fp_file = NULL;
fp_file = fopen(file_path, "wb");
if(NULL == fp_file)
return RET_NULL_POINT;
else
return RET_OK;
}
2.
int _open_file(const char* ps_file_path, const char* ps_open_mode, FILE* fp_arg)
{
if(NULL == ps_file_path || NULL == ps_open_mode)
{ return RET_INV_ARG;}
fp_arg = fopen(ps_file_path, ps_open_mode);
if(NULL == fp_arg)
{ return RET_NULL_POINT;}
else
{ return RET_OK;}// fp_arg is NULL after fopen, but it return RET_OK, why?
}
int main()
{
FILE* fp_file = NULL;
int i4_ret = 0;
i4_ret = _open_file((const char*)file_path, "wb", fp_file);
if(RET_OK != i4_ret)
{// do sth NG}
else
{// do sth OK}
......//NULL_POINT exception will be caused at some place below.
}
2的file_path与1)相同。 1)的结果是返回RET_OK,2)的i4_ret的结果是RET_OK, 但是fp_file是NULL。 我想知道为什么1)的fp_file是正确的值,但在2)它是否为NULL? 1)和2)之间的fopen参数没有区别。
答案 0 :(得分:3)
这是因为传递给函数的params被复制(在这种情况下指针被复制)。所以当你打电话时:
_open_file((const char*)file_path, "wb", fp_file);
函数_open_file
正在获取指针fp_file
的副本,因此指针的副本在调用的函数中更新,而不是main
中的指针。
请参阅此thread以获取有关按值和引用传递变量的更多信息。
答案 1 :(得分:0)
FILE* fp_file = NULL;
...
i4_ret = _open_file((const char*)file_path, "wb", fp_file);
...
fp_arg = fopen(ps_file_path, ps_open_mode);
fp_file引用被视为作为函数_open_file的值发送。即使您尝试修改_open_file函数中的引用fp_file,在您离开函数后更改也不会成立。
即使您将指针作为参数发送到函数,在该函数中也不会修改通过该引用指向的内存区域的内容,您可以修改引用本身。它将作为局部变量复制到_open_file函数中,并仅在本地更改。
为了能够修改引用,您必须将函数作为参数发送给您的FILE引用。
FILE* fp_file = NULL;
...
i4_ret = _open_file((const char*)file_path, "wb", &fp_file);
...
*fp_arg = fopen(ps_file_path, ps_open_mode);
答案 2 :(得分:0)
FILE*
函数中有fp_file
main()
个_open_file()
。当您调用fp_arg
时,此指针将作为参数传递并存储在函数中的局部变量fp_arg
中。
然后,该函数修改此fopen()
变量以包含fp_file
返回的新指针。
main()
中的fp_arg
不会受_open_file()
变量的这些更改影响。当fp_file
返回时,{{1}}仍处于与其开始时相同的状态。
答案 3 :(得分:0)
好_open_file()
正常工作,但fp_arg = fopen(...)
指定另一个指向你的参数变量fp_arg
的指针,但不会传回。它就像你将一个int
传递给一个函数并在那里更改它一样。将_open_file()
的签名者更改为
int _open_file(const char* ps_file_path, const char* ps_open_mode, FILE** fp_arg)
按
设置 fp_arg的值*fp_arg = fopen()
并致电
i4_ret = _open_file((const char*)file_path, "wb", &fp_file);