int main() { char *c[] = {"ENTER", "NEW", "POINT", "FIRST"}; char **cp[] = {c+3, c+2, c+1, c}; char ***cpp = cp; printf("%s", **++cpp); printf("%s", *--*++cpp+3); printf(" %s", *cpp[-2]+3); printf("%s", cpp[-1][-1]+1); system("pause"); return 0; } 

Please explain why the conclusion: POINTER STEW

The lesson did not really explain anything about pointers, neither increment nor increment. Also, I don’t understand why the printf("%s", *(c+1)); code printf("%s", *(c+1)); compiles, and printf("%s", *++c); do not compile.

  • 7
    The horrors that you have in class - m9_psy

3 answers 3

 //массив указателей на строковые константы char *c[] = {"ENTER", "NEW", "POINT", "FIRST"}; char **cp[] = {c+3, c+2, c+1, c}; //первый элемент c+3, // т.е. мы идем три раза вперед на размерность с и попадаем на POINT char ***cpp = cp; //ехал указатель через указатель, // видит в реке указатель, // сунул указатель в указатель, // гитлер гитлер гитлер гитлер printf("%s", **++cpp); //выводится POINT printf("%s", *--*++cpp+3); //снова шастаем по указателям, // приходим на ENTER, прыгаем на 3 размера данного указателя вперед // (теперь это char жизнь, сынок, это просто, как ездить на велосипеде, // и мы в аду и ты горишь и велосипед горит) // вместо ENTER получаем ER (ENT ER) // выводится в итоге POINTER 

further you understand.

And yes, the horrors you have in class.

when someone looks at this terrible example and examines it in more detail, will gladly delete the answer, the main thing for me is that the OP does not go through the veins with the razor.

here is a hint of a solution, thanks for a good example, pointer stew is google

ps Pointer stew is translated as (thick) soup (stew, stew) pointers. Soup from pointers. Handsomely.

  • * - * ++ cpp + 3 did not quite understand how they got into Enter at all - j6wj1997
  • Because of the pre-increment operator, (++ variable, not variable ++), it first increases the value and returns it to the expression, I would recommend you by the way to take the operator precedence table and place brackets to more easily understand the example en.cppreference .com / w / cpp / language / operator_precedence - strangeqargo
  • most likely you have a task on the topic of understanding the sequence of operators and which way they work (from left to right or from right to left) - strangeqargo
  • 2
    @ j6wj1997 After ++cpp in the previous line, cpp points to the string cp[2] , i.e. "NEW". Then ++cpp is executed, and it becomes pointing to the string cp[3] , i.e. "ENTER". - Harry

On the second part of the question:

Also, I don’t understand why the printf ("% s", * (c + 1)) code; compiles, and printf ("% s", * ++ c); do not compile.

Because ++c changes the value of c itself, and it cannot be changed - c is an array (yes, in fact it is a pointer to the first element of the array, but these are the rules of the game).

  • Not quite like this: the prefix ++ for the built-in type expects lvalue , the expression c is rvalue , hence the impossibility of compiling this example. - ixSci
  • @ixSci Frankly speaking, I decided to hide it in the “rules of the game”, because then I need to explain what lvalue and rvalue are, and, actually, go back to what they started from - why c is rvalue ... - Harry
  • one
    also true, just for more advanced users could be painted, probably. - ixSci
  • @ixSci in accordance with the Standard Standard: Analogue that An lvalue is an expression (with an object type other than void) that potentially designates an object; . Those. c is a lvalue . But further it has already been said about modifiable lvalue : A modifiable lvalue is an lvalue that does not have array type ... - αλεχολυτ
  • one
    @ixSci is just a current question in fact to c ++ does not apply at all. For pure c , especially with string literals without const . - αλεχολυτ pm

The execution of prefix increments / decomposition and pointer derefections comes from the variable name to the left, and A [i] is equivalent to * (A + i), therefore, without additional parentheses, the array element will be accessed first through square brackets. And for the same reason, the record i [A] is absolutely valid, you can try to write like this on the control: D

Now for your code:

printf("%s", **++cpp); pointer cfp is incremented by 1, and points to c + 2, c + 2 is an element of the array with index 2 (remember that the counting starts from zero) dereference it with two asterisks, and we get the string "POINT".

printf("%s", *--*++cpp+3); here, cfp is again increased by 1, and starts pointing to c + 1, then we dereference it 1 time, now our piece of expression points to "NEW" already in the c array (the cp array contains only copies of pointers to different parts of c), obtained from +1 decrementing, we get with, dereferencing again, we get the string "ENTER", and only now adding to this line (that is, to the pointer to its zero element) triples, that is, the beginning of the line is shifted by 3 and it turns out "ER"

printf(" %s", *cpp[-2]+3); first, we refer to cpr [-2], that is, it was c + 1, it became c + 3, and a dereferencing by one level occurred, cpr [-2] is equivalent to * (cpr-2), dereference again, we get the string " FIRST ", shift its beginning by 3 characters and get" ST "

printf("%s", cpp[-1][-1]+1); remember that cfp is still equal to c + 1, and then the first brackets give us c + 2, and the second give us the string "NEW", increase its beginning by 1, and it turns out "EW".