Когда я читал книги о языке C, указатель на два уровня беспокоил меня много.
char s[5][5];
char *s[5];
char (*s)[5];
так в чем разница между ними?
Когда я читал книги о языке C, указатель на два уровня беспокоил меня много.
char s[5][5];
char *s[5];
char (*s)[5];
так в чем разница между ними?
В C лучше сказать декларацию. Затем он становится интуитивным. Для этого вы следуете правилу слева. Вот как это делается:
char *s[5];
Как вы это говорите? Для этого вы начинаете справа от имени переменной s, а затем идите влево. Итак, вы начинаете с того, что "s есть a/an". Справа вы видите [], и вы говорите, что s - массив... ". И затем вы идете влево и видите *, и говорите, что s - массив указателей. И это то, что есть. Это массив из 5 указателей. Вы можете хранить различные указатели в этом массиве.
Теперь для другого:
char (*s)[5];
Вы начинаете так же. "s является a/an", а затем просмотрите (). Все, что находится внутри (), привязано к s ближе чем что-либо снаружи. Таким образом, * более тесно связан с s чем []. Итак, теперь вы говорите: "s - это указатель...", и теперь вы выходите из круглой скобки и смотрите []. Итак, вы продолжаете: "s является указателем на массив". И это именно то, что есть. Это указатель, который указывает на первый элемент массива.
Теперь следуйте той же логике и попытайтесь угадать, что будет:
int (*callme)(int a, int b)
int (*callme[10])(int a, int b)
Подсказка, последняя может использоваться для создания таблиц поиска для функций.
Изменить:
Как уже упоминалось в комментариях, в начале есть также char. Я никогда не мог найти простой способ говорить об этом, но, как правило, ясно из контекста. Например, в первом примере char определяет тип массива, а во втором - определяет указатель. В упражнениях, которые я опубликовал, int определяет тип возвращаемых значений функций. Как правило, с такими определениями будет только один элемент с типом undefined. И вот как я понимаю, где идет тип.
В то время как объявление было рассмотрено, возможно, следует указать на различия в использовании:
char s[5][5]; -
s указывает на область выделенной памяти (куча, если глобальная, стек, если она локальная),s[0][0].. s[4][4] (или в s[0].. s[24]),sizeof(s) == 25. char *s[5]; -
s указывает на область выделенной памяти (куча, если глобальная, стек, если она локальная),s[0].. s[4],sizeof(s) == 40 (*). char (*s)[5]; -
s указывает не на любую выделенную память - это просто неинициализированный указатель в этой точке,&s,sizeof(s) == 8 (*).(*) note: предполагается 64-битная архитектура.
1.char s [5] [5];
Здесь s - двумерный массив с 5 строками и 5 столбцами. Где в этих 5 строках и 5 столбцах вы сохраните элемент символа типа.
2.char * s [5]; s - одномерный массив с 5 элементами, каждый элемент имеет указатель типа на символ.
3.char(* s) [5]; s - это указатель здесь не массива. S указывает на массив символов. например,
char arr[5][5];
char(*s)[5];
s = arr;
s [0] [0] будет таким же, как массив из arr [0] [0]