2012-04-11 2 views
7

Как передать параметр как char * в качестве ссылки?char * как ссылка в C

Моя функция использует таНос()

void set(char *buf) 
{ 
    buf = malloc(4*sizeof(char)); 
    buf = "test"; 
} 

char *str; 
set(str); 
puts(str); 

ответ

17

Вы передаете адрес указателя:

void set(char **buf) 
{ 
    *buf = malloc(5*sizeof(char)); 
    // 1. don't assign the other string, copy it to the pointer, to avoid memory leaks, using string literal etc. 
    // 2. you need to allocate a byte for the null terminator as well 
    strcpy(*buf, "test"); 
} 

char *str; 
set(&str); 
puts(str); 
+3

4 символа недостаточно, чтобы удерживать строку, хотя :) Может быть, 'sizeof (" test ")' будет лучше. –

+1

Я получаю это после публикации. См. Править. – MByD

+3

'sizeof (char)' is '1', всегда. –

1

С проходит по значению. Нет пропусков.

+0

В информатике, передать по ссылке означает передать адрес переменной. C++ создал определение, отличное от нормы в информатике. Это не делает определение C++ нормой, и вопрос о C во всяком случае. Передача по ссылке в C означает передачу указателем. C11 6.2.5 'Тип указателя может быть получен из типа функции или типа объекта, называемого ссылочным типом. Тип указателя описывает объект, значение которого предоставляет ссылку на объект ссылочного типа. Тип указателя, полученный из ссылочного типа T, иногда называют «указателем на T». – Lundin

+0

@ Lundin У вас есть ссылка на «В информатике, передайте по ссылке средство передать адрес переменной»? AFAIK термин проходит по ссылке, и его синонимы использовались в их текущем значении, начиная с Fortran и Pascal, задолго до C++. – Joni

+0

Я думаю, мы можем согласиться с тем, что в общем случае информатика имеет только пропускную ценность или пропускную способность. C и C++ поддерживает исходную версию pass-by-reference, называемую указателями, которая позволяет вам изменить фактический адрес ссылки, если хотите. Эта функция не останавливает параметры указателя от передачи по ссылке. В C++ они решили создать альтернативный синтаксис для передачи по ссылке, с типом ссылки C++. После этого программисты на С ++ начали полагать, что синтаксис указателя больше не передавался по ссылке. Не спрашивай меня, почему. -> – Lundin

5

Вы должны передать его как указатель на указатель:

void set(char **buf) 
{ 
    *buf = malloc(5 * sizeof(char)); 
    strcpy(*buf, "test"); 
} 

Позвони это так:

char *str; 
set(&str); 
puts(str); 
free(str); 

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

Я также использую strcpy для копирования строки в выделенную память. Это связано с тем, что вы переписываете указатель иначе, то есть вы теряете указатель, который вы выделяете, и будете иметь утечку памяти.

Вы должны также помнить free указатель, когда вы закончите с ним, или память останется выделенной до завершения программы.

+2

Пожалуйста, укажите, почему у вас есть «5» вместо «4». Я съежился, когда увидел ОП. –

+0

@ D.Shawley Уже сделано. –

+0

+1 потому что упоминается «чтобы освободить указатель». – Kakashi

4

C не поддерживает передачу по ссылке. Но вы можете передать указатель на указатель, и установить, что:

void set(char **buf) 
{ 
    *buf = malloc(5*sizeof(char)); //5, to make room for the 0 terminator 
    strcpy(*buf,"test"); //copy the string into the allocated buffer. 
} 

char *str; 
set(&str); 
puts(str); 
+0

В информатике, передать по ссылке означает передать адрес переменной. C++ создал определение, отличное от нормы в информатике. Это не делает определение C++ нормой, и вопрос о C во всяком случае. Передача по ссылке в C означает передачу указателем. C11 6.2.5 'Тип указателя может быть получен из типа функции или типа объекта, называемого ссылочным типом. Тип указателя описывает объект, значение которого предоставляет ссылку на объект ссылочного типа. Тип указателя, полученный из ссылочного типа T, иногда называют «указателем на T». – Lundin

+0

Обычно обычно различают значение «проход за» и «пересылка по ссылке», в котором ссылка передается неявно. Говорят, что многие языки, такие как C, поддерживают только пропускную способность, хотя вы можете эмулировать pass-by-reference, явно передавая указатель на все, что вам нужно для ссылки. (Этот указатель передается по значению, хотя) - так Я не согласен с вашим определением. – nos

+0

Не соглашайтесь с тем, что вам нравится, это не мое определение, это определение стандарта C, что ссылка на языке C. В примере OP buf является ссылкой на тип char. Тот факт, что эта ссылка сама по себе передается по значению, является другим вопросом. – Lundin

3

Вы передать указатель на указатель, char**: нет ссылки на C.

void set(char** buf) 
{ 
    *buf = malloc(5); /* 5, not 4: one for null terminator. */ 
    strcpy(buf, "test"); 
} 

Обратите внимание, что:

buf = "test"; 

не копирует "test" в buf, но указывает buf на адрес строки буквального "test". Для копирования используйте strcpy().

Помните free() возвращенного буфера, когда больше не требуется:

char* str; 
set(&str); 
puts(str); 
free(str); 
+0

В информатике, передать по ссылке означает передать адрес переменной.C++ создал определение, отличное от нормы в информатике. Это не делает определение C++ нормой, и вопрос о C во всяком случае. Передача по ссылке в C означает передачу указателем. C11 6.2.5 'Тип указателя может быть получен из типа функции или типа объекта, называемого ссылочным типом. Тип указателя описывает объект, значение которого предоставляет ссылку на объект ссылочного типа. Тип указателя, полученный из ссылочного типа T, иногда называют «указателем на T». – Lundin

-1

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

От Керниган & Ритчи:

(K & R 2, 1,8 Вызов по значению) "В C все аргументы функции передаются по "значение""

Чтобы изменить указатель T, вы можете иметь указатель на указатель на T как тип аргумента функции.

+0

В информатике пропуск через ссылочное средство передает адрес переменной. C++ создал определение, отличное от нормы в информатике. Это не делает определение C++ нормой, и вопрос о C во всяком случае. Передача по ссылке в C означает передачу указателем. C11 6.2.5 'Тип указателя может быть получен из типа функции или типа объекта, называемого ссылочным типом. Тип указателя описывает объект, значение которого предоставляет ссылку на объект ссылочного типа. Тип указателя, полученный из ссылочного типа T, иногда называют «указателем на T». – Lundin

+0

Я не согласен. Использование формулировки * pass-by-reference * в C может только немного запутать новичков: в C нет ссылки, как есть на C++. В отличие от других языков нет двух (или более) разных способов передачи аргументов функции в C, вы можете просто пройти по значению; и аргументы указателей передаются так же, как и любой другой аргумент. И я думаю, что цитата C в §6.2.5 не имеет ничего общего с передачей по ссылке. – ouah

+0

кстати для downvoter, я не буду удалять этот ответ, поскольку я не думаю, что он заслуживает '-1' :) – ouah

Смежные вопросы