2010-10-01 7 views
2

Я не могу понять разницу между различными объявлениями массива или массивом 2d.
, например:ссылаясь на массивы как указатели

void swap(char **a, char **b) { 
    char *t = *a; 
    *a = *b; 
    *b = t; 
} 
int main(int argc, char **argv) { 
    char a[] = "asher"; 
    char b[] = "saban"; 
    swap(&a,&b); 
} 

этот код не компилируется, он выводит:

warning: passing argument 1 of ‘swap’ from incompatible pointer type 
test.c:10: note: expected ‘char **’ but argument is of type ‘char (*)[6]’ 

не a указатель на первую ячейку массив символов и &a является указателем на указатель?

другой пример:

char (*c)[3]; 
char (*d)[3]; 
swap(c,d); 

не компилируется либо .. это char (*c)[3] же, как указатель на char a[] = "ab"?

Однако это делает компиляции:

char *c[3]; 
char *d[3]; 
swap(c,d); 

поэтому я совершенно запутался. Почему существует разница? Есть ли какие-то правила в этой проблеме, чтобы я не мог все время ошибаться?

Спасибо всем

+3

Это второй раз, когда мы видели этот код в течение трех дней: [Перестановка двух строковых указателей] (http://stackoverflow.com/questions/3816233/). Если, случайно, это связано с тем, что вы делитесь классом с басом, вы можете захотеть собраться с ним для взаимной помощи ... – dmckee

ответ

9

Я думаю, что это источник вашей путаницы.

Переменная массива - фиксированный объект. Он относится к фиксированному набору элементов массива. Он не может быть изменен, хотя значения элементов массива могут быть изменены.

Во всех контекстах выражения, кроме как в аргументе унарного & (адрес) и sizeof, массив будет распадаться на указатель на его первый элемент.

Дано:

char a[] = "asher"; 

Выражение a будет распадаться на указатель на символ (char*) и будет указывать на первый символ a.

Выражение &a является указателем на массив символов (char (*)[]). Это указатель на полный массив, а на указатель на первый символ. Это другой тип для указателя на первый символ массива, хотя он будет иметь то же значение, что и указатель на первый символ массива.

Однако ни одно из выражений a и &a являются lvalues ​​, они являются временным значением указателя.

Вы не можете обменять массивы, вы можете менять указатели, но для этого вам нужно lvalue указатели, адрес которых вы можете взять.

void swap(char **a, char **b); 

int main(int argc, char **argv) { 
    char a[] = "asher"; 
    char b[] = "saban"; 
    char* pa = a; 
    char* pb = b; 
    swap(&pa, &pb); 
} 
+0

Большое спасибо, это очень информативный ответ –

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