通过两种不同的方式调用fopen后,返回值不同

时间:2013-07-09 14:43:53

标签: c linux fopen

好朋友。我发现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参数没有区别。

4 个答案:

答案 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);