3
int main()
{
    char word[100];
    char* lowerCase;

    scanf("%s", word);

    lowerCase = toLowerCase(&word);
    printf("%s", lowerCase);
}

char * toLowerCase(char *str)
{
    int i;

    for(i = 0; str[i] != '\0'; ++i)
    {
        if((str[i] >= 'A') && (str[i] <= 'Z'))
        {
            str[i] = str[i] + 32;
        }
    }

    return str;
}

I am getting a warning while executing the above code. the warning is

try.c: In function 'main':
try.c:16:26: warning: passing argument 1 of 'toLowerCase' from incompatible pointer type [-Wincompatible-pointer-types]
  lowerCase = toLowerCase(&word);
                          ^~~~~
try.c:4:7: note: expected 'char *' but argument is of type 'char (*)[100]'
 char* toLowerCase(char *str);

I am not able to understand why this warning is coming? if i am passing (word) to the function there is no warning, but when i execute the following code the output is same:

printf("%d", word);
printf("%d", &word);

If the address is same then why this warning?

Aditya Naitan
  • 162
  • 3
  • 11
  • 4
    `char` is a single character, `char[100]` is a block of 100 characters. These are different types and therefore a pointer to each is a different type of pointer . You designed your function to expect a pointer to a single character – M.M Mar 15 '20 at 07:55
  • 1
    You should be using `toLowerCase(word)`. – Sulthan Mar 15 '20 at 07:57
  • `word` already denotes a pointer; i.e., a `char *`. You may pass it w/o the reference operator `&`. For `char *p = "some text";`, `p` points to the starting address of the string, whereas `&p` means the address of the pointer variable (a `char **`), not the address where its pointing at. – ssd Mar 15 '20 at 07:59
  • @M.M char is a single character, char[100] is a block of 100 characters. These are different types -> aggreed, therefore a pointer to each is a different type of pointer? You designed your function to expect a pointer to a single character? – Aditya Naitan Mar 15 '20 at 08:07
  • @WeatherVane how does that affect my question? i am asking a totally different thing – Aditya Naitan Mar 15 '20 at 08:30
  • Because without a function prototype the compiler knows nothing about it. The warning is in `main`, before the function definition. So when receiving warnings about function arguments, the first step should be to declare them correctly (which they should be anyway). – Weather Vane Mar 15 '20 at 08:37
  • @WeatherVane I have used function prototype in my code, but haven't uploaded it here. the warning is not because of that. – Aditya Naitan Mar 15 '20 at 08:54
  • That is one reason you are asked to post the [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) that shows the complete code. Then readers *know* you have a function prototype, and which matches the function definition. – Weather Vane Mar 15 '20 at 08:59
  • @P__J__'s answer teaches it well. This, however, is adjacently related and provides some more insight into array parameter types: https://stackoverflow.com/questions/6567742/passing-an-array-as-an-argument-to-a-function-in-c/51527502#51527502 – Gabriel Staples Mar 15 '20 at 17:58

1 Answers1

4

char x[100]

Array x decays to pointer:

x - pointer to the char (char *)

&x - pointer to a the array of 100 chars (char (*)[100]);

&x[0] - pointer to the char (char *)

all of those pointers reference the same start of the array, only the type is different. The type matters!!.

You should not pass the &x to the functions which expect (char *) parameters.

Why type matters?:

char x[100];

int main()
{
    printf("Address of x is %p, \t x + 1 - %p\t. The difference in bytes %zu\n", (void *)(x), (void *)(x + 1), (char *)(x + 1) - (char *)(x));
    printf("Address of &x is %p, \t &x + 1 - %p\t. The difference in bytes %zu\n", (void *)(&x), (void *)(&x + 1), (char *)(&x + 1) - (char *)(&x));
    printf("Address of &x[0] is %p, \t &x[0] + 1 - %p\t. The difference in bytes %zu\n", (void *)(&x[0]), (void *)(&x[0] + 1), (char *)(&x[0] + 1) - (char *)(&x[0]));
}

Result:

Address of x is 0x601060,    x + 1 - 0x601061   . The difference in bytes 1
Address of &x is 0x601060,   &x + 1 - 0x6010c4  . The difference in bytes 100
Address of &x[0] is 0x601060,    &x[0] + 1 - 0x601061   . The difference in bytes 1

https://godbolt.org/z/SLJ6xn

0___________
  • 60,014
  • 4
  • 34
  • 74