2013-07-08 4 views
2

Я новичок в языке C и указателях в целом. Поэтому мое понимание этих двух вещей является основополагающим.Как эти два указателя отличаются друг от друга?

Я пытался создать структуру, которая содержит указатели на функции, ничего необычного. При этом; Я заметил, что это заявление:

int *func()
не работает. в то время как это на самом деле работает:

int (*func)()

В чем разница между ними? Это потому, что первый оператор является только указателем на целое число. в то время как другой указатель, как-то, указывает на функцию? Как так?

+0

функция объявлена ​​с '()' принимает неопределенное количество и тип (ы) аргументов. Это устаревшая форма, которая, вероятно, не должна использоваться в новом коде. Если ваша функция не принимает аргументов, используйте '(void)', а не '()'. (C++ использует '()' для обозначения никаких аргументов, но C++ - это другой язык.) –

ответ

9
int *func(void) 

Определяет функцию с именем func, который не имеет параметров и возвращает указатель на целое

int(*func)(void) 

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

Причина для этой разницы приоритет оператора. Parerenteses имеют более высокую точность, чем *. Поэтому в первом выражении int *func() скобки функций имеют наивысший приоритет и считаются первыми, поэтому связываются с символом func, поэтому компилятор знает, что func является символом для функции. Поэтому остальное - это возвращение.

Во втором случае int(*func)() есть дополнительный набор круглых скобок. Внутри первой круглой скобки мы видим *func. Поскольку скобка является наивысшей вероятностью (слева направо), компилятор должен интерпретировать содержимое этого набора ... *func - это указатель. ОК указатель на что? Посмотрите правду, и мы видим (), поэтому это указатель на функцию. Затем посмотрите влево, чтобы увидеть тип возврата.

Надеюсь, что это имеет смысл :) Также попробуйте How to interpret complex C/C++ declarations на CodeProject.com. В нем говорится о чем-то под названием «Правое право», которое является «... простым правилом, которое позволяет вам интерпретировать любое объявление ...». Это немного больше, чем на полпути вниз по странице ...

Также попробуйте cdecl: C gibberish ↔ English. Это довольно хорошая реализация утилиты cdecl.

enter image description here

+4

Функция, не принимающая аргументов в C, действительно должна быть объявлена ​​как '(void)', а не только '()'. – unwind

+0

Да, хорошая точка, +1 – Jimbo

+0

+1. Но cdecl.org не требует односимвольных идентификаторов. Это всего лишь некоторые ключевые слова (например, func, cast), которых следует избегать, по-видимому. Кроме того, я сомневаюсь, что скриншот необходим. –

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