2016-04-22 2 views
0

В C это можно инициализировать массив строк с такой строкой кода:Строка инициализации массива в C

char *exStr[] = { "Zorro", "Alex", "Celine", "Bill", "Forest", "Dexter" }; 

На мой отладчик массив инициализируется, как показано ниже:

Debugger view

Этом отличается в качестве стандартного двумерного массива, где каждая строка занимает одно и то же количество байтов; может кто-то указать мне в правильном направлении, чтобы понять:

  1. Что означает именно объявление «char * exStr [] = ...»;
  2. Как я могу воссоздать структуру той же переменной из моей программы.
+0

Просто прочитайте заявление назад: 'полукокса * exStr [] ': массив указателей на символы. Каждый указатель указывает на первый символ в каждой строке с нулевым завершением. –

+0

Пожалуйста, не используйте странное форматирование, чтобы указать на что-то конкретное, используйте комментарии. –

+0

Ваш второй вопрос не ясен, вы можете уточнить? –

ответ

2

Что означает именно заявление «обугленного * exStr [] = {......};

Здесь exStr представляет собой массив указателей char, инициализируется входящие в комплект поставки инициализаторов.

Чтобы уточнить, начальный адрес каждого строки литерала в списке инициализатора сохраняется в каждом элементе массива.

Следует отметить, что содержимое элементов массива (, являющееся строковыми литералами), не поддается изменению.

Что касается второй части,

Как я могу воссоздать структуру того же переменной из моей программы.

непонятно. Можете ли вы рассказать об этой части?

На всякий случай, если вы имели в виду, как получить доступ, то это похоже на доступ к нормальному массиву. Пока вы находитесь в пределах границ, вам хорошо идти.

0

Для второй части вашего вопроса, я думаю, вы просите массив указателей на строки переменной длины.

Это можно сделать так:

#include <stdio.h> 

int main(void) { 
    char* ma[2]; // Array of char pointers for pointing to char-strings 

    char* pZorro = "Zorro";   // Char string - not modifiable 
    char AlexString[5] = {"Alex"}; // Char string - modifiable 

    ma[0] = pZorro;  // Make the first pointer point to the "Zorro" string 
    ma[1] = AlexString; // Make the second pointer point to the "Alex" string 

    printf("%s\n", ma[0]); 
    printf("%s\n", ma[1]); 

    // strcpy(ma[0], "x"); // Run time error! Can't change "Zorro" 
    strcpy(ma[1], "x");  // OK to change "Alex" 

    printf("%s\n", ma[0]); 
    printf("%s\n", ma[1]); 

    return 0; 
} 

Выход будет:

Zorro 
Alex 
Zorro 
x 
3

Что означает именно декларация "символ * exStr [] = ...";

Это означает «массив poniter to char». Char данные литералов типа «Zorro» обычно помещаются в сегменты данных только для чтения, а элементы массива включают только адрес первого символа литерала.

Как я могу воссоздать структуру той же переменной из моей программы.

Вы можете сделать что-то вроде:

char zorro[] = {'Z', 'o', 'r', 'r', 'o', '\0'}; // initialized every char for clarity 
char alex[] = "Alex"; 
char celine[] = "Celine"; 
... 
char* exStr[] = { 
    &zorro[0], // explicitly referenced for clarity 
    alex, 
    celine, 
    ... 
}; 
2

1. Как и другие ответы и комментарии сказал, выражение "символ * exStr []" означает "массив указателей на символ".

а) Как читать

Лучший способ читать его (а также другие более сложные заявления C), чтобы начать по имени твари (в данном случае «exStr») и работать ваш путь к концы декларации, как это:

  • Сначала идут вправо, добавляя каждый сталкивался значимый символ (ы) в значении выражения
  • Stop происходит прямо на первой закрывающей paranthesis «)», или когда выражение заканчивается
  • Когда yo u больше не может идти дальше, возобновить, где вы начали, и идти влево, снова добавляя каждый столкнутый символ к значению выражения
  • Остановитесь налево в скобках »(« что соответствует «)», который остановил вас справа , или в начале выражения
  • Когда вы остановились налево у "(" paranthethis и вы не достигли начала выражения, возобновите движение сразу после соответствующего ему ")"
  • Keep движение вправо и влево до тех пор, пока вы не достигнете полей выражения в обоих направлениях.

В вашем случае вы бы хотели:

  • старт на exStr: это имя переменной
  • идти направо: []: exStr является массив
  • идти направо: остановка: нет ничего там, Знак «=» останавливает нас
  • go left: *: exStr - это массив из указатели
  • налево: символ: exStr является массив из указателей к полукокса
  • налево: остановка: нет ничего там, "=" знак остановки нам

б) Почему вы видите, что каждый элемент массива занимает разное количество байт

Если у вас есть значение, подобное "Zorro", это строка C.
AC строка представляет собой массив байт, который начинается с заданным адресом в памяти и заканчивается 0. В случае "Zorro" она будет занимать 6 байт: 5 для строки, шестой по 0.

У вас есть несколько способы создания строк C. Несколько распространенными из них являются:
А) использовать его в буквальном смысле, например:

printf("Zorro"); 

B) использовать его literraly но хранить его в переменной:

char *x = "Zorro"; 

C) выделяют динамически и копировать данные в него

size_t n = 2; 
char *p = malloc((n+1) * sizeof(char)); 
char c = getch(); // read a character from the console 
p[0] = c; 
p[1] = 0; 
// do something with p... 
free(p); 

Всякий раз, когда вы помещаете значение строки, как "Zorro" в вашей программе, компилятор будет зарезервировать память для достаточно просто удерживайте эту строку плюс 0-терминатор. Он будет инициализировать эту память с помощью того, что вы указали внутри "", оно добавит 0 и тайно сохранит указатель на эту память. Это не позволит вам изменить эту память (вы не можете изменить эту строку).
В вашем примере кода он сделал это для каждой строки, которая появилась в инициализации exStr.
Вот почему вы видите, что каждый элемент массива занимает различный объем памяти. Если вы посмотрите ближе к выходу отладчика, вы увидите, что зарезервированная память компилятора для строки сразу после предыдущей, и каждая строка занимает свою длину в байтах плюс терминатор 0. Например. «Zorro» начинается с 02f и занимает позиции 02f - 034, которые составляют 6 байт (5 для Zorro и 1 для терминатора 0). Затем «Алекс» начинается с 035, занимает 5 байт: 035 - 039 и т. Д.

2. Чтобы создать подобный массив программно:

Если все у вас есть некоторые статические строки, как в вашем примере, то ваш пример кода достаточно хорошо.

В противном случае, если вы планируете поставить динамические значения в массиве (или, если вы планируете изменить исходные строки в программе), вы могли бы сделать что-то вроде:

#define COUNT 5 
char *strings[COUNT]; 
int i; 
for (i = 0; i < COUNT; i++) { 
    int n = 32; // or some other suitable maximum value, or even a computed value 
    strings[i] = malloc((n+1) * sizeof(char)); 
    // put up to 32 arbitrary characters into strings[i], e.g. read from a file or from console; don't forget to add the 0 terminator 
} 
// use strings... 
// free memory for the strings when done 
for (i = 0; i < COUNT; i++) { 
    free(strings[i]); 
} 
Смежные вопросы