Различие между указателями на переменные и указателями на структуры в C

В изучении C, я только что начал изучать указатели на структуры и имею некоторые вопросы.

Предположим, что я должен был создать названную структуру myStructure, и затем создайте указатель myStructurePointer, указывая myStructure. *myStructurePointer, и myStructure два способа сослаться на то же самое? Если так, почему необходимо иметь-> оператор? Кажется более простым использовать *myStructurePointer.variable_name чем myStructurePointer->variable_name.

6
задан Carl Norum 20 February 2010 в 01:19
поделиться

6 ответов

Для расширения ответа основной задачей является создание роли базы данных и назначение ей разрешений. Для этого вам нужен какой-то модный динамический SQL, например:

Set @Routines = Cursor Fast_Forward For
    Select ROUTINE_SCHEMA + '.' + ROUTINE_NAME, ROUTINE_TYPE, DATA_TYPE
    From INFORMATION_SCHEMA.ROUTINES
    Where ROUTINE_NAME NOT LIKE 'dt_%'
        Or ROUTINE_TYPE = 'FUNCTION'

Open @Routines
Fetch Next From @Routines Into @Procname, @RoutineType, @DataType

While @@Fetch_Status = 0
Begin
    Set @Msg = 'Procname: ' + @Procname + ', Type: ' + @RoutineType + ', DataType: ' + Coalesce(@DataType,'')
    Raiserror(@Msg, 10, 1) WITH NOWAIT

    If @RoutineType = 'FUNCTION' And @DataType = 'TABLE'
        Set @SQL = 'GRANT SELECT ON OBJECT::' + @Procname + ' TO StoredProcedureDataReader'
    Else
        Set @SQL = 'GRANT EXECUTE ON OBJECT::' + @Procname + ' TO StoredProcedureDataReader'

    exec(@SQL)

    Fetch Next From @Routines Into @Procname, @RoutineType, @DataType
End

Close @Routines
Deallocate @Routines

Этот код предоставит EXECUTE хранимым процедурам и скалярным функциям, а SELECT - определяемым пользователем функциям, которые возвращают тип TABLE.

-121--2396168-

Обходной путь: Задайте изображение как фон элемента контейнера, затем добавить радиус границы на элемент.

Это не будет работать, если только изображение не будет точно такого же размера. Если вы не используете новое свойство css в firefox 3.6, которое позволяет для размера фонового изображения, но вряд ли кто-то уже находится на 3.6.

Поэтому я согласен с Алексом, то есть если вы сделаете изображение размером div/other elm.

-121--1066887-

Вы правы,

(*structurePointer).field

это точно то же самое, что и

structurePointer->field

Однако у вас есть:

*structurePointer.field

Что действительно пытается использовать . оператор для переменной указателя, а затем отмена привязки результата - он даже не будет скомпилирован. Если нужно, чтобы выражения были эквивалентны, вам нужны круглые скобки, как у меня есть в первом примере выше. Стрелка сохраняет по крайней мере пару нажатий клавиш в этом простом случае.

Использование - > может иметь больше смысла, если задуматься о случае, когда поле структуры имеет тип указателя, возможно, на другую структуру:

structurePointer->field->field2

против.

(*(*structurePointer).field).field2
8
ответ дан 8 December 2019 в 13:45
поделиться

Деннис Ритчи однажды заметил, что deref, вероятно, должен был быть постфиксным оператором1

Верно, следующее эквивалентно:

pointer->field
(*pointer).field
pointer[0].field

Если бы оператор перенаправления имел постфиксный синтаксис, язык Си выглядел бы совсем иначе, но в этом случае вообще не было бы необходимости в ->.

Интересно подумать о том, как выглядели бы обычные идиомы языка Си в этой альтернативной вселенной...

do s1++* = c = s2++*;
   while(c);

while(n-- > 0)
    s++* = '\0';

p*.x = 1;
p*.y = 2;
. . .
. . .
. . .

1. См. "Развитие языка Си , Деннис М. Ричи (Dennis M. Ritchie)

1
ответ дан 8 December 2019 в 13:45
поделиться

Недавно я изучал язык C, и этот ресурс оказался для меня чрезвычайно полезным.

http://claymore.engineer.gvsu.edu/~steriana/226/C.CheatSheet.pdf

-1
ответ дан 8 December 2019 в 13:45
поделиться

Проблема с *myStructurePointer.variable_name заключается в том, что * связывается менее жестко, чем , поэтому он будет интерпретирован как *(myStructurePointer.имя_переменной). Эквивалентом myStructurePointer->имя_переменной будет (*myStructurePointer).имя_переменной, где скобки обязательны.

Между a->b и (*a).b нет разницы, но -> проще использовать, особенно если есть вложенные структуры. (*(*(*a).b).c).d гораздо менее читабелен, чем ´a->b->c->d`.

5
ответ дан 8 December 2019 в 13:45
поделиться

Чтобы обобщить, изучите приоритет ваших операторов C:

Здесь "." оператор обрабатывается перед "*" -> отсюда необходимость в круглых скобках

4
ответ дан 8 December 2019 в 13:45
поделиться

Использование * разыменовывает указатель, поэтому вы можете использовать синтаксис с точкой для доступа к полям. Если вы не разыменовываете указатель, вы используете -> для доступа к полям. Вы можете использовать то, что вам больше нравится.

0
ответ дан 8 December 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: