#include<stdio.h>
int main()
{
static char *s[]={"black","white","pink","violet"};
char **ptr[]={s+3,s+2,s+1,s},***p;
char a[]={"DEAD"};
p=ptr;
++p;
printf("%c\n",a[0]);
printf("%s\n",*s); //black
printf("%s\n",*s+1); //lack
//printf("%s\n",s+1);
printf("%s\n",s[0]);//black
printf("%s\n",s[1]);//white
printf("%s\n",s[2]);//pink
printf("%s\n",s[1]);//violet
printf("%s\n",s[1]+1);//hite
printf("%s\n",s[1]+6);//pink
printf("%s\n",**p+1); // how does this prints ink
return 0;
}
output:
D black lack black white pink white hite pink ink
please help to understand
so, p is a pointer to a pointer to a string, which basically is a pointer to a char.
p itself points to the first element of the ptr array; after p++ it points to the second, which is s+2.
s+2 points to the third element in the s array, which is "pink"
these are the two levels od dereferencing performed by **p
now, **p points to the first character of "pink", thus **p+1 points to the 'i'
now, printf takes the pointer to the i and prints everything until the next null byte, resulting in "ink" being printed to your console.
I assume you have no problem with lines I haven't directly copied
printf("%s\n",*s+1); //lack
*s+1 is the same as (*s) + 1
printf("%s\n",s[1]+6);//pink
s[1]+6 is the same as (s[1]) + 6. s[1] has type char*, so s[1]+6 points 6 characters to the right. But it's illegal to do that: s[1] only points to 6 valid characters. You just had (bad) luck that your program didn't crash.
printf("%s\n",**p+1); // how does this prints ink
approximately the same things go for **p+1 :)
You have to understand pointers.
s[0] is exactly the same as *s.
If you have s[0]+1, it points one char further than s[0].
s[1] is the same as *(s+1), but it is completely different from *s+1, which is the same as s[0]+1.
You have to draw arrows on a blackboard.
p = ptr;
++p; /* p now points to the second element of ptr "s+2" */
/* s+2 points to the third element of s "pink" */
/* **p+1 will point to the second character of "pink", thus "ink"; essentially **(s+2)+1 */
Related
Hello i just need to see why my Gcc stopped working after execution.
#include<stdio.h>
int main()
{
static char *s[] = {"black", "white", "pink", "violet"};
char **ptr[] = {s+3, s+2, s+1, s}, ***p;
p=ptr;
++p;
printf("the value of **p is %s\n\t",**p); // printed on screen pink
printf("the value of **ptr[1] is %s\n\t",**ptr[1]); // here got the error
printf("the value of *(s[2]) is %s\n\t",*s[2]); // here got the error
return 0;
}
**ptr[1] is a char. You are passing it to printf for a %s conversion. %s requires a pointer to char, not a char. Pass *ptr[1] instead.
Similarly, instead of *s[2], pass s[2].
Assuming you're referring to the segfault on the last two printf's that you commented, you're dereferencing one time too many. ptr is an array of pointers to strings, but you dereference the second item twice, which gives a character. s is an array of strings, and dereferencing the third element also gives you a character. You can fix it by removing one * on each:
printf("the value of *ptr[1] is %s\n\t", *ptr[1]);
printf("the value of s[2] is %s\n\t", s[2]);
This gives the following output:
the value of **p is pink
the value of *ptr[1] is pink
the value of s[2] is pink
char mening[] = "tjena pa dig hog";
This string contains 16 characters. I am then using a function adresss() to find the memory address of a random character in that array. The function adresss() returns a pointer containing the address. The address is at this moment 0x7ffeefbff5f9.
I now need to know what positions that address is pointing to, example is it pointing to the "t" at position 0 in the array, or maybe it is pointing to "d" at position 9. How do I do this?
Edit:
char* adresss(char mening[]){
//Lots of code going on here
return &mening[i];
}
int main(void){
char mening[] = "tjena pa dig hog";
char* ptr;
ptr = adresss(mening);
printf("%p\n", ptr);
That is basically how I get the memory adress. I want to know what "i" was, inside the main function only knowing the memory adress.
If you have two pointers, both pointing to the same array (or to one beyond the end of the array), then you can subtract them from each other.
For example:
char mening[] = "tjena pa dig hog";
char *pointer_to_mening = &mening[10]; // Pointer to the eleventh character
// Should print 10 (which is the index of the eleventh character)
printf("The distance is %zu\n", pointer_to_mening - mening);
This is the code that make me confused.
static char *s[] = {"black", "white", "pink", "violet"};
char **ptr[] = {s+3, s+2, s+1, s}, ***p;
p = ptr; // p point to the address of (s+3), so "violet"
++p; // p point to "pink"
printf("%s", **p+1); // I though it print "pink" but answer is "ink", I'm not sure about the sequence of ** and +, which executes first and how is this one begins from "i"?
After ++p, p does not point to "pink". It points to ptr[1], and ptr[1] points to s[2], and s[2] points to the first character of "pink".
*p is ptr[1], and **p is s[2]. So **p + 1 is &s[2][1], i.e. the "i" in "pink".
It is like:
char *ptr = **p; // ptr points to the 'p' in "pink"
printf("%s", ptr + 1);
static char *s[] = {"black", "white", "pink", "violet"};
The above statement defines s to be an array of characters and initializes its elements with pointers to the first element of the string literals enclosed in braces. static means the array s has internal linkage and its lifetime extends across the entire program run.
char **ptr[] = {s+3, s+2, s+1, s}, ***p;
The above statement defines ptr to be an array of objects of type char **, i.e., pointer to pointer to characters. It also defines p of type char ***, i.e., a pointer to a pointer to a pointer to a character. It initializes ptr with pointers to elements of the array s.
Therefore, ptr[0] points to s[3], ptr[1] points to s[2] and so on. The below two statements are equivalent. This is because the array ptr decays (evaluates) to a pointer to its first element.
p = ptr;
// the above is equivalent to
p = &ptr[0];
++p; // makes p point to the next element of ptr
The side effect of executing the above statement is to increment p, i.e., make it point to the next element which is ptr[1].
**p+1
Indirection operator * has higher precedence. Therefore, **p is evaluated first. Since p is pointing to ptr[1], *p evaluates to ptr[1]. Now ptr[1] is pointing to s[2], therefore **p evaluates to s[2]. s[2] is pointing to the first element of the string literal "pink". This means **p + 1 points to the next element, i.e, 2nd element which is 'i'.
printf("%s", **p + 1); // prints ink
// equivalent to
printf("%s", "pink" + 1); // prints ink
// equivalent to
printf("%s", &"pink"[1]); // prints ink
**p points to pink (i.e. **p == s[2]). Incrementing that pointer (**p) + 1 will make it point to the i in pink, so printf will print ink. Elementary. :)
The rule of thumb is that if you feel the need for declaring a triple-pointer, you are doing something wrong.
*p gives ptr[1]
**p gives value stored at s+2 i,e "pink" and it points to character p
now **p+1 gives the string ink
void main()
{
printf("ABCD");
printf("\n");
printf("ABCD" +1);
printf("\n");
printf("ABCD" +3);
}
Outputs is:
ABCD
BCD
D
Can anyone explain me why?
"ABCD" is actually an array of characters {'A','B','C','D', '\0'} (where '\0' is the trailing null byte). If you add 3 to that, then that is the equivalent of advancing a pointer 3 bytes forward from A, so you end up pointing at D.
Question 6.2 in the C FAQ has a picture that makes this clearer. The array decays to a pointer as described in 6.4 so you have the situation of the variable p.
char a[] = "hello";
char *p = "world";
"ABCD" is treated as a pointer to a block of memory containing four characters followed by a null terminator (\0).
"ABCD" + 1 adds 1 to the pointer, causing it to point one byte further.
I am new to pointers in C. I know the basic concepts. In the below code, why is it printing the "ink" as its output?
#include<stdio.h>
main()
{
static char *s[]={"black","white","pink","violet"};
char **ptr[]={s+3,s+2,s+1,s},***p;
p=ptr;
++p;
printf("%s",**p+1);
}
Thanks
Let's trace it:
ptr = {pointer to "violet", pointer to "pink", pointer to "white", pointer to "black"}
p = ptr --> *p = pointer to "violet"
++p --> *p = pointer to "pink"
This implies that:
*p = {'p','i','n','k','\0'}
Which means:
**p = 'p'
**p + 1 = 'i'
so **p + 1 is a pointer to this string: {'i', 'n', 'k', '\0'}, which is simply "ink".
s is an array of char * (which represent strings).
ptr is an array of pointers to pointers (pointing to the values of s, which are pointers to strings)
p is set to point to ptr[0] (which is a pointer to s[3] or "violet")
p is incremented to point to ptr[1], which points to s[2] or "pink"
In the printf statement p is dereferenced twice. The first deref is a pointer to s[2], the second deref gets you the value of s[2] - "pink". The +1 shifts the pointer to the start of "pink" on by one char, so printing from here to the end of the string will give you "ink".
I'd advise that you work backwards from what you know was printed (the 'ink' in 'pink') and see where the different variables must be pointing for that to happen.
Remember that an array can be viewed as a pointer to its first element and that a string can similarly be viewed as a pointer to its first character.
static char
*s[]={"black","white","pink","violet"};
In the above statement you are initialize.
char **ptr[]={s+3,s+2,s+1,s}
In the above statement you are assign pointer s value to ptr
value. And declare a triple pointer.
p=ptr;
In the above statement you assign the double pointer address to
triple pointer.
++p;
In the above statement you increment the triple pointer value. So
that time it point to "pink".
But you are print the **p+1. That time it will print only "ink".
If you print **(p+1), that time it
will print "white". Because in the
initialization of double pointer you
initialize the "s+2". So that time it
will points to the "white".