As written in c books,an array name is a pointer to first element so here in names array,names points to first element which is also a pointer to string literal,then *names will print the first element,but in next line of code p points to a,and q points to q like names arr,but as u print *q u dont get a value which is 3,why?
#include <stdio.h>
int main(void){
char *names[]={"jack","philip"};
printf("%s\n",*names);
int a=3;
int *p=&a;
int *q=&p;
printf("%i\n",*q);
return 0;
}
a is an int, so p is a pointer to an int (int *), thus q is a pointer to a pointer to an int (int **). To print an int, you feed that int to printf:
printf("This is an int: %i\n", 42);
So for %i the function printf expects an argument of type int, but you pass *q to it, which is of type int *. You pass a pointer to printf, which does not expect a pointer for numbers, only for strings.
The difference is in printf(). The %s expects a pointer to a null terminated string, while %i expects to be handed the number itself, not a pointer to the number, which is what you have.
This is what the working code should look like
#include <stdio.h>
int main(void) {
char *names[]={"jack","philip"};
printf("%s\n",*names);
int a=3;
int *p=&a;
int **q=&p;
printf("%i\n",**q);
return 0;
}
%s expects a char* which as you correctly stated is what *names is, since names is of type char**. However %i expects an int. Since p points to a, p is an int pointer, since q points to p q is a pointer to an int pointer. q is just whatever p is pointing at (the address of a) so it won't print what you want. also assigning type int to the address of an int* (which is what youre doing when you do int* q = &p) will have unexpected results
printf("%i", *q);
would be like doing
printf("%c", *names);
which obviously will give strange output
Related
I am doing a homework of C programming.
#include <stdio.h>
typedef struct JustArray {
char *x;
} JustArray;
int main()
{
JustArray Items[12];
char *d = "Test";
Items[0].x = (char *) &d;
printf("Pointer: %p\n", &d);
printf("Address: %u\n",&d);
printf("Value: %s\n", d);
/*------------------------------------*/
//Knowing address of d from above, print value stored in it using Items[0].x. Cannot use &d, *d, or d.
char *ptr;
ptr = Items[0].x;
printf("%p\n", Items[0].x);
printf("%p\n", &ptr);
printf("%s\n", ptr);
return 0;
}
The output of ptr needs to be "Test" as well but it is showing me weird characters. The assignment is to have find a way to use the address info in Items[0].x and print its value "Test" in console. I could not find a way to do it...
Remember that the value of a pointer is an address. The content of a pointer (i.e. its dereference, the value pointed, addressed by it) is a value (with the type being pointed) which is in another place. So a int* has as value an address of another variable (of type int) which is stored in another address. Note that each primitive variable in C is the name of a data stored in some address.
int p = 1;
p above is a var of type int. It has 1 as value, which is directly given by p (so p == 1). p has an address (say 0x11111) that can be accessed with &p (so &p == 0x11111). Thus, p is the name of a variable whose value is an int (1) and whose address is 0x11111 (given by &p). This means that the value 1 (which is an int) is stored in the address 0x11111.
int* q = 0x22222;
q above is a var of type int* (pointer to int, meaning "an address to a var of type int"). q has an address as value (in this case is 0x22222), which is directly given by q (so q == 0x22222). but q also has an address (say 0x33333), which can be accessed with &q (so &q == 0x33333). Thus, q is the name of a variable whose value is an address to int (0x22222, given by q) and whose address is 0x33333 (given by &q). Basically, the value 0x22222 (which is an address) is stored in the address 0x33333.
You can use the prefix operator * over q to dereference it, i.e. access its content, which is the value stored in the address 0x22222, which is the value of q. So basically we have: q==0x22222, &q==0x33333, and *q==[whatever is the value stored in the adress 0x22222]. Now consider this:
int* r = &p;
Remember that p has value 1 (an int given by p itself) and address 0x11111 (given by &p). Now I declared a pointer to int called r and initialized it with the address of p (0x11111). Thus, r is a pointer whose value is an adress (0x11111), but it also has an address (say 0x44444).
The operator * prefixing a pointer lets us access the value of the address that is its value. So *r will give us 1 because 1 is the value stored in the address 0x11111, which is the value of r and the address of p at the same time. So r==&p (0x11111==0x11111) and *r==p (1==1).
Now lets go back to your code. When you declare a char* you already have a pointer, so the printing of it will be an address if you set %p as the desired format or a string if you set %s as the desired format. (The %s makes the function printf iterate throughout the contents whose start address is the value of the given pointer (and it stops when it reaches a '\0'). I fixed your code (and modified it a little bit for the sake of readability). The problem was that you were sending the addresses of the pointers instead of the pointers themselves to the function printf.
#include <stdio.h>
typedef struct justArray
{
char* x;
}
JustArray;
int main()
{
//d is a pointer whose content is an address, not a char 'T'
char* d = "Test";
printf("Pointer: %p\n", d); //print the address (no need for &)
printf("Address: %lu\n", (long unsigned) d); //print the address again as long unsigned)
printf("Value: %s\n", d); //print a string because of the %s
JustArray Items[12];
Items[0].x = d;
printf("%p\n", Items[0].x); //Items[0].x == d, so it prints the same address
char* ptr = Items[0].x;
printf("%p\n", ptr); //ptr == Items[0].x, so it prints again the same address
printf("%s\n", ptr); //prints the string now because of the %s
return 0;
}
The output of this program will be:
Pointer: 0x400734
Address: 4196148
Value: Test
0x400734
0x400734
Test
The key here is to notice what this line does:
Items[0].x = (char *) &d;
Observe first that d is a char * (i.e. a null-terminated string in this case), thus &d (taking a reference to it) must yield a value of type char * * (i.e. a pointer to a pointer to a char, or a pointer to a string). The cast to char * has to be done for the C type checker to accept the code. [Note that this is considered very bad practice, since you are forcing a value of one type into a value of another type that makes no sense. It's just an exercise though, and it's precisely this "bad practice" that makes it a bit of a challenge, so let's ignore that for now.]
Now, to get back d again, given just Items[0].x, we need to sort of "invert" the operations of the above line of code. We must first convert Items[0].x to its meaningful type, char * *, then dereference the result once to get a value of type char * (i.e. a null-terminated string).
char *d_again = *((char * *) Items[0].x);
printf("%s\n", d_again);
And viola!
Why in this code the pointer shifts to another location:
#include <stdio.h>
void f(int *p)
{
int j=2;
p=&j;
printf("%d\n%p\n%d\n",*p,&j,p);
}
int main(void)
{
int *q;
int m=98;
q=&m;
f(q);
printf("%p ",q);
return 0;
}
Output:
2
0x7ffff5bf1bcc
0x7ffff5bf1bcc
0x7ffff5bf1bc8
I understand that when the function f() is done with printing value of j and address of j the memory occupied by j goes back to the stack but IMO p should continue pointing that location even after the function is over & it should be printing the same address in main as well. What is wrong with this?
Considering you meant printf("%p ", (void *)q); in the actual code,
No, function argument(s) in C is (are) passed by value. It won't reflect the changes made to the parameter into the actual arguments used (in function call) themselves.
To put it into other words, the function parameters are local to the function (call) scope, any changes made to them won't be reflected to the actual arguments.
So, if you need to change a pointer, you need to pass a pointer to the pointer which needs to be changed.
Consider a rather light-hearted but realistic scenario.
void f (int x) { x = 10; }
int main(void) { f(5); printf ("%d", 5); return 0;}
Now, do you expect it to print 10?
That said, an advice. Always cast the argument to %p conversion specifier to (void *) (if it is not already). printf() is a variadic function and for pointers, no default argument promotion happens, so the supplied argument type needs to match the expected type, explicitly. Otherwise, technically it is undefined behavior.
Learn the difference between Pointers and Pointers to pointers - the pointer passed p is no doubt good to change the value of the variable it is pointing to (m), but to change the memory location it is pointing to - you need a pointer to pointer.
Expanding on top of what #SouravGhosh said, when you pass in a pointer to an int you are making a copy of the pointer. If you wanted to change the pointer you need to be doubly indirect and pass in a pointer to a pointer to an int. The first pointer is copied and you can directly affect the second pointer.
void f(int ** p)
{
int j = 2;
*p = &j;
printf("%d\n%p\n%p\n",*p,&j,p);
}
int main(void)
{
int ** q = (int **)malloc( izeof(int *));
int m = 98;
*q = &m;
f(q);
printf("%p ",q);
free(q);
return 0;
}
And the output is
2
0xffffcbcc
0xffffcbcc
0xffffcbcc
If you do this you'll see that it never changes:
#include <iostream>
#include "Header2.h"
#include "header1.h"
#include <stdio.h>
void f(int *p)
{
int j = 2;
p = &j;
printf("%d\n%p\n%p\n", *p, &j, p);
}
int main(void)
{
int *q;
int m = 98;
q = &m;
printf("Value of pointer q before calling f() =%p ", q);
f(q);
printf("Value of pointer q after calling f() =%p ", q);
return 0;
}
#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.
int a=4;
int *p=&a;
This syntax is right but when we write like this
int a;
int *p;
*p=&a;
The third line is an error and i know that but, why is it possible to do so in first code
int *p=&a;
We even do this when we pass the value by reference to functions ...
Thanks for the reply
with int *p=&a;, you are
declaring a variable (p) which is a pointer to an int
assigning the address of a to p
An equivalent code would be
int *p; // declare a pointer variable 'p'
p = &a; // assign the address of a to 'p'
The third line *p=&a; is an error because *p denotes the (integer) value of the pointer whose address is p, the value is an int and not a address of an int (i.e., not a pointer to an int)
The type is int *. So if the general pattern is:
T a;
T b;
a = b;
then with T = int *, the pattern is:
int * p;
p = &n; // n is an int
The "*" in the type specifier int * should not be confused with the almost entirely unrelated unary operator that is also called "*".
when you type
int *p;
you are declaring the pointer p.
using the * again after it has been declared would de-reference the pointer.
so
*p = &a;
would be saying "The value within pointer p = the reference to the value a"
the correct solution is
int *p;
p = &a
I'm trying to do it this way:
int (*p)(void);
int *i;
...
p = (int *(void))i;
But it's causing syntax error:
error: cast specifies function type
What's wrong here?
You should respect error in this case. You must not convert a pointer to function to an int pointer or other way around. That might result in undefined behavior.
If you insist then, syntax should be:
p = (int (*)(void))i;
i is a pointer to an integer, and p is a function pointer returning and int and taking no arguments. They are not compatible/castable in any way, shape or form.
What the compiler says. int (*p)(void) is a function pointer declaration (pointer to a function which returns an int). int *i; is a scalar pointer declaration (pointer to an int). You can't cast one into the other.
Write
p = (int (*)(void))i;
Here's an example:
#include <stdio.h>
int f(){
printf("test\n");
return 0;
}
int main()
{
int (*p)(void);
int *i;
i = (int*)f;
p = (int (*)(void))i;
printf("i=%p\n", i);
printf("p=%p\n", p);
((int (*)(void))i)(); //here, it will call f()
return 0;
}
If you must do it ( and I am in no way saying that you should) then:
typedef int (*fp)(void);
int *i;
fp p;
...
p = (fp)((void*)i);
*i points to a simple integer, while *p is a pointer to a function with no arguments returning an integer. Thus, these two have completely different types, and because you said p shall point to a function returning an int, you can not tell it to point to an int.
However, you can try to wrap both in a union like the following:
union u {
int *i;
int (*p)(void);
};
int f(void){
return 5;
}
int main(int argc, char *argv[]) {
union u myU;
int a=6;
myU.i=&a;
myU.p=&f;
return 0;
}
Note that after assigning &f, you can simply call myU.p(). But if you leave out the assignment of &f and call myU.p() afterwards, it results in undefined behaviour (i.e. program crashes).
You don't. That is, unless you know better than the compiler that the pointer stored in your int * came from an int (*p)(void) in the first place. As others have said, that second type is a pointer to a function that takes no parameters and returns an int. The first type is a simple pointer to an integer (or more than one integer if treated as an array).