2015-05-04 2 views
1

Когда я прочитал чей-то код, я наткнулся на незнакомый код. Код как следующее:.?Что означает «#define setId (ptr, value) ((ptr) -> id = (value), 0)

struct Employee { 
    int id; 
}; 
#define getId(ptr) ((ptr)->id) 
#define setId(ptr, value) ((ptr)->id = (value), 0) 

Я не мог понять, из ((ptr)->id = (value), 0) ли этот макрос так же, как ((ptr)->id = (value)

+0

'' 'является оператором запятой. –

+1

Вы переключали 'имя' и' id' при расшифровке кода? 'name' не используется в расширении макроса. 'id', который используется в расширении макроса, не является одним из параметров макроса. –

+0

кажется сложным .. может кто-нибудь подумать о сценарии, где это полезно? –

ответ

1

Я не мог понять, из «((PTR) -> id = (id), 0) ". ? Является ли этот макрос такой же, как "((PTR) -> ID = (идентификатор)"

Предполагая, что определение макроса:

#define setId(ptr, name) ((ptr)->id = (name), 0) 

Если есть выражение

a = setId(ptr, name); 

она расширена до

a = ((ptr)->id = (name), 0); 

Когда это выражение выполняется, значение a - 0, который является значением выражения для запятой ((ptr)->id = (name), 0). Побочным эффектом оценки выражения является то, что объект id объекта, на который указывает ptr, установлен в name.

0

код вы вывесили кажется ошибочным:

#define setId(ptr, name) ((ptr)->id = (id), 0) 

Макрос setId должен, вероятно, использовать аргумент name вместо некоторого локального идентификатора id. Если name является целым числом, оно может быть таким:

#define setId(ptr, name) ((ptr)->id = (name), 0) 

В противном случае, это может быть что-то вроде этого:

#define setId(ptr, name) ((ptr)->id = nameToId(name), 0) 

Что касается , 0) части, это экземпляр оператора запятая: макро расширяется до выражения, которое оценивает присвоение, а затем оценивает 0. В случае, если используется результат setId(ptr, name), его значение будет всегда 0. Конструкция, подобная этой, не очень читаема и, вероятно, будет генерировать предупреждения для некоторых компиляторов.

1

Я не мог понять ((ptr)->id = (id), 0). Этот макрос такой же, как ((ptr)->id = (id)?

, является comma operator used in a complex return context в макропроцессоре препроцессора.

Так что, когда вы будете называть вас макросом, он установит идентификатор сотрудника, а затем вернет 0 (это просто дизайнерское решение программиста, возможно, предназначенное для возврата 0 как означающее «без ошибок»).

Но, как отметил другие люди в комментариях, макрос, вероятно, имеет погрешность в определении, это, вероятно, следует выглядеть следующим образом:

#define setId(ptr) ((ptr)->id = (id), 0) 
0

Эти макросы заменяют функции «сеттер» и «геттер». Предполагая, что «сеттер» должен возвращать 0 в случае успеха и -1 в случае неудачи, функция будет выглядеть следующим образом

int getId(struct Employee *ptr) 
{ 
    return(ptr->id); 
} 

int setId(struct Employee *ptr, int value) 
{ 
    ptr->id = id; 
    return 0;  // this setter always succeeds 
} 

Замена сорбент с макро прост. Замена установщика немного сложнее, так как вам нужно «вернуть» правильное значение. Здесь полезен оператор запятой.

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

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