2013-04-29 4 views
0

Как я могу объявить массив массивов char *? (Когда значения будут заполнены позже в моей программе ..) Это моя цель:Как объявить массив массивов char *?

arr[0] = {"0a","0b","0c"}; 
arr[0][0] = "0a"; 
arr[0][1] = "0b"; 
.. 
arr[1] = {"1a","1b","1c"} 
  1. ли char *arr[][]? Я очень смущен.
  2. Как передать этот параметр функции?
+2

Вы можете получить некоторые подсказки, если вы читали о [по часовой стрелке/спираль правила] (HTTP://c-faq.com/decl/spiral.anderson.html). –

+0

@JoachimPileborg: Стоит ссылка! – deepmax

+0

@MM. Это хорошо для многих продвинутых объявлений, но может быть не идеально для этого случая. Например, объявление 'char * v [K] [L];', не совсем ясно, что мы должны пропустить указатель в первом «раунде» и перейти непосредственно ко второму массиву. –

ответ

0
void fill(char *arr[10][2]) { 
    arr[0][0] = strdup("k"); 
    arr[0][1] = strdup("ki"); 
    arr[1][0] = strdup("s"); 
    arr[1][1] = strdup("si"); 
} 

void clean(char *arr[10][2]) { 
    free(arr[0][0]); 
    free(arr[0][1]); 
    free(arr[1][0]); 
    free(arr[1][1]); 
} 


int main (int argc, char *argv[]){ 

    char *array[10][2] = {NULL}; 
    fill(array); 
    printf("%s %s\n", array[0][0], array[1][1]); 

    // when arr[i][j] bcome useless in your code, do not forget to free memories 
    clean(array); 
} 

fill и clean функции могут также определены следующим образом:

void fill(char *arr[][2]) { 
void clean(char *arr[][2]) { 
+0

Не могли бы также отметить, как будет выглядеть сигнатура функции, которая получает параметр arr в качестве параметра и может фактически изменить его содержимое? func (char ???) – Popokoko

+0

это func (char (* arr) [] [SIZE])? erm, im lost :( – Popokoko

+0

@Popokoko обновленный код – MOHAMED

0

Любой из них. Обратите внимание, что это одна вещь, почти все запутывается о в С.

char ** a; 

Здесь a указатель на один или несколько указателей на один или несколько символов. В памяти есть куча указателей, и каждый указывает на строку (так сказать). a относится к первому из этих указателей. (a+1) относится ко второму. Каждый из блоков символов находится где-то в памяти, но не обязательно рядом друг с другом. Вы можете сделать это:

for (int i = 0 ; i < 10 ; ++i) { 
    a++ = malloc(100); 
} 

или вы могли бы сделать это:

char *b = malloc(1000); 
for (int i = 0 ; i < 10 ; ++i) { 
    a++ = b; 
    b += 100; 
} 

И вы наполнили в массиве с 10 указателями на 100 символов. (Ну, на самом деле места для 100 символов, так как мы не заполняли ни символы, которые еще.)

char* a[]; 

Здесь, опять же, a это куча указателей на первую кучу персонажей. Это действительно то же самое, что и char ** a, но имеет смысл, если вы собираетесь их повторно использовать.

for (int i = 0 ; i < 10 ; ++i) { 
    a[i] = malloc(100); 
} 

, который будет делать то же самое, что и выше, но облегчает возврат к любому заданному блоку символов. Например, мы могли бы сделать strcpy(a[4], "Bob was here");

char a[][]; 

Это немного отличается тем, что это указатель на кучу символов, которые могут быть разбиты на блоки одинаковой длины. Обычно вы даете размеры в этом случае, если его слишком большой размер для размещения в стеке. char a[10][100] выделил бы 1000 символов в памяти, разделенных на 10 групп по 100 штук.

Обратите внимание, что ваш пример {"0a","0b","0c"}; - это способ выделения трех блоков памяти. Каждый имеет длину три байта и предварительно заполняется с персонажами там (и закрытие \ 0 символ

+0

Возможно, стоит отметить, что они не эквивалентны. – 2013-04-29 15:30:24

+0

Практически - Могли ли вы рассказать о различиях? – Popokoko

+0

Да. Это зависит от того, что он имеет в виду. –

2

Закрыть, но вы должны использовать агрегатную инициализацию все в одном кадре, например, так:.

char arr[][2][3] = 
{ 
    {"0a", "0b"}, 
    {"1a", "1b"}, 
}; 

Обратите внимание, что все, кроме наиболее значимы (крайний слева) массив должен быть явно размера Или может объявить каждую внутреннюю строку, как только указатель:.

const char * arr[][2] = 
{ 
    {"0a", "0b"}, 
    {"1a", "1b"}, 
}; 

это зависит от того, как структурированы ваши данные, и как статические . Альтернативой является использование stl std :: vector, если вы хотите динамически назначать содержимое каждого массива.

+0

+1, это ** ** правильный ответ. – 2013-04-29 15:30:59

+0

Я не хочу определять, как const или жестко закодированный массив. do u означает, что я должен определить его как char * arr [] [size]? вещь им не так уверенна в длине каждого массива – Popokoko

+0

@ H2CO3 - thx! Popokoko - я имею в виду, что если ваши данные известны во время компиляции, а структура фиксирована (количество массивов и т. Д.), Вы, вероятно, захотите выбрать статическое представление, которое будет проще и быстрее. Если ваши данные должны быть заполнены один раз (const, после инициализации), вам понадобится поддержка времени выполнения, например std :: vector. Наконец, если ваши данные будут много мутированы во время выполнения (что, я сомневаюсь), вы можете выбрать другой контейнер в целом, который выражает необходимую вам сложность (например, std :: unordered_map или что-то еще). Все зависит от характеристик программы. –

1

Это символ * arr [] []?

Звук о праве. Но вам нужно предоставить размеры для массивов в декларации.

0
int main (int argc, char *argv[]){ 

    char arr[10][2][3] = {0}; 

    memcpy(&arr[0][0], "k", sizeof(arr[0][0])); 
    memcpy(&arr[0][1], "ki", sizeof(arr[0][0])); 
    memcpy(&arr[1][0], "s", sizeof(arr[0][0])); 
    memcpy(&arr[1][1], "si", sizeof(arr[0][0])); 

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

} 
Смежные вопросы