Если у Вас есть ноутбук с гибридной графикой, она может также возникнуть проблема, которую Вы испытываете. Затем Вы могли бы хотеть посмотреть проект Шмеля, который позволяет Вашей гибридной графике работать правильно.
В случае сомнений - спросите cdecl
$> cdecl
Type `help' or `?' for help
cdecl> explain int *columns[32]
declare columns as array 32 of pointer to int
EDIT В ответ на комментарии: Я нашел исходный код cdecl в Google Code Search . Для этого требуется библиотека GNU readline . Думаю, не составит труда скомпилировать его в Mac OS X или Windows.
Вы определяете массив из 32 указателей.
Чтобы определить указатель на массив из 32 целых чисел, вы должны сделать
int (*columns)[32];
Первое объявление создает экземпляр массива с пространством для 32 * sizeof (число). С другой стороны, последний создает единственный неинициализированный указатель, который затем можно использовать следующим образом:
int myintegers[32] = {0, 1, 2, ..., 31};
int (*columns)[32];
columns = &myintegers;
printf("%d\n", (*columns)[2]);
Надеюсь, я немного прояснил разницу.
Это массив из 32 указателей на int
, и да, это имеет значение.
Правила грамматики C указывают, что доступ к массиву ([]
) связывает более жестко, чем разыменование ( *
) и объявления отражают использование.
Объявление int * columns [32];
означает, что выражение * columns [n]
(где n
- число от 0 до 31) - это int
. Это выражение аналогично * (columns [n])
. В объявлении выделяется место для 32 указателей, но не выделено int
и (при условии, что это локальное объявление функции) ни один из указателей не инициализирован.
Если бы объявление было int (* столбцы) [32];
тогда выражение (* columns) [n]
было бы int
, что означает, что разыменование *
происходит до доступа к массиву, поэтому столбцы был бы указателем на массив из 32 int
s. В объявлении был бы выделен один указатель, но не было массивов int
s.
Тестовая программа показательна, особенно для тех из нас, кто не является знатоком языка:
$ gcc -x c -
#include <stdio.h>
int main(void)
{
int *columns[32];
printf("%lu\n%lu\n", sizeof(columns), sizeof(columns[0]));
return 0;
}
$ ./a.out
128
4
$
Она выглядит как массив указателей.
Вот несколько забавных объявлений для вас:
int *arrayOfIntP[32];
int (*pointerToArrayOf32)[32];
Для большего удовольствия с многомерными массивами посмотрите эти сообщения:
Один трюк - читать справа налево.
Дано int * cols [32];
Все, что осталось от array - это тип элементов в массиве. Итак, мы читаем его как массив указателей на int (и счетчик 32).
Расширение комментария к другому ответу:
Существует довольно простая процедура для чтения объявлений C. Начните с крайнего левого идентификатора в деклараторе и продолжайте работу, помня, что []
и ()
связываются перед *
. Учитывая объявление
int *columns[32];
, разбейте его как
columns -- columns
columns[32] -- is a 32-element array
*columns[32] -- of pointers
int *columns[32] -- to int.
Если бы объявление было
int (*columns)[32];
, то оно будет разбито как
columns -- columns
(*columns) -- is a pointer
(*columns)[32] -- to a 32-element array
int (*columns)[32] -- of int.
. Это также поможет вам создавать сложные объявления. Предположим, вы хотите объявить массив указателей на функции, возвращающие указатели на массивы char:
f -- f
f[N] -- is an N-element array
*f[N] -- of pointers
(*f[N])() -- to functions
*(*f[N])() -- returning pointers
(*(*f[N])())[M] -- to M-element arrays
*(*(*f[N])())[M] -- of pointers
char *(*(*f[N])())[M]; -- to char
cdecl - хороший инструмент, но после того, как вы проделаете это упражнение несколько раз, он вам не понадобится.
Я проделал это упражнение несколько раз, оно вам не понадобится. Я проделал это упражнение несколько раз, оно вам не понадобится.См. Вопрос № 5 из A 'C' Test: 0x10 Лучшие вопросы для потенциальных программистов встраиваемых систем Найджела Джонса *
a) int a; // Целое число
б) int * a; // Указатель на целое число
c) int ** a; // Указатель на указатель на целое число
d) int a [10]; // Массив из 10 целых чисел
e) int * a [10]; // Массив из 10 указателей на целые числа
f) int (* a) [10]; // Указатель на массив из 10 целых чисел
g) int (* a) (int); // Указатель на функцию a, которая принимает целочисленный аргумент и возвращает целое число
h) int (* a [10]) (int); // Массив из 10 указателей на функции, которые принимают целочисленный аргумент и возвращают целое число
* Увы, исходная статья на embedded.com больше не может быть найдена на их веб-сайтах.