Need help understanding char and int pointers - c

In this code to print the value of int and char pointer variables, why do I access them differently? For the char pointer I write sampleclient but for the int I write *intid. Why does one use * but not the other?
int main()
{
char client[] = "ABCD";
int intid = 10;
samplepass(&client, &intid);
return 0;
}
void samplepass(char *sampleclient, int *intid)
{
printf("%s %d\n", sampleclient, *intid);
}

This is because %s format specifier expects a char pointer, while %d expects an integer argument. If you want to see the value of the pointers themselves(i.e. the address they point to) use %p.

In C, you can't pass a string (character array) to a function like printf, so you do the next best thing: pass it its address in memory. The function can then treat the memory address like an array using pointer arithmetic. So the way printf reads strings is by taking in a pointer to the string. Then %s displays the dereferenced string (ABCD here), not the pointer address (which you could get by using %p instead of %s).
The integer problem is more straightforward: the * in *intid means 'get the value stored at this address'. That's why it prints out 10, not the memory address.
The 'correct' format specifier to get a memory address is %p. But you could write:
int main()
{
char client[] = "ABCD";
int intid = 10;
samplepass(&client, &intid);
return 0;
}
void samplepass(char *sampleclient, int *intid)
{
printf("%d %d\n", sampleclient, intid);
}
On my machine, the output was
-2140958000 -2140958004
(and those are the addresses in memory of client and intid). Substituting %p for %d gives nicely formatted pointers with a 0x in front and conforms to the standard, so I'd use that.

For an output that looks like:
ABCD 10
change your line
from samplepass(&client,&intid);
to samplepass(client,&intid);

Related

working with char pointer and integer pointer

My question is about dereferencing a char pointer
Here is my code -
#define MAX 10
char s[80]="Hello";
int main(){
char *stackValue;
stackValue=&s;//here I assined the address of s to stackValue
if(!stackValue){
printf("No place for Value");
exit(1);
}
else{
printf("\n%s",*stackValue);//This doesn't work with * before it
printf("\n%s",stackValue);//This works properly
}
return 0;
}
In the above code I have assigned the address of S[] to stackValue and when I am printing *stackValue it doesn't work ,
But If I print only 'stackValue' That works.
When I do same thing with Integer
int main(){
int i=10, *a;
a=&i;
printf("%d",*a);//this gives the value
printf("%d",a)//this gives the address
return 0;
}
Is printing char pointer and integer pointer is different. When I use * in int value it gives the value but gives an error when I use it as a char pointer.
Help me out?
With the first code snippet:
stackValue=&s; is incorrect given s is already an array to char. If you write like that then stackValue becomes pointer to pointer to char (not pointer to char).
Fix that by changing to stackValue=s;
Also, again %s expect a pointer to char (NOT pointer to pointer to char) - that explains why this doesn't work
printf("\n%s",*stackValue); // this doesn't work
You need printf("\n%s",stackValue); instead.
With the second code snippet.
a=&i; is ok because i is a single int, NOT an array.
What you are trying to do is this:
int main(void)
{
char a_data = "Hello, this is example";
char *pa_stack[] = {a_data};
printf("We have: %s\n", *pa_stack);
}
The "%s" format specifier for printf always expects a char* argument.
so this is working and correct statement
printf("\n%s",stackValue);
and in first statement you are passing value so it will give you undefined behaviour.

malloc() pointer output clarification

