Массив символов или строка программирования C как параметр функции

Если я, например, определяю массив

char string[20] = "something";

И функция

void f(char* somestring[])

Что это, адрес или номер или что и как с этим работать? В каких целях используется?

string — это множество из 20 char с. somestring — это указатель для указателя на char.
John Bollinger 18.03.2019 21:28

Последняя часть вопроса слишком широка, чтобы ответить здесь.

John Bollinger 18.03.2019 21:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
47
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Во-первых, адрес — это число. Затем тип char *foo[] (который на самом деле просто char **foo) имеет несколько интерпретаций эквивалент.

  1. foo — массив с двойным индексом char.
  2. foo — это указатель на массив char (то есть строку, если она завершается нулем, как строковый литерал).
  3. и, вероятно, самый редкий случай использования, foo — это указатель на указатель на значение char.

Его также можно использовать несколькими способами.

  1. foo — двумерный массив символов; затем foo[x][y] возвращает вам символ в массиве в строке x и столбце y.
  2. foo — указатель на строку. Затем (*foo)[x] дает вам x-й символ строки.
  3. Используйте **foo, чтобы установить значение char, и *foo, чтобы изменить символ, на который указывает указатель.

РЕДАКТИРОВАТЬ: конечно, все они составные и эквивалентны. Например, foo[0][0] — это просто (*foo)[0], а это просто **foo.

string — это массив из 20 элементов char — вы можете хранить нить до 19 символов (необходимо зарезервировать один элемент для ограничителя строки) или вы можете хранить последовательность из 20 символов, которая представляет нет строку (например, хеш-значение или что-то в этом роде).

За исключением случаев, когда это операнд оператора sizeof или унарного &, выражение типа «N-элементный массив T» будет преобразован («распад») в выражение типа «указатель на T», и его значение будет адрес первого элемента массива.

Итак, если вы передали string в качестве аргумента функции, вот так:

f( string );

то, что функция фактически получает, является значением указателя:

void f( char *somestring ) { ... }

В контексте объявления параметра функции (и Только в этом контексте) T a[N] и T a[] обрабатываются как T *a, поэтому вы можете объявить f любым из

void f( char somestring[20] ) { ... }

или

void f( char somestring[] ) { ... }

также.

Оператор индекса [] предназначен для работы с выражениями указателя, а также с выражениями массива, поэтому вы все равно можете использовать [] для индексации в somestring, как и любой другой массив:

void f( char *somestring )
{
  int i = 0;
  while ( somestring[i++] )
  {
    // do something interesting with somestring[i]
  }
}

Итак, если void f( char *somestring ) такое же, как void f( char somestring[] ), то что мы делаем из

void f( char *somestring[] )

?

В этом случае ясно, что somestring должен быть массивом указатели наchar, что-то вроде

char *strings[] = {"foo", "bar", "bletch", ... };

Каждый strings[i] хранит адрес соответствующего строкового литерала, а не содержимое самой строки. По тому же правилу, что и выше, прототип может быть записан как

void f( char **somestring ) { ... }

или

void f( char *somestring[N] ) { ... }

Одна вещь somestrings — это нет, в данном случае это двумерный массив char. Если бы strings было объявлено

#define N ... // number of strings
#define M ... // maximum length of string

char strings[N][M+1] = {"foo", "bar", "bletch", ... };

то, если мы перейдем от strings к f, оно «распадется» до

void f( char (*somestrings)[M+1] ) { ... }

Тип strings - это «массив N-элементов из M+1-элементного массива char», поэтому выражение «распадается» до «указатель на M+1-элементный массив char».

Другие вопросы по теме