2014-08-30 4 views
-1

Я дал следующий фрагмент кода:Указатель на массив 2D

int group1[3][3] = {3,4,5,1,9,8}; 
int group2[3][3] = {{1},{2,3},{4,5}}; 
int *gPtr1 = group1; 
int *gPtr2 = group2; 

Вопрос спрашивает меня для значения: (я должен ответить на это на бумаге, конечно, ни один компьютер)

*(gPtr1 + 3) 
*(gPtr2 + 3) 

Как правило, я знаю, что для 1-мерного массива он добавляет «адрес» вместо значения. Так, например:

int balance[10]={1,2,6,4}; 
int *p=balance; //p points to balance [0] 

p+=3;   //points to balance [3] 

Однако, я не могу показаться, чтобы сделать указатель на массив 2D, чтобы проверить это, как в этом вопросе, я всегда получаю «Initialization от несовместимого типа указателя» ошибка.

+1

Код не будет компилироваться без предупреждений от достойного компилятора - из-за несоответствий типа инициализация указателей больше, чем из-за неполных фигурных скобок в первом инициализаторе. Вы можете исправить их с помощью 'int * gPtr1 = & group1 [0] [0];' и 'int * gPtr2 = & group2 [0] [0];' (и вы получите результат, который автор кода намеревается вы получите). Вы знаете, к чему относится этот вопрос? –

ответ

0

Двумерные матрицы представлены в строгом порядке в памяти. Это связано с тем, что память одномерна и поэтому хранит двумерные массивы в виде конкатенированного списка строк.

При создании group1, вы получите массив целых чисел, является 9 долго, и это выглядит следующим образом:

3 4 5 1 9 8 _ _ _ 

Итак, когда вы делаете *(gPtr1 + 3), он добавляет 3 к исходному расположению gPtr1, который является адресом 3. Добавляя 3, вы попадаете в положение 1, которое вы разыскиваете.

Таким образом, при создании Group2, вы получите массив целых чисел, является 9 долго, и это выглядит следующим образом:

1 _ _ 2 3 _ 4 5 _ 

Итак, когда вы делаете *(gPtr2 + 3), он добавляет 3 к исходному местоположению gPtr2 , который является адресом 1. Добавляя 3, вы попадаете в пункт 2, который вы разыскиваете.

2

правильные записи будут выглядеть

int (*gPtr1)[3] = group1; 
int (*gPtr2)[3] = group2; 

И эти выражения

*(gPtr1 + 3) 
*(gPtr2 + 3) 

пытаются получить доступ к памяти после того, как последние элементы массивов, поскольку массивы имеют только три строки. То есть тип выражения *(gPtr1 + 3) равен int[3], и в массивах оридинов есть только три таких элемента.

или вы могли бы написать

int *gPtr1 = (int *)group1; 
int *gPtr2 = (int *)group2; 

В этом случае, используя указатели на массивы interpretated как одномерные массивы с 9 элементов и выражений

*(gPtr1 + 3) 
*(gPtr2 + 3) 

вернется соответственно

1 
2 
2

Для доступа к адресу группы1 передайте его указателю следующим образом:

int *gPtr1 = &group1[0][0]; 

С помощью этого можно легко найти soultions: 1 и 2.

0

Может быть, это поможет вам начать работу:

#include <stdio.h> 

int group1[3][3] = {3,4,5,1,9,8}; 
int group2[3][3] = {{1},{2,3},{4,5}}; 

int main(void) 
{ 
    int *p; 
    int i; 
    for (p = group1[0], i = 0; i < 9; ++i, ++p) 
     printf("%d - ", *p); 
    printf("\n"); 
    for (p = group2[0], i = 0; i < 9; ++i, ++p) 
     printf("%d - ", *p); 
    printf("\n"); 
    return 0; 
} 

Если вы понимаете, как память в этом 2D массива хранится , должно быть понятно, почему это будет работать. Поскольку я предполагаю, что понимание - это то, что вы ищете, я оставлю вас, чтобы понять эту часть самостоятельно. :-)

+0

Очень верно, я не заметил тега. Исправлена. – Anthony

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