2016-05-15 12 views
8

Мне просто интересно, есть ли способ сделать массив указателей, указывающих на первый столбец каждой строки в многомерном массиве целых чисел. В качестве примера, пожалуйста, посмотрите на следующий код:Массивы указателей, которые указывают на массивы целых чисел

#include <stdio.h> 

int day_of_year(int year, int month, int day); 

main() 
{ 
    printf("Day of year = %d\n", day_of_year(2016, 2, 1)); 
    return 0; 
} 

static int daytab[2][13] = { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

int day_of_year(int year, int month, int day) 
{ 
    int leap; 
    int *nlptr = &daytab[0][0]; 
    int *lpptr = &daytab[1][0]; 
    int *nlend = nlptr + month; 
    int *lpend = lpptr + month; 

    leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0; 
    if (leap) 
     for (; lpptr < lpend; lpptr++) 
      day += *lpptr; 
    else 
     for (; nlptr < nlend; nlptr++) 
      day += *nlptr; 
    return day; 
} 

Когда я пишу, как это показано ниже:

int *p[2]; 
*p[0] = daytab[0][0]; 
*p[1] = daytab[1][0]; 

Я получаю сообщение об ошибке, как это:

Error: Array must have at least one element 
Error: Variable 'p' is initialized more than once 
Error: { expected 
Error: Variable 'p' is initialized more than once 
Error: { expected 
***5 errors in Compile*** 

Я изменил его, как это:

int *p[2]; 
p[0] = &daytab[0][0]; 
p[1] = &daytab[1][0]; 

Я все еще получаю такая же ошибка.

Я знаю, что мы можем сделать массив указателей на символьные строки, как в следующем:

char *str[] = { 
    "One", "Two", "Three", 
    "Four", "Five", "Six", 
    "Seven", "Eight", "Nine" 
} 

Как мы делаем это для массивов целых чисел?

+0

"* Это не работает *" является более или менее стоит сообщить об ошибке можно дать. Пожалуйста, уточните ошибку, предупреждение, неисправность, которую вы получаете, соблюдайте! – alk

+2

Первый пример: большой шанс вызвать разрыв сегментации путем разыменования неверного указателя. Второй пример: Не могли бы вы объяснить, что вы подразумеваете под «не работает»? – MikeCAT

+1

Код, как показано (с использованием второго подхода), выглядит хорошо для меня. – alk

ответ

2

Ваш код должен работать как шарм:

int *p[2]; 
p[0] = &daytab[0][0]; 
p[1] = &daytab[1][0]; 

printf("%d \n", p[0][2]); // shows: 28 
printf("%d \n", p[1][2]); // shows: 29 

Это также работает:

int *p[2] = { &daytab[0][0],&daytab[1][0] }; 
+0

Бывший код, когда он скомпилирован, продолжает давать мне ошибки, о которых я упоминал выше, хотя я думаю, что это не должно. Но последнее работает для меня, и это делает программу более компактной, устраняя необходимость в if-else. Спасибо. –

+0

Последний код работает, когда я скомпилирую его как cpp. Но когда я скомпилирую его как c, я получаю ошибку 'Illegal initialization в функции day_of_year' в строке' int * pe [2] = {p [0] + month, p [1] + month}; '. –

+1

Как уже упоминалось, Алк, пожалуйста, обновите свой компилятор как можно скорее !. Это было устарело в 90-х годах, и это наверняка даст вам большую головную боль. – tomekpe

1

Если это об изменении определения daytab идти как 3 примера вы могли бы использовать это:

int * daytab[] = { 
    (int[]){0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    (int[]){0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

вместо этого.

Или остаться сохранить и отметить конец массива, используя часовому сделать:

int * daytab[] = { 
    (int[]){0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    (int[]){0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    NULL 
}; 

Или^2, чтобы остаться даже заставки маркировки также внутренний массив заканчивается:

int * daytab[] = { 
    (int[]){0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, -1}, 
    (int[]){0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, -1}, 
    NULL 
}; 

Пожалуйста, обратите внимание, что соединения ((Type){Initialiser}), используемые здесь, доступны только с C99.

1

Использование, как показано ниже

int *p[2]; p[0] = daytab[0]; p[1] = daytab[1];