0

Can anybody explain me why this code doesn't work?

#include <stdio.h>
#include <stdlib.h>

void findAndPrint(char *arr[], int year, int month, int day);

int main()
{
    char *dayTab[] = {
        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };
    findAndPrint(dayTab, 3, 3, 3);
    getchar();
    return 0;
}

void findAndPrint(char *arr[], int year, int month, int day ){
    int d = 0;
    if(month > 12 || month < 1 || day > 31 || day<1)
        return;
    int leap = ((year%4==0 && year%100!=0) || year%400 == 0)?1:0;
    int i;
    for(i=0; i<month-1; i++){
        d += arr[leap][i];
    }
    d+= day;
    printf("Day = %d", d);
}

IDE(Code::Blocks) writes "Program received signal SIGSEGV. Segmentation fault."

Denis
  • 719
  • 2
  • 8
  • 23
  • The compiler doesn't know the dimensions of `char *arr[]` inside function `findAndPrint`. Either pass it as `char arr[][12]` (or as `char [2][12]` if you really want), or simply declare it inside the function, as it appears to be the logically correct place for it. In addition, declare it `static` if you intend to call it more than once, in order to avoid the initialization every time it is invoked. – barak manos Oct 12 '14 at 17:22
  • `void findAndPrint(char arr[][12], int year, int month, int day);` , `char dayTab[][12] = {` – BLUEPIXY Oct 12 '14 at 17:24
  • You really should care about the warnings issued by the compiler. They are not given for fun ... – alk Oct 12 '14 at 17:28
  • @BLUEPIXY I declared it inside 'findAndPrint' function, but IDE writes the same. – Denis Oct 12 '14 at 17:28
  • @user3051029: What language is that? Your declaration of `dayTab` is not even remotely valid in C. No compliant C compiler will accept it. You are opening the second level of nested `{}` for a data structure that has only one level of aggegate nesting. – AnT stands with Russia Oct 12 '14 at 17:35

2 Answers2

4

First you need a 2d array of characters, not an array of pointers to characters.

char dayTab[][12] = {
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

Then you have to change the function to accept that type.

void findAndPrint(char arr[][12], int year, int month, int day ) ;

The rest looks ok.

Trying with parameters:

findAndPrint(dayTab, 2014, 10, 12);

Gives us day: 285

Which is correct, yaaay!

2501
  • 25,460
  • 4
  • 47
  • 87
  • As I know, I can create this array as _array of pointers to characters_. – Denis Oct 12 '14 at 17:36
  • The code will work perfectly fine with an array of pointers (as in the original post), as long as the proper initialization syntax is used. The only problem with the original code is broken initialization. – AnT stands with Russia Oct 12 '14 at 19:29
1

If I properly understood your intent, you wanted those nested {31, 28, ... } sequences to serve as char[] arrays, to which the pointers in the upper level array would point to.

Despite what the other answer(s) states, it is not correct to say that you necessarily need a literal 2D array (even though in this case a 2D array might be a better idea than what you attempted to do). You original attempt will work too, as long as you use the proper syntax.

Now, you can't just plant a {31, 28, ... } sequence in the middle of the code and expect the compiler to interpret it as an array. The language does not have such feature, but it has a similar one with slightly different syntax. The only way achieve the proper initialization of your char *dayTab[] array in that "inline" fashion is to use the compound literal feature. The initialization will look as follows

char *dayTab[] = {
    (char []) { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
    (char []) { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};

Note the extra (char []) syntax. This is absolutely necessary. This is the only thing that you have to change in your original code to make it compile as intended.

What you currently have in your original code is not valid C. If some compiler accepted this code (GCC in CodeBlocks?), then only due to some compiler extension. That compiler extension happened to play a cruel joke on you in this particular case. I don't even know how it was interpreted by the compiler, but definitely not how you intended it to be interpreted.

P.S. In my experiments, GCC gave a wall of diagnostic messages in response to our original code. Did you get those messages from your compiler? Did you just ignore them?

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765