2015-02-11 2 views
0

я хотел бы спросить, почему это возможно изменить значение указателя файла в функции C без прохождения ссылки на него, что я имею в виду:изменение файла указатель внутри функции C

void fun(FILE *f) 
{ 
    fclose(f); 
    f = fopen("newfile", "r"); 
} 

int main(void) 
{ 
    FILE *old = fopen("file", "r"); 
    char *msg = (char*)malloc(sizeof(char) * 100); 
    fun(old); 
    fscanf(old, "%s", msg); 
    printf("%s", msg); 
    free(msg); 
    return 0; 
} 

Может кто-нибудь объясните это мне? Я думал, что указатели копируются, поэтому я ожидал получить сообщение об закрытом файле. Удивительно, но я этого не понял.

+0

Стандартное предупреждение: Пожалуйста, [не использовать] (http://stackoverflow.com/q/605845/2173917) возвращаемое значение 'malloc()' и family. –

+0

@SouravGhosh С тех пор, когда вы не лишили void * к типу, вам нужно стать хорошей практикой? – BitTickler

+0

@ user2225104 Ликвидация возвращаемого значения, например. 'malloc' может скрывать предупреждения, заданные, когда' malloc' не были надлежащим образом прототипированы (например, когда программист забыл включить '') –

ответ

2

Аргументы в C передаются по значению, а это значит, что они скопированы. Таким образом, функции никогда не имеют первоначальных значений, просто копий и модификации копии, конечно, не будут изменять оригинал.

Вы можете эмулировать пройти по ссылке с помощью указателей, а также в случае передачи указателя по ссылке вы, конечно, должны передать указатель на указатель (используя адрес-оператора &).

void fun(FILE **f) 
{ 
    fclose(*f); 
    *f = fopen("newfile", "r"); 
} 

... 

fun(&old); 
+0

Я знаю, что происходит по значению. Дело в том, что, хотя я не передаю аргумент как указатель на указатель, как вы здесь, я получаю изменение указателя в главном. – greenshade

+0

@greenshade Я могу пообещать вам, что указатель 'old' does * not * изменит значение в' main' после вызова. Если это работает, это связано с [* неопределенным поведением *] (http://en.wikipedia.org/wiki/Undefined_behavior). –

+0

Спасибо, это ответ, который я хотел получить. Хотя мне кажется странным, потому что я получил код из своего университета, и они сказали мне закрыть файл внутри функции и снова открыть его, но указатель передается копией. Может быть, это просто опечатка. – greenshade

0

Скопировано, но оно по-прежнему указывает на тот же файл.

+0

Я не понимаю. Внутренняя функция указателя указывает на файл, открытый в основной функции, но я закрыл этот файл и назначил новый указатель на переменную f, и он не должен влиять на переменную old в главной функции. – greenshade