Передача аргумента указателя по ссылке в C? - PullRequest
8 голосов
/ 01 декабря 2009
#include <stdio.h>
#include <stdlib.h>

void
getstr(char *&retstr)
{
 char *tmp = (char *)malloc(25);
 strcpy(tmp, "hello,world");
 retstr = tmp;
}

int
main(void)
{
 char *retstr;

 getstr(retstr);
 printf("%s\n", retstr);

 return 0;
}

gcc не скомпилирует этот файл, но после добавления #include <cstring> я мог бы использовать g ++ для компиляции этого исходного файла.

Проблема в том, поддерживает ли язык программирования C аргумент указателя по ссылке? Если нет, то почему?

Спасибо.

Ответы [ 6 ]

29 голосов
/ 01 декабря 2009

Нет, C не поддерживает ссылки. Это по замыслу. Вместо ссылок вы можете использовать указатель на указатель на языке C. Ссылки доступны только на языке C ++.

20 голосов
/ 01 декабря 2009

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

void getstr(char ** retstr)
{
    char *tmp = (char *)malloc(25);
    strcpy(tmp, "hello,world");
    *retstr = tmp;
}

int main(void)
{
    char *retstr;

    getstr(&retstr);
    printf("%s\n", retstr);

    // Don't forget to free the malloc'd memory
    free(retstr);

    return 0;
}
5 голосов
/ 01 декабря 2009

Попробуйте это:


void
getstr(char **retstr)
{
 char *tmp = (char *)malloc(25);
 strcpy(tmp, "hello,world");
 *retstr = tmp;
}

int
main(void)
{
 char *retstr;

 getstr(&retstr);
 printf("%s\n", retstr);

 return 0;
}
2 голосов
/ 02 декабря 2009

Это должен быть комментарий, но он слишком длинный для поля комментария, поэтому я делаю его CW.

Код, который вы указали, лучше написать следующим образом:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
getstr(char **retstr)
{
    *retstr = malloc(25);
    if ( *retstr ) {
        strcpy(*retstr, "hello,world");
    }
    return;
}

int
main(void)
{
    char *retstr;

    getstr(&retstr);
    if ( retstr ) {
        printf("%s\n", retstr);
    }
    return 0;
}
1 голос
/ 31 июля 2012

В libgmp есть интересный трюк, который эмулирует ссылки: typedef mpz_t __mpz_struct[1];

и тогда вы можете написать так:

mpz_t n;
mpz_init(n);
...
mpz_clear(n);

Я бы не рекомендовал использовать этот метод, потому что он может быть непонятен для других, он все еще не защищает от того, чтобы быть NULL: mpz_init((void *)NULL), и он настолько же многословен, как и его указатель-указатель.

0 голосов
/ 01 декабря 2009

C lang не имеет ссылочных переменных, но входит в C ++ lang.

Причина введения ссылки состоит в том, чтобы избежать висящих указателей и предварительная проверка на недействительность указателей.

Вы можете рассматривать ссылку как константный указатель , то есть константный указатель может указывать только на данные, на которые он был инициализирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...