2013-10-15 2 views
2

Вот мой код: -Передача 2D массива в функции в C

void display(int *p) 
{ 
printf ("%u\n", p); 
printf ("%u\n", p+1); 
} 

int main() 
{ 
    int a[3][4] = { 
        1,2,3,4, 
        5,6,7,8, 
        9,0,1,2 
       }; 
    printf("%u\n",a); 
    printf("%u\n",a+1); 
    display(a); 


} 

Почему а + 1 и р + 1 дают разные адреса? Если a и p дают одинаковые адреса, то не должны указывать +1 и p + 1 на одни и те же адреса?

+0

Учитывая, что вы игнорируете предупреждения компиляции, вы должны получить разницу 'sizeof (int)' (вероятно, 4) от 'display()', и вы должны получить разницу в размере 4 * sizeof (int) '(вероятно 16) из кода в 'main()'. Это потому, что 'a' в' a + 1' имеет тип 'int (*) [4]' или указатель на массив из 4 'int'. –

ответ

3

Ваш компилятор должен был выдать ошибку (или хотя бы предупреждение), когда вы проходили a, которая имеет тип int (*)[4] функции, ожидающей int *. Вы увидите это, если бы включили все предупреждения компилятора.

Мой компилятор ясно заявляет:

Предупреждение: проезжают аргумент 1 из 'дисплея' от несовместимого типа указателя

Слово совет: если ваш компилятор жалуется на свой код, вам следовало бы это прислушаться. Научитесь использовать ВСЕ флагов компилятора (-Wall -pedantic и т. Д.) - это уловит самые плохие привычки кодирования, прежде чем они станут укоренившимися. Или однажды они тебя укусят.

+0

GCC 4.8.1 говорит: 'note: expected 'int *', но аргумент имеет тип 'int (*) [4]''. –

+0

@JonathanLeffler - У меня есть старый компилятор; новое сообщение об ошибке явно более наглядное. Основное сообщение такое же ... – Floris

+0

Почти то же самое: подробный тип отличается (указатель на массив из 4 'int' отличается от указателя на указатель на' int'). –

1

У них разные размеры, поэтому переход к следующему добавляет другую сумму. То же самое произойдет, если вы указали указатель int и указатель char - так как они имеют разные размеры, добавление одного на тот же адрес даст вам разные адреса.

0

Для компиляции кода вы должны изменить последнее утверждение на display(&a[0][0]). Причина: array decay не применяется повторно, поэтому int[3][4] становится int(*)[4]. После того, как вы сделаете код компилируемым, вы увидите проблему, о которой вы спросили: increment by 1, показывающий разные значения для указателей a и p.

Хотя фактическое значение обоих a и p будет одним и тем же базовым адресом расположения массива/первого значения (назовите его X), следует отметить, что оба указателя имеют разные типы; p имеет тип int*, в то время как int (*) [4] бы тип указателя на 2-мерного массива (как распад массива применяется только к первой размерности. В псевдокоде

р + 1 = Х + SizeOf (INT)

а + 1 = Х + SizeOf (INT (*) [4]) = Х + (SizeOf (INT) * 4)

, где 4 является второй размер массива. Следовательно, на машина, где sizeof(int) - 4, вы можете увидеть X + 4 для p и X + 16 для a. На моей машине p + 1 = 0x22fe34, а a + 1 = 0x22fe40.

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