timkl
timkl

Reputation: 3339

Data type warning when initializing pointers

I'm currently trying to wrap my head around pointers in C, coming from front-end developing this not an entirely easy endeavour. I'm following this tutorial, and everything is running smoothly until I try to compile the following example:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int **ramon;
    int *paul;
    int melissa = 5;
    paul = &melissa;
    ramon = &paul;
    printf("ramon = %d\n", ramon); // <- warning: format '%d' expects type 'int'...
    printf("&paul = %d\n", &paul); // <- warning: format '%d' expects type 'int'...
    printf("*ramon = %d\n", *ramon); // <- warning: format '%d' expects type 'int'...
    printf("&melissa = %d\n", &melissa); <- warning: format '%d' expects type 'int'...
    printf("**ramon = %d\n", **ramon);p1); <- warning: format '%d' expects type 'int'...
    return(0);  
}

From the first printf line I get this error: "warning: format '%d' expects type 'int', but argument 2 has type 'int **'"

I reckon this has to do with the way I initialize my pointers, but standing at the bottom of a steep learning curve I don't know how to progress. What is wrong, how do I initialize pointers to avoid the warnings?

Upvotes: 3

Views: 431

Answers (8)

Karl Knechtel
Karl Knechtel

Reputation: 61643

I reckon this has to do with the way I initialize my pointers

Why would you reckon that when the error message says nothing about initialization? Read it again:

"warning: format '%d' expects type 'int', but argument 2 has type 'int **'"

You have %d in the format string for your printf() call, as a placeholder for the value that you want to print. %d is used as a placeholder for values that are int s. The value you want to print is ramon. That variable has the type int**. The type int and the type int** are not the same.

If you want to print a pointer, then you should write the format string so as to expect a pointer. We format pointers with %p.

but standing at the bottom of a steep learning curve I don't know how to progress.

The way to progress is to read the error and/or warning messages and attempt to understand them. The error messages are talking about types. You should not be trying to do anything with pointers if you haven't first got your head around the concept that values have a type (i.e., what kind of thing they are).

Upvotes: 0

SiegeX
SiegeX

Reputation: 140497

You declared ramon of type "pointer to pointer to type int". i.e. it holds an address to a "pointer to type int". %d on the other hand is the format specifier for int which is why you are getting the errors. Instead try the following:

printf("&paul = %p\n", ramon);     //print the address that ramon points to
printf("&melissa = %p\n", *ramon); //print the address that paul points to
printf("&melissa = %p\n", paul);   //same as above
printf("melissa = %d\n", **ramon); //print the contents of melissa
printf("melissa = %d\n", *paul);   //same as above
printf("melissa = %d\n", melissa); //same as above

Output

&paul = 0xbf8072f4
&melissa = 0xbf8072f0
&melissa = 0xbf8072f0
melissa = 5
melissa = 5
melissa = 5

Upvotes: 1

LeopardSkinPillBoxHat
LeopardSkinPillBoxHat

Reputation: 29441

Your pointer initialization looks correct. The problem is that you are trying to print a variable of type int** (i.e. a "pointer to a pointer to an int") using the %d format specifier which is for int values.

Print int value

If you want to print the value of melissa (i.e. 5) which is essentially what ramon is indirectly pointing to, you need to de-reference the pointer value the correct number of times.

De-referencing pointers is done via the * operator, and it essentially means "the value at which this pointer is pointing to".

  • De-referencing it once (i.e. *ramon) will get the int* value which ramon is pointing to.
  • De-referencing it a second time will get the int value which the de-referenced int* value is pointing to.
  • You can chain together de-reference operators like so to get what you want:

    printf("ramon = %d\n", **ramon);

Print pointer value

If you want to print a pointer (i.e. memory location) value, you can use the %p format specifier. This will print the memory address out in hex:

printf("ramon = %p\n", ramon); // Print the "pointer to the pointer to melissa"
printf("ramon = %p\n", *ramon); // Print the "pointer to melissa"

Upvotes: 4

Nick Meyer
Nick Meyer

Reputation: 40402

The warning has nothing to do with how you are initializing your pointers, it has to do with the mismatch in types between printf's %d specifier and the types you are passing to it.

If you want to print a pointer, use %p.

Upvotes: 1

Praetorian
Praetorian

Reputation: 109289

ramon and paul are pointers and the printf format specifier for printing values of pointers themselves (not what they're pointing to) is %p. Try

printf("ramon = %p\n", ramon);

Upvotes: 1

Blagovest Buyukliev
Blagovest Buyukliev

Reputation: 43558

The type of the expression ramon is an int **, and the %d specifier expects an int. *ramon will be of type int *, and **ramon will be the desired int.

If you want to print the pointer itself, use the %p specifier.

Upvotes: 1

vpit3833
vpit3833

Reputation: 7961

read man printf. It is not clear whether you want to print the value pointed to by ramon or the actual value of ramon which is an address of an pointer to an int. Same for other warnings as well.

Upvotes: 1

arsenm
arsenm

Reputation: 2933

ramon isn't an int, it's a pointer to a pointer to an int. **ramon would be an int. You're trying to print a bunch of ints with %d, but you're mostly trying to print pointers which uses the format %p.

Upvotes: 1

Related Questions