2009-11-05 6 views
2
typedef struct Value{ 
    int id; 
    char type; 
    char a; 
} Value; 

void fooV(Value v){ 
    v.id = 10; 
    v.type = 'L'; 
    v.a = 'R'; 
} 

int main(void){ 
    Value v; 
    Pointer p; 
    int id = 5; 
    char type = 't'; 
    char a = 'a'; 

    printf("id: %d, type: %c, a: %c \n",id,type,a); 

    v.a = a; 
    v.id = id; 
    v.type = type; 
    fooV(v); 
    printf("id: %d, type: %c, a: %c \n",id,type,a); 

} 

на вызове fooV, создается Локальное переменное значение ... поэтому никаких данных вызывающий не будут обновляться Но что, если я хочу, чтобы вернуть значения из fooV? что я должен добавить в fooV? Благодарявозвращаемых значений из структуры

+2

Просто примечание: структуры, как и все остальное на C, передаются по значению. Значение struct может быть огромным (в терминах 'sizeof struct'), поэтому прохождение указателей на структуры является хорошей привычкой. – pmg

ответ

10

Yo и нужно передать V в по ссылке, которая осуществляется с помощью указателей в C:

void fooV(Value* v) 
{ 
    (*v).id = 10; 
    (*v).type = 'L'; 
    (*v).a = 'R'; 
} 

Или используйте -> сокращенный оператор:

void fooV(Value* v) 
{ 
    v->id = 10; 
    v->type = 'L'; 
    v->a = 'R'; 
} 

И не забудьте передать адрес V в :

fooV(&v); 
+1

В качестве альтернативы вы можете вернуть конструкцию 'Value' из' fooV() ':' Value fooV (Value v); 'хотя она, вероятно, менее эффективна. –

+0

Я получил его на работу !!!! , но объясните ли вы разницу между (* v) .id = 10; и * (v) .id = 10; по какой-то причине, я думаю, что они такие же ... – user133466

+1

@metashockwave: Оператор «.» имеет более высокий приоритет, чем оператор «*», поэтому «* (v) .id» и «* v.id» будут интерпретироваться как «* (v.id)». Чтобы получить намеченное значение, то есть FIRST, следуйте указателю с помощью «*» и THEN, чтобы получить поле «id» в структуре, вам нужно написать «(* v) .id» или «v-> id» , –

5

Если вы просто хотите иметь fooV функцию, которая возвращает «сконструированный» Value-структуру, вы можете переписать fooV следующим образом:

Value fooV() { 
    Value v; 
    v.id = 10; 
    v.type = 'L'; 
    v.a = 'R'; 
    return v; 
} 

и вы могли бы назвать эту функцию как:

Value v = fooV(); 

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

Value fooV(Value v){ 
    v.id = 10; 
    v.type = 'L'; 
    v.a = 'R'; 
    return v; 
} 

в этом случае вы могли бы назвать это нравится:

v = fooV(v); 

или изменить fooV принимать указатель на Value:

void fooV(Value* v){ 
    v->id = 10; 
    v->type = 'L'; 
    v->a = 'R'; 
} 

в этом случае вы могли бы назвать это нравится:

fooV(&v); 
+0

Разве ваш первый пример не создаст значение v в стеке? Это может иметь некоторые действительно неприятные побочные эффекты ... –

+0

@Robert: Да, 'v' существует в стеке. Я не понимаю, почему это имеет значение, поскольку 'v' существует только до тех пор, пока функция не закончится, и никакие указатели или ссылки на' v' не будут пропущены из функции, поэтому нет способа получить к ней доступ после возвращения функции. –

+0

Верно, мое плохое. Я писал слишком много Java в последнее время :) –

1

И измените второй printf, чтобы использовать значения v, а не идентификатор переменной, тип, a.

printf("id: %d, type: %c, a: %c \n",v.id,v.type,v.a); 
Смежные вопросы