Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arrays of pointers that point to arrays of integers

I am just wondering if there is a way to make an array of pointers that point to the first column of each row in a multidimensional array of integers. As an example, please look at the following code:

#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;
}

When I write like this below:

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

I get an error like this:

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***

I changed it like this:

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

I still get the same error.

I know we can make an array of pointers to character strings as in the following:

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

How do we do that for arrays of integers?

like image 752
W. Zhu Avatar asked May 15 '16 08:05

W. Zhu


3 Answers

Your code should work as charm:

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

This also works:

int *p[2] = { &daytab[0][0],&daytab[1][0] };
like image 142
LookAheadAtYourTypes Avatar answered Oct 09 '22 23:10

LookAheadAtYourTypes


If it's about changing the definition of daytab to go like the 3rd example you might like to use this:

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}
};

instead.

Or to stay save and mark the end of the array using a sentinel do:

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
};

Or^2 to stay even saver marking also the inner array ends:

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
};

Please note that the compounds ((Type){Initialiser}) used here are available only from C99 on.

like image 42
alk Avatar answered Oct 09 '22 22:10

alk


Use like below

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

like image 43
Ashish Avatar answered Oct 09 '22 21:10

Ashish