What is difference between %d and %u when printing pointer addresses?
For example:
int a = 5;
// check the memory address
printf("memory address = %d\n", &a); // prints "memory address = -12"
printf("memory address = %u\n", &a); // prints "memory address = 65456"
You can find a list of formatting escapes on this page.
%d is a signed integer, while %u is an unsigned integer. Pointers (when treated as numbers) are usually non-negative.
If you actually want to display a pointer, use the %p format specifier.
%u prints unsigned integer
%d prints signed integer
to get a pointer address use %p
Other List of Formatting Escapes:
Here are the full list of formatting escapes. I am just giving a screen shot from this page
If I understand your question correctly, you need %p to show the address that a pointer is using, for example:
int main() {
int a = 5;
int *p = &a;
printf("%d, %u, %p", p, p, p);
return 0;
}
will output something like:
-1083791044, 3211176252, 0xbf66a93c
%u is used for unsigned integer. Since the memory address given by the signed integer address operator %d is -12, to get this value in unsigned integer, Compiler returns the unsigned integer value for this address.
The difference is simple: they cause different warning messages to be emitted when compiling:
1156942.c:7:31: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("memory address = %d\n", &a); // prints "memory add=-12"
^
1156942.c:8:31: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("memory address = %u\n", &a); // prints "memory add=65456"
^
If you pass your pointer as a void* and use %p as the conversion specifier, then you get no error message:
#include <stdio.h>
int main()
{
int a = 5;
// check the memory address
printf("memory address = %d\n", &a); /* wrong */
printf("memory address = %u\n", &a); /* wrong */
printf("memory address = %p\n", (void*)&a); /* right */
}
Related
I am getting the output that I want but can't figure out how to get rid of these warnings. Any help is appreciated.
Warnings:
Format specifies type 'void *' but the argument has type 'char' [-Wformat]
printf("\nThe pointer variable's value is %p\n", *myString);
"Format specifies type 'void *' but the argument has type 'char' [-Wformat]
printf("%p\n", myString[x]);
#include <stdio.h>
#include <stdlib.h>
int main() {
char *myString = "Daniel";
int x;
printf("\nThe pointer variable's value is %p\n", *myString);
printf("\nThe pointer variable points to %s\n", myString);
printf("\nThe memory location for each character are: \n");
for (x = 0;x < 7;x++){
printf("%p\n", myString[x]);
}
return 0;
}
Ouput:
The pointer variable's value is 0x44
The pointer variable points to Daniel
The memory location for each character are:
0x44
0x61
0x6e
0x69
0x65
0x6c
(nil)
For starters these calls
printf("\nThe pointer variable's value is %p\n", *myString);
and
printf("%p\n", myString[x]);
do not make a sense because you are trying to use a value of a character as a pointer value.
As for the other warning then just cast pointers to the type void *. For example
printf("\nThe pointer variable's value is %p\n", ( void * )myString);
printf("\nThe pointer variable points to %s\n", myString);
printf("\nThe memory location for each character are: \n");
for (x = 0;x < 7;x++){
printf("%p\n", ( void * )( myString + x ));
}
For some reason when I try to compile this code in the C program it is giving me back an error. I am trying to print out the actual memory address of variable x. If anyone knows I would appreciate it!
Code:
int x = 7;
printf("x is %d\n", x);
x = 14;
printf("x is %d\n", x);
int *aptrx = malloc(sizeof(int));
aptrx = &x;
printf("aptrx is %x\n", aptrx);
Error:
*pointer.c:12:29: error: format specifies type 'unsigned int' but the argument has type* 'int \*' [-Werror,-Wformat]
You do not need to have this line in your code if you just want to print the address of x.
int *aptrx = malloc(sizeof(int));
You do not need to allocate memory whenever you create a pointer variable. If you want to point to an existing variable, which you want in this case, you can simply do
int *aptrx = &x;
Then try to print the address using below line using the format specifier %p.
printf("aptrx is %p\n", aptrx);
You are having an error because the format expects an unsigned int but the argument is an int *.
The manual for printf says about the %x conversion specifier:
The unsigned int argument is converted [...] to unsigned hexadecimal (x and X)
notation.
If you want to print a pointer, you can use the %p conversion specifier.
The void * pointer argument is printed in hexadecimal (as if by %#x
or %#lx).
Like this:
printf("aptrx is %p\n", aptrx);
It's not necessary to allocate memory dynamically to create a pointer variable.
int *aptrx = malloc(sizeof(int)); //unnecessary
Simply, create a pointer variable just like any other variable
int *aptrx = &x;
To print out the value of the pointer (i.e. address of x), use the format specifier %p or %u:
printf("aptrx is %p\n", aptrx);
In my C program i assign a string in one integer variable and i print with percentage %s it will print that string with warning integer to pointer without cast and print with %d it print 134513904 then i change my string value and print with %d "134513904" is printing what is this value and how integer variable storing a string value in int variable?
enter code here
#include<stdio.h>
main()
{
int a="naveen";
printf("%d\n",a);
printf("\n%s\n",a);
if("naveen")
{
printf("hi");
}
int_point.c: In function ‘main’:
int_point.c:22:8: warning: initialization makes integer from pointer without a cast [enabled by default]
int a="naveen";
^
int_point.c:24:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("\n%s\n",a);
^
134513920
naveen
hi
The following assigns a pointer (not a string) to s:
const char *s = "navven";
That means the following assigns a pointer (not a string) to a:
int a = "naveen";
Computers don't really see a difference between a pointer and number. They're both things that fit in their registers. And some people take advantage of that fact. So while the compiler warns you that you are doing something wrong, it still lets you treat the pointer as a number.
So a is ends up with the value of the pointer if it were an int. That's not safe to do. Not quite. While you can't use an int safely, you can use an intptr_t safely.
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
int main(void) {
const char *p1 = "naveen";
printf("%p %s\n", p1, p1);
intptr_t i = (intptr_t)p1;
printf("0x%" PRIxPTR "\n", i);
const char *p2 = (const char*)i;
printf("%p %s\n", p2, p2);
return 0;
}
Output:
0x51ee878764 naveen
0x51ee878764
0x51ee878764 naveen
When I try and compile this I get the following error, not sure why...
warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘char *’ [-Wformat=]
printf("Name buffer address: %x\n", buffer);
The code:
#include <string.h>
#include <stdio.h>
main(){
char name[200];
printf("What is your name?\n");
scanf("%s", name);
bo(name, "uname -a");
}
int bo(char *name, char *cmd){
char c[40];
char buffer[40];
printf("Name buffer address: %x\n", buffer);
printf("Command buffer address: %x\n", c);
strcpy(c, cmd);
strcpy(buffer, name);
printf("Goodbye, %s!\n", buffer);
printf("Executing command: %s\n", c);
fflush(stdout);
system(c);
}
You are getting the warnings because of the following statements
printf("Name buffer address: %x\n", buffer);
printf("Command buffer address: %x\n", c);
%x expects an unsigned int, whereas you're supplying a pointer.
To refer, C11 standard, chapter §7.21.6.1
o,u,x,X The unsigned int argument is converted to unsigned octal (o), unsigned
decimal (u), or unsigned hexadecimal notation (x or X) in the style dddd; [...]
Supplying invalid argument invokes undefined behavior.
You should be using %p to print the address
p The argument shall be a pointer to void.[...]
and cast the argument to void *, because for pointer types no default argument promotion takes place.
Having said that,
main() should be int main(void), at least, to conform to the standard.
You need to forward declare your function bo() because implicit declarations are bad and non-standard now.
To print an address use "%p" instead of "%x". You also need to cast to void *
printf("Name buffer address: %p\n", (void *) buffer);
My code is:
#include <stdio.h>
#include <string.h>
void main()
{
char string[10];
int A = -73;
unsigned int B = 31337;
strcpy(string, "sample");
// printing with different formats
printf("[A] Dec: %d, Hex: %x, Unsigned: %u\n", A,A,A);
printf("[B] Dec: %d, Hex: %x, Unsigned: %u\n", B,B,B);
printf("[field width on B] 3: '%3u', 10: '%10u', '%08u'\n", B,B,B);
// Example of unary address operator (dereferencing) and a %x
// format string
printf("variable A is at address: %08x\n", &A);
I am using the terminal in linux mint to compile, and when I try to compile using gcc I get the following error message:
basicStringFormatting.c: In function ‘main’:
basicStringFormatting.c:18:2: warning: format ‘%x’ expects argument
of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("variable A is at address: %08x\n", &A);
All I am trying to do is print the address in memory of the variable A.
Use the format specifier %p:
printf("variable A is at address: %p\n", (void*)&A);
The standard requires that the argument is of type void* for %p specifier. Since, printf is a variadic function, there's no implicit conversion to void * from T * which would happen implicitly for any non-variadic functions in C. Hence, the cast is required. To quote the standard:
7.21.6 Formatted input/output functions (C11 draft)
p The argument shall be a pointer to void. The value of the pointer is
converted to a sequence of printing characters, in an
implementation-defined manner.
Whereas you are using %x, which expects unsigned int whereas &A is of type int *. You can read about format specifiers for printf from the manual. Format specifier mismatch in printf leads to undefined behaviour.
A workaround to use %x with length specifier to print an int or unsigned int without compiler complaining about casting would be to use malloc:
unsigned int* D = malloc(sizeof(unsigned int)); // Allocates D
unsigned int D_address = *((unsigned int*) &D); // D address for %08x without warning
*D = 75; // D value
printf("variable D is at address: %p / 0x%08x with value: %u\n", D, D_address, *D);
Alternatively you can compile with gcc -w flag to suppress those casting warnings.
Edit for 64-bit addresses:
unsigned long* D = malloc(sizeof(unsigned long)); // Allocates D
unsigned long D_address = *((unsigned long*) &D); // D address for %016lx without warning
*D = ULONG_MAX; // D value
printf("variable D is at address: %p / 0x%016lx with value: %lu\n", D, D_address, *D);