Как изменить значение переменной, переданной в качестве аргумента? - PullRequest
0 голосов
/ 27 февраля 2012

Как изменить значение переменной, передаваемой в качестве аргумента в C? Я попробовал это:

void foo(char *foo, int baa){
    if(baa) {
        foo = "ab";
    } else {
        foo = "cb";
    }
}

и звоните:

char *x = "baa";
foo(x, 1);
printf("%s\n", x);

но печатает baa почему? заранее спасибо.

Ответы [ 4 ]

12 голосов
/ 27 февраля 2012

Вы хотите изменить, где char* указывает, поэтому вам нужно будет принять аргумент в foo() с еще одним уровнем косвенности ;char** (указатель на указатель char).

Поэтому foo() будет переписано как:

void foo(char **foo /* changed */, int baa)
{
   if(baa) 
   {
      *foo = "ab"; /* changed */
   }
   else 
   {
      *foo = "cb"; /* changed */
   }
}

Теперь при вызове foo() вы передадите указатель на x с использованием оператора адреса (&):

foo(&x, 1);

Причина, по которой ваш неверный фрагмент печатает baa, заключается в том, что вы просто назначаетеновое значение переменной local char *foo, которая не связана с x.Поэтому значение x никогда не изменяется.

4 голосов
/ 16 марта 2016

Ваш вопрос называется в общем виде. У вас уже есть ответы на ваши конкретные проблемы. Я собираюсь добавить пару иллюстративных примеров для типов int и double.

#include <stdio.h>

void incrementInt(int* in, int inc)
{
   *in += inc;
}

void incrementDouble(double* in, double inc)
{
   *in += inc;
}

int main()
{
   int i = 10;
   double d = 10.2;

   printf("i: %d, d: %lf\n", i, d);

   incrementInt(&i, 20);
   incrementDouble(&d, 9.7);

   printf("i: %d, d: %lf\n", i, d);
}

Выход:

i: 10, d: 10.200000
i: 30, d: 19.900000
4 голосов
/ 27 февраля 2012

Есть несколько проблем:

void foo(char *foo, int baa)
{
    if (baa) 
        foo = "ab";
    else 
        foo = "cb";
}

Этот код изменяет локальный указатель, но ничего с ним не делает. Чтобы скопировать строки, вам нужно использовать strcpy(), чтобы интерфейс оставался прежним:

void foo(char *foo, int baa)
{
    if (baa) 
        strcpy(foo, "ab");
    else 
        strcpy(foo, "cb");
}

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

char x[] = "baa";
foo(x, 1);
printf("%s\n", x);

Кроме того, вы можете сохранить x в качестве указателя и изменить интерфейс функции:

void foo(char **foo, int baa)
{
    if (baa) 
        *foo = "ab";
    else 
        *foo = "cb";
}

и вызывающая последовательность:

char *x = "baa";
foo(&x, 1);
printf("%s\n", x);

Оба механизма работают, но делают это по-разному. Есть разные наборы проблем с каждым. Не существует единственного решения «это лучше, чем это»; что лучше, зависит от обстоятельств, выходящих за рамки показанных фрагментов кода.

0 голосов
/ 27 февраля 2012

в функции foo, вы меняете аргумент foo только локально.когда функция foo заканчивается, аргумент x по-прежнему равен x.Вы не изменили это в foo.вы только скопировали его и назвали foo.

также посмотрите на комментарий @Greg Hewgill.

...