2014-11-21 6 views
-2

Я нашел этот код где-то в Интернете, и я могу разобрать все 4 случая, но последний из них снова и снова ставит меня в недоумение относительно его выполнения.объяснение вывода кода c

#include <stdio.h> 
int a1[] = {6, 7, 8, 18, 34, 67}; 
int a2[] = {23, 56, 28, 29}; 
int a3[] = {-12, 27, -31}; 
int *x[] = {a1, a2, a3}; 
void print(int *a[]) 
{ 
     printf("%d,", a[0][2]); 
     printf("%d,", *a[2]); 
     printf("%d,", *++a[0]); 
     printf("%d,", *(++a)[0]); 
     printf("%d\n", a[-1][+1]); 
} 
main() 
{ 
     print(x); 
} 

То, что я думал, что это лучший метод визуализации таких случаев является:

a[0][2])=a-->a[0]-->a[0][2](way of understanding)=>a1[2]=8 

на исполнение дает выход как:

8,-12,7,23,8 
+1

И вопрос в том, что? – bitcell

+0

Я думаю, что более важно здесь не использовать оператор инкремента как это, поскольку он уменьшает читабельность кода. Если бы это был код, который вы написали, я бы предложил вам пересмотреть, как вы это написали. – shuttle87

+3

@ shuttle87 Я думаю, что это пример обучения, а не настоящий код. –

ответ

1

Я собираюсь изменить имена ясности, а затем следует строка за строкой:

void print(int *b[]) 
{ 
    printf("%d,", b[0][2]); 
    printf("%d,", *b[2]); 
    printf("%d,", *++b[0]); 
    printf("%d,", *(++b)[0]); 
    printf("%d\n", b[-1][+1]); 
} 

printf("%d,", b[0][2]); 

b[0] является a1 затем a1[2] является 8

printf("%d,", *b[2]); 

b[2] является a3 и *a3 является первым элементом, который является a3 -12

printf("%d,", *++b[0]); 

b[0] является a1, то мы увеличиваем поэтому мы имеем *++a1 что эквивалентно до a1[1], который составляет 7

printf("%d,", *(++b)[0]); 

Теперь в этом случае мы должны сделать только (++b), что эквивалентно ++x, что составляет a2. теперь у нас есть *a2[0], который составляет 23. Важно то, что мы только что изменили b, указатель на b только что получил приращение и сохранил новый указатель в b.

printf("%d\n", b[-1][+1]); 

Мы должны помнить, что b изменил одну строку перед так b здесь начинается, как если бы он был принят в b+1 первоначально. Это означает, что мы начинаем указатель одного адреса дальше, чем раньше: так это то, как мы имели (x+1)[-1][+1], который x[-1+1][+1+1] или x[0][2], который a1[2] который 8.

Это как это работает, потому что массив здесь действительно только один непрерывный блок памяти. Обратите внимание, что если вы сделали int **x, это было бы иначе.

Обратите внимание, что это правильный результат, как вы можете видеть, когда вы запустите код здесь: http://ideone.com/0mFvXn

По существу на последней строке, что произошло можно продемонстрировать следующим образом:

#include <stdio.h> 
int a1[] = {6, 7, 8, 18, 34, 67}; 
int a2[] = {23, 56, 28, 29}; 
int a3[] = {-12, 27, -31}; 
int *x[] = {a1, a2, a3}; 

int main(void) 
{ 
    printf("%d, %d \n", x[0][0], x[1][1]); 
    int** z = x; 
    ++z; 
    printf("%d, %d \n", z[0][0], z[1][1]); 
    return 0; 
} 

выход:

6, 56 
23, 27 

Последний фрагмент кода на ideone: http://ideone.com/cB5y75

. Обратите внимание, что гораздо лучше яснее писать этот тип кода, чем пример кода в вопросе, поэтому, пожалуйста, не делайте ничего подобного в производственном коде.Второй фрагмент кода в этом ответе довольно ясен в моем сознании, чем первый.

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