ptr_array_type
псевдонимы int (*)[3]
, а не int *
- вы не сможете использовать его для перебора array_type
.Вы могли бы использовать его для перебора массива из array_type
, например:
array_type arr[3];
ptr_array_type ptr = arr;
while ( size_t i = 0; i < 3; i++ )
do_something_with( ptr[i] );
Если вы хотите иметь возможность перебирать массивT
с указателем, тогда тип этого указателя должен быть T *
.Поэтому вам нужно изменить ваши typedefs на что-то вроде
typedef int array_type[3]; // probably want to replace int with another
typedef int *ptr_array_type; // typedef to abstract out the type
...
array_type a = {1, 2, 3}; // yuck! don't do this! a is not obviously an array,
// so an array initializer looks wrong in this context
ptr_my_type p = a;
printf( "%d", *p );
Однако ...
Если вы используете typedef
, чтобы абстрагировать детали реализации для типа, то выследует абстрагироваться от всех деталей реализации для этого типа, включая такие вещи, как разыменование и подписка.Вы захотите создать полный API, такой как:
array_type *arr = new_array_type( 1, 2, 3 ); // even this is leaky since it assumes we know
// the array element type is integral
array_type_iterator *itr = new_array_type_iterator( arr );
array_element_type target;
begin_iterator( &itr );
while( next_iterator( &itr ) )
{
get_data_from_iterator( itr, &target );
write_array_element_to( stdout, target );
}
free_array_type_iterator( itr );
free_array_type( arr );
Частичные или неплотные абстракции просто ведут к коду, который запутывает использование и обслуживание.Если пользователь типа должен знать о «массивности» или «указателе» этого типа, чтобы правильно его использовать, не скрывайте эти качества за определением типа, не предоставляя замены для []
иунарные *
операторы.Также предоставьте некоторый способ абстрагирования ввода / вывода - не заставляйте пользователя знать, использовать ли %d
или %f
или %s
в операторе printf
, если они не работают с примитивомтип.