2017-02-21 5 views
2

Я столкнулся со следующей проблемой, и я не мог найти никаких конкретных объяснений: почему C не хочет предоставлять определения типов? Не определяет макрос BOOL так же хорошо, как определение типа Bool, используя typedef?Почему C не требует определения типов?

Например, #define директива может использоваться, чтобы создать макрос, который может быть использован в качестве логического типа:

#define Bool int 

Там еще один способ создать логический тип, используя функцию, известную как определение типа.

typedef int Bool; 

Почему последний метод предпочтительнее? Каковы преимущества?

+1

В C отсутствует макрос BOOL, а также встроенный тип 'bool'. Существует, однако, boolena тип '_Bool', который следует использовать вместо homeprew' typedef 'или макросов. На ваш вопрос: это ** не ** предпочтительнее и сильно обескуражен. – Olaf

+1

Обратите внимание, что C '' Bool' является типом, отличным от результата 'typedef int Bool;' OP во многих функциональных атрибутах. «Bool» здесь не является хорошим примером для демонстрации проблем OP с 'typedef' и' # define'. – chux

+0

@chux: пример, где они различаются: '_Bool b = 5; printf (% d ", b);'. Попробуйте это с помощью 'typedef'ed' int'. – Olaf

ответ

8

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

Например

#define MAX 5 

//some use of MAX 

#undef MAX 
#define MAX 10 

// some more use of MAX 

вполне допустимо, но попытка сделать что-то вроде

typedef int into; 

///something.... 

typedef char into; 

является недействительным, так как «тип» уже определен ранее.

Таким образом, typedef, который создает псевдоним для «типа», считается более последовательным в этом отношении.

+3

* «Итак, с одной точки зрения, typedef более определенно». * - Это лучшее, что я услышал сегодня :) Я бы выбрал дважды, если мог, только для этого. Просто не спрашивайте меня, почему мне это так нравится, потому что я понятия не имею. – StoryTeller

+3

@StoryTeller Дважды не очень хороший вариант, идите трижды. :П –

10

Существует два важных различия между определениями типов и определениями макросов.

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

#define PTR_TO_INT int * 

Декларация

PTR_TO_INT p, q, r 

станет

int * p, q, r 

после предварительной обработки. К сожалению, толькоp - указатель; q и r являются обычными целочисленными переменными. Определения типов не имеют этой проблемы.

Во-вторых, typedef имена подчиняются тем же правилам сферы, что и переменные; a typedef имя, определенное внутри тела функции, не будет распознано вне функции. С другой стороны, имена макросов заменяются препроцессором, где бы они ни появлялись.

+1

Объектные указатели никогда не должны быть 'typedef'ed в любом случае. И массивы только если хорошо подумали. – Olaf

+1

Слабость здесь заключается в том, что обсуждаются проблемы '#define PTR_TO_INT int *', но решение с использованием 'typedef' не показано '- IOWs, односторонний аргумент. 'typdef int * ptr_to_int;' не является идеальным решением для эфира. – chux

+1

@chux "' typdef int * ptr_to_int; 'не является идеальным решением для эфира". Конечно, он побеждает над #define PTR_TO_INT int *. В такой ситуации я не вижу, что случилось с 'typedef'. 'typedef', безусловно, делает сложные определения и декларации, такие как указатели на функции в структурах, которые выполняют функции в качестве аргументов, намного легче понять. –

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