2010-11-24 5 views
0

У меня есть следующие ...C - прохождение через массивы функций

void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys]) {} 

int main() 
{ 
    char keys[NumberOfKeys][LengthOfKeys] = {}; 
    keySorter (&keys); 
} 

Итак, у меня есть это, он отлично компилируется, но я получаю обратно то, что я хочу. Клавиши [] [] были инициализированы с помощью = {};, поэтому он пуст, но он должен заполняться материалом внутри функции.

Первый элемент попадает в функцию, остальное идет ...? Я наблюдаю за функцией STRCPY, которая помещает данные в ключи [] [], и имеет правильное исходное значение, значение назначения кажется мусором, хотя (или, по крайней мере, это символы, которые выглядят как мусор).

strcpy(*keys[i], "BLAH"); 

Это другая часть функции.

+0

Как вы пытаетесь прочитать значения внутри keySorter? – 2010-11-24 18:59:01

+0

Также, вы заселили «ключи»? – 2010-11-24 19:00:56

+0

Нет, я на самом деле пытаюсь заполнить клавиши [] []. Его отправили пустым. – MykC 2010-11-24 19:09:07

ответ

1

Здесь (C99) код, который работает - выход опрятно если окно более 100 столбцов в ширину (отрегулировать 32 до меньшего числа, если у вас есть узкие окна):

#include <stdio.h> 

enum { NumberOfKeys = 20, LengthOfKeys = 32 }; 

static void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys]) 
{ 
    size_t k = 0; 
    for (size_t i = 0; i < NumberOfKeys; i++) 
     for (size_t j = 0; j < LengthOfKeys; j++) 
      (*keys)[i][j] = ++k & 0xFF; 
} 

static void dumpKeys(char keys[NumberOfKeys][LengthOfKeys]) 
{ 
    for (size_t i = 0; i < NumberOfKeys; i++) 
    { 
     for (size_t j = 0; j < LengthOfKeys; j++) 
      printf("%02X ", keys[i][j] & 0xFF); 
     putchar('\n'); 
    } 
} 

int main(void) 
{ 
    char keys[NumberOfKeys][LengthOfKeys] = {}; 
    printf("Before:\n"); 
    dumpKeys(keys); 
    keySorter(&keys); 
    printf("After:\n"); 
    dumpKeys(keys); 
} 

Обратите внимание на принципиальное различие между нотаций, используемых для доступа к массиву в keySorter() по сравнению с dumpKeys(). В первом случае, поскольку передается указатель на двумерный массив, код для доступа к массиву должен сначала разыменовать указатель с (*keys)[i][j], тогда как во втором массив передается напрямую, а запись прямого доступа keys[i][j] в порядке.

Когда я скомпилирован с GCC 4.2.1 (на MacOS X 10.6.5) с помощью:

gcc -O -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \ 
    -Wold-style-definition xx.c -o xx 

код, показанный компилируется. Когда я экспериментировал с использованием keys[i][j] в keySorter(), он жаловался на ошибку «несовместимые типы при присваивании».

Вы также можете Пересмотреть keySorter() использовать strcpy() (вы должны #include <string.h>, конечно, тоже):

static void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys]) 
{ 
    for (size_t i = 0; i < NumberOfKeys; i++) 
     strcpy((*keys)[i], "BLAH"); 
} 

Вы еще разыменовать указатель на массив, прежде чем индексировать в массив.

Если/когда Вы писали:

strcpy(keys[i], "BLAH"); 

, то вы должны получать предупреждения компилятора (если вы не получаете лучший компилятор, или, по крайней мере, работать, как сделать ваш компилятор испускает обильным предупреждения), но значение keys[0] было первым массивом в наборе массивов, на который указывал keys, а затем keys[1] был вторым массивом, а keys[2] был третьим массивом и т. д. Указатель может сильно расплыться, что вы в конечном итоге написали BLAH по первой строке каждого массива, но в итоге у вас будет основной дамп или другие подобные проблемы, потому что вы не выделили достаточное количество массивов в основной программе.

1

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

Да, вы правильно оцениваете массив, так как совпадают тип вызова и объявленного типа функции. Но вы передаете указатель на массив массива char вместо простого указателя на первый элемент массива char. Может быть, вы должны сделать это таким образом:

void keySorter(char keys[NumberOfKeys][LengthOfKeys]) 
{...} 

int main(void) 
{ 
    char keys[NumberOfKeys][LengthOfKeys]; 
    keySorter(keys); 
} 

Это позволяет получить доступ к элементам массива очень просто:

for (int i = 0; i < NumberOfKeys; i++) 
{ 
    for (int j = 0; j < LengthOfKeys; j++) 
    { 
     ... keys[i][j] ... 
    } 
} 

Добавление

Добавление явного значения инициализатора достаточно для инициализации массив для всех нулей (т.е. все значения):

char keys[NumberOfKeys][LengthOfKeys] = { 0 }; 
0

ключи уже указатель, поэтому вам не нужно делать этот ключ. Строка (& ключей); класть только keySorter (ключи);

2

Внутри keySorter, keys является указателем на массив массивов char. Это означает, что для получения массива char для использования с strcpy вам необходимо отделить указатель от указателя, а затем использовать доступ к массиву для выбора массива.

E.g.

strcpy((*keys)[i], "test"); 

Вы не можете использовать *keys[i], потому что правила приоритета означают, что [] применяется первый и keys не является указателем на первый элемент массива является указателем на сам массив.

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

void keySorter(char keys[][LengthOfKeys]); 

или

void keySorter(char (*keys)[LengthOfKeys]); 

В этом случае вы можете просто сделать, потому что strcpy(keys[i], "blah")keys является указателем в массив из массивов char.

Вызывается:

int main() 
{ 
    char keys[NumberOfKeys][LengthOfKeys] = {}; 
    keySorter(keys); 
} 
Смежные вопросы