I'm trying to learn C, more specifically pointers and malloc(). I wrote the following program and need a few clarifications about warning messages I got and the output.
#include<stdio.h>
#include<stdlib.h>
void printem(char *ptr, char loopagain)
{
int i;
for (i = 0; i < loopagain; i++)
{
printf("Found %c at address %c \n",ptr[i],&ptr[i]);
}
return;
}
void initializeblock(char *ptr, char loopagain)
{
int i;
for (i = 0; i < loopagain; i++)
{
ptr[i] = 65+i;
}
return;
}
int main()
{
char neededbytes = 10;
char *p;
p = (char *) malloc(neededbytes * sizeof(char));
if(p==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
else
{
printem(p,neededbytes);
initializeblock(p,neededbytes);
printem(p,neededbytes);
}
free(p);
}
The first problem I have is I don't get the address of each of the 10 char elements to print out correctly as numbers. Instead of a numbers I get symbols. This is the line of code that prints out the values and addresses.
printf("Found %c at address %c \n",ptr[i],&ptr[i]);
What am I doing wrong?
The second problem is inside the else statement I have the following code
printem(p,neededbytes);
initializeblock(p,neededbytes);
printem(p,neededbytes);
originally I used an & before p but got the following warnings
[Warning] passing argument 1 of 'printem' from incompatible pointer type
[Note] expected 'char *' but argument is of type 'char **'
The examples I found online show that a function expecting a pointer should have the address passed to it, why am I getting the warings when I use
printem(&p,neededbytes);
initializeblock(&p,neededbytes);
printem(&p,neededbytes);
Also, when I allocate a block using malloc(), is there another way to access/modify the data other than using array brackets, p[i]?
Is there a way to know the size of the block allocated so I don't have to pass it as an argument in the following line
printem(p,neededbytes);
First of all
printf("Found %c at address %c \n",ptr[i],&ptr[i]);
should be at least
printf("Found %c at address %p \n",ptr[i],(void *)&ptr[i]);
because, &ptr[i] is an address and it needs %p format specifier. Then, printf() being a variadic function, only default argument promotion takes place, so you need to cast the argument to void *, the expected type of %p. Using inappropriate type argument for conversion specifier leads to undefined behavior.
That said, even this won't save you. At the point you're calling printem(), the memory location pointed by p is uninitialized [#]and the content of it is undeterministic. Using uninitialized value will again lead you to UB. So, you need to initialize the memory before trying to print the value.
Then, check the signature of initializeblock()
void initializeblock(char *ptr, char loopagain)
and the call on which you got the warning
initializeblock(&p,neededbytes);
in this call, you're trying to pass &p which is of type char ** and trying to receive the same in a char *, which triggers the warning. You should be fine with a call like
initializeblock(p,neededbytes);
in this case.
Lastly
Is there a way to know the size of the block allocated so I don't have to pass it as an argument in the following line...
I'm afraid, no. There is no standard way of knowing the allocated size just from the pointer, so you have to pass the size as a second parameter.
[#] malloc() returns uninitialized memory.

Why does the C program give me this output when printing a pointer?

#include <stdio.h>
int main()
{
int i;
int buf[10];
char *p ;
p = 4;
printf("%d",p);
return 0;
}
Output:
4
How come it is 4? I was expecting some address value. Can you please help me understand it?
This is undefined behavior, because %d expects an integer.
The reason why you see this output is that pointers have enough capacity to store small integer numbers, such as 4. If by coincidence the pointer size on your system matches the size of an integer, printf would find a representation that it expects at the location where it expects it, so it would print the numeric value of your pointer.
The proper way to print your pointer would be with the %p format specifier, and a cast:
printf("%p", (void*)p);
I was expecting some address value.
You would get an address value if you had assigned p some address. For example, if you did this
char buf[10];
char *p = &buf[3];
printf("%p", (void*)p);
you would see the address of buf's element at index 3.
Demo.

Issue with string and pointers

Can somebody tell me why this program does not work?
int main()
{
char *num = 'h';
printf("%c", num);
return 0;
}
The error I get is:
1>c:\users\\documents\visual studio 2010\projects\sssdsdsds\sssdsdsds\sssdsdsds.cpp(4): error C2440: 'initializing' : cannot convert from 'char' to 'char *'
But if I write the code like that:
int main()
{
char num = 'h';
printf("%c", num);
return 0;
}
it's working.
char *num = 'h';
Here, the letter 'h' is a char, which you are trying to assign to a char*. The two types are not the same, so you get the problem that you see above.
This would work:
char *num = "h";
The difference is that here you're using double-quotes ("), which creates a char*.
This would also work:
char letter = 'h';
char* ptrToLetter = &letter;
You should read up on pointers in C to understand exactly what these different constructions do.
char * is a pointer to a char, not the same thing than a single char.
If you have char *, then you must initialize it with ", not with '.
And also, for the formatting representation in printf():
the %s is used for char *
the %c is only for char.
In thefirst case you declared num as a pointer to a char. In the second case, you declare it as a char. In each case, you assign a char to the variable. You can't assign a char to a pointer to a char, hence the error.
'h' = Char
"h" = Null terminated String
int main()
{
char *num = "h";
printf("%s", num); // <= here change c to s if you want to print out string
return 0;
}
this will work
As somebody just said, when you write
char *num = 'h'
The compiler gives you an error because you're trying to give to a pointer a value. Pointers, you know, are just variables that store only the memory address of another variable you defined before. However, you can access to a variable's memory address with the operator:
&
And a variable's pointer should be coerent in type with the element pointed.
For example, here is how should you define correctly a ptr:
int value = 5;
//defining a Ptr to value
int *ptr_value = &value;
//by now, ptr_value stores value's address
Anyway, you should study somewhere how this all works and how can ptrs be implemented, if you have other problems try a more specific question :)
When you are using char *h, you are declaring a pointer to a char variable. This pointer keeps the address of the variable it points to.
In simple words, as you simply declare a char variable as char num='h', then the variable num will hold the value h and so if you print it using printf("%c",num), you will get the output as h.
But, if you declare a variable as a pointer, as char *num, then it cannot actually hold any character value. I can hold only the address of some character variable.
For example look at the code below
void main()
{
char a='h';
char *b;
b=&a;
printf("%c",a);
printf("%c",b);
printf("%u",b);
}
here , we have one char variable a and one char pointer b. Now the variable a may be located somewhere in memory that we do not know. a holds the value h and &a means address of a in memory The statement b=&a will assign the memory address of a to b. Since b is declared as a pointer, It can hold the address.
The statenment printf("%c",b) will print out garbage values.
The statement printf("%u",b) will print the address of variable a in memory.
so there's difference between char num and char *num. You must first read about pointers. They are different from normal variables and must be used very carefully.

Learning C - Pointers and memory addressing

I am learning C programming and I have a simple question about pointers...
I used the following code to play around with pointers:
#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
printf("%x\n",c);
return 0;
}
When I print the value of C, I get back a 0. However, when I print &c (i.e. printf("&x\n",&c) I get an address in memory...
Shouldn't I be getting an address in memory when printing the pointer (i.e. printf("%x\n",c)?
--- EDIT ---
#include <stdio.h>
#include <stdlib.h>
int main (int argc, const char * argv[]) {
char * a = malloc(11);
printf("String please\n");
scanf("%s",a);
printf("%s",a);
}
The question is, why does printf("%s",a) returns the string instead of the address that is stored in a?
Shouldn't I use *a to follow the pointer and then print the string?
your current program is not correct. You define variable and do not set value before first use. the initial value is not guranteed for c, but you are lucky and it is equal to 0. It means that c points to nowhere. when you print &c you print address of variable c itself. So actually both versions print address.
printf is actually quite a complex function and can be made to do all sorts of tricks by giving it the right format specifier.
In your string example:
printf("%s", a)
the "%s" tells the printf function that the following variable should be treated as a string. In C, a string is a pointer to one or more char, terminated by a char containing 0. This is a pretty common request, which is why printf supports a format specifier "%s" that triggers this relatively complex behavior. If you want to print the address contained in the string pointer you have to use the format you found earlier:
printf("%x\n",a);
which tells printf to treat the contents of a as an unsigned integer, and print it in base 16.
*a would just be the value pointed to by a, which is just a single character.
You could print the single character with
printf("%c", *a);
Having int* c; If you print value of c, you get back a value that should be interpreted as a memory address of an integer value. In you example it might be 0 or something completely different as you are not initializing c.
If you print &c you get memory address of the pointer c (stored in stack).
#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
int a=10;
c = &a;
printf("%x\n",c);
return 0;
}
This may clarify what happens when you make the int pointer point to something in memory.

Resources