+ 13
C CHALLENGE QUESTION 🙋🏾♂️
https://www.sololearn.com/post/1500687/?ref=app // C challenge question #include <stdio.h> int main(){ static int a[] = {10, 20, 30, 40, 50}; static int *p[] = {a, a+3, a+4, a+1, a+2}; int **ptr = p; ptr++; printf("%d%d", ptr-p, **ptr); } //output: 140 Explanations are welcome 👍🏼
25 Answers
+ 14
Oh maaaan, who thinks of this? 🙄 A lot needs to be considered concerning pointer arithmetics.
So, a contains integers. And p contains a shuffled, and only references to entries of a.
ptr is a pointer, pointing to the beginning of the p array. In arithmetic expressions, p and ptr have the same type: int**. Essentially pointers.
Since ptr was incremented to point to p[1], pointer arithmetic has it that ptr-p is one. The type, iirc, is ptrdiff_t, an integral type. Output using %d thus gives 1. Double deref ptr from p[1] goes via a+3 (i.e. a[3]) to yield 40. Putting both together, you get 140.
+ 8
Thanks 👍🏼
And I think *p is an array pointer while **ptr is a pointer to the pointer (ie p).
+ 7
Quantum:
I do sololearn challenges a lot. And I just did a little experiment now with html challenge. And the duration for a question is approximately 39 seconds. Maybe 40 secs since I didn't wait for it to completely elapse.
We can do some challenges together if you want. It's fun! Let's do 15 challenges (that's the maximum number of challenges between 2 participants in one day).
+ 5
Quantum:
😂
You gave me a good laugh. Challenge questions on sololearn take more than 30 secs. And there are plenty easy ones. Add to that, the fact that questions get repeated then it won't be a big deal anymore.
+ 4
Romeo Cojocaru && Ani Jona 🕊
Thanks guys. I learned a lot.
+ 3
👍 👍 👍 👍
+ 3
Œ ㅤ In the C language the static keyword is a storage class specifier. it determines the storage location, lifetime, and visibility of a variable.
Contrary to ordinary local variables, a static local variable is not stored on the stack. Consequently it is not removed along with the stack frame, but retains its value after the end of a function
In this particular case, the static keyword serves no purpose since the function is never called a second time. The only notable difference would be in the file size of the final executable because static variables are stored inside the file.
+ 3
Ani Jona 🕊 So the array is actually stored inside the file?
+ 3
👑 Tchybooxuur! and Ani Jona 🕊
It's like this:
'a' is an statically allocated array, let's say at address 0x010 through 0x014 (these address values are not correct ones for a 4 byte integer, but I choose a simpler version);
examples:
a[0] = *a = 10;
a[3] = *(a + 3) = 40;
a[4] = *(a + 4) = 50;
&a = &a[0] = 0x010;
'p' is an array of pointers to int, having its own address from 0x015 - 0x019, each address holding / pointing to a reference to 'a', or storing 'a' addresses {0x010, 0x013, 0x014, 0x011, 0x012};
examples:
p[0] = 0x010 = &a[0];
*p[0] = *a = a[0] = 10;
&p[0] = 0x015;
'ptr' is a pointer to a pointer to int, having its own memory address, 0x020, and storing 'p' memory address 0x015, which is a reference to a[0].
examples:
ptr = &p = 0x015;
&ptr = 0x020;
*ptr = &a[0] = 0x010;
**ptr = *p = a[0] = 10;
Now the memory address stored in 'ptr' is incremented by 1, so 0x015 (&p[0]) is incremented to 0x016 (&p[1]).
+ 2
Ani Jona 🕊 What significance does 'static' have here? I don't get what the keyword means tbh
+ 2
Yes. That is, space is reserved inside the file. The array is not actually written to the file though as it's values change throughout the program. It's initial values are stored inside the file, and so the array is always initialised with the same values a every program start. But it's initialised only once.
+ 2
Ani Jona 🕊 Thank you
+ 2
(previous message continues) Subtracting the 2 addresses stored in 'p' and 'ptr', you have a difference of 1 (4 bytes for integer), and the value pointed by ptr, **ptr is also incremented by one. So, you will have:
ptr-p = &p[1] - &p[0] = 0x016 - 0x015 = 1;
**ptr = *(p+1) = *(a+3) = a[3] = 40;
Output: 1 concatenated with 40 => 140.
+ 2
Ani Jona 🕊
😂😅🤣 You are funny!
I didn't make any confusion between on incrementing a memory address with one and how memory address are represented on a machine.
An integer is on 4 bytes (on 32 bit system);
A pointer is on 8 bytes (both 32 and 64 bit system);
Pointer arithmetics are just adding or substracting values from memory addresses.
Can you point where did I confuse those 2? 🤩
+ 2
Ani Jona 🕊
Ok! You seems to be contradictory about my examples and comments, also saying that "nice and detailed explanation".
You should know that it took me 10 minutes of my simple life to write more than 1024 words in 2 separated messages.
I'm sorry that I couldn't give some 32 bit memory addresses in Hexa, so you won't be such judgemental.
If someone want to learn it should take my examples and use them on SoloLearn Playground.
Also, I have a series of explained questions in C challenges:
https://code.sololearn.com/cdHXhHaduFSf/?ref=app
https://code.sololearn.com/cCFmm2eH4Jru/?ref=app
+ 2
Quantum I'm very well aware about what is discussing here. Also, 6 sec. to answer a question in any challenge is relative, because easy questions have less seconds, while hard questions have more than 15 sec.
The world is changing, but not for the greater good... Any programming language is working with memory addresses, references and by no except with pointers. But those programming mechanisms are hidden in modern or worse in shortcut languages like Python, Swift or Kotlin.
Learning old, low-level programming languages is the key for a solid understanding. Even as your first programming languages, there is no excuse. My generation learned Turbo Pascal or C, even Java or C++ existed.
Also, programming languages like C have an easy syntax with less keywords than shortcut languages or abstract and high-level ones.
Why a pointer is a hard to understand subject?! Draw some memory stacks and some arrows to point from one memory address to another. Mix some knowledge from computer architecture from Wikipedia..
+ 1
Using a pointer size of 1 makes it look simple and convincing. I find your calculations misleading, though, Romeo Cojocaru, because replaced with a pointer size of 4 or 8, the differences will be larger, pointer arithmeic, however, will respect pointer sizes and still return 1, not 4 or 8. Otherwise a nice and detailed explanation.
+ 1
Romeo Cojocaru i was referring to the simple calculation &p[1]-&p[0] = 0x016 - 0x015 = 1. With a pointer size of 8, that would read &p[1]-&p[0] = 0x020 - 0x018 = 8. But even if the array holds structs of a kilobyte in size, the difference of two elements in an array still returns the distance in elements, not byte.
+ 1
Romeo Cojocaru We are taking about a challenge where you have to answer within 6 seconds, and the pointer thing in C is definitely not for beginners.
Maybe 20 years was a little bit exaggerated, but C is fundamentally different because of the pointer thing.
Understanding C as a first language was something you did 40 years ago, but not today,
You can always learn C if you are planning to write a new operating system or a new programming language or something like that.
Personally, I think that C is an interesting language, but it's not a language that everybody should learn as a first language. Its too complicated for beginners, and most of them would leave the coding world quite quickly if they were forced to learn C as their first language.