В чем разница между char * s [] и char (* s) []?

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

char s[5][5];
char *s[5];
char (*s)[5];

так в чем разница между ними?

Ответ 1

В 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. И вот как я понимаю, где идет тип.

Ответ 2

  • сначала является 2-мерным массивом char
  • second - это массив указателя на char
  • third - указатель на массив char

Ответ 3

В то время как объявление было рассмотрено, возможно, следует указать на различия в использовании:

char s[5][5]; -

  • s указывает на область выделенной памяти (куча, если глобальная, стек, если она локальная),
  • вы можете безопасно записать до 25 char значений в s[0][0].. s[4][4] (или в s[0].. s[24]),
  • sizeof(s) == 25.

char *s[5]; -

  • s указывает на область выделенной памяти (куча, если глобальная, стек, если она локальная),
  • вы можете безопасно записать до 5 значений указателя в s[0].. s[4],
  • sizeof(s) == 40 (*).

char (*s)[5]; -

  • s указывает не на любую выделенную память - это просто неинициализированный указатель в этой точке,
  • вы можете безопасно записать одно значение указателя в &s,
  • sizeof(s) == 8 (*).

(*) note: предполагается 64-битная архитектура.

Ответ 4

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]