Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hard time understanding precedence principle of char (*p)[sizeof(c)];

Tags:

c++

c

pointers

I'm learning pointers and to challenge myself I tried dereferencing a pointer to a character array. Eventually this worked:

char (*p)[sizeof(c)];

Where c is an array c[]="something"

I'm having a hard time understanding how (*p)[sizeof(c)]; differs from *p[sizeof(c)];

Based on what I know presently (which is not much!) the computer is saying this in the case of (*p)[sizeof(c)];:

"p points to c! oh, and btw, p is an array of whatever sizeof(c) ends up being".

But even that seems strange to me, so I guess I am confused as to what is being constructed when the parenthesis are added.

Can someone explain?

Full code in context here:

#include <iostream>

using namespace std;

int main(int argc, char *argv[]) {

    char c[] = "something";

    char (*p)[sizeof(c)]; // this works
    // char *p[sizeof(c)]; // this doesn't?

    p = &c;

    cout << p << endl;  

    cout << *p << endl;
}
like image 440
Pipsqweek Avatar asked Dec 28 '16 12:12

Pipsqweek


People also ask

What is sizeof char * in C?

sizeof is a unary operator in the programming languages C and C++. It generates the storage size of an expression or a data type, measured in the number of char-sized units. Consequently, the construct sizeof (char) is guaranteed to be 1.

What is the size of * p in this code?

And on a 32-bit system, it's size will be 32-bit(4 bytes). sizeof(*p) is the size of pointer type i.e. int here. So usually int is of 32-bit long that is 4 bytes.

What is the size of a character type in C and C ++?

In C++ the size of the character literal is char. In C the type of character literal is integer (int). So in C the sizeof('a') is 4 for 32bit architecture, and CHAR_BIT is 8. But the sizeof(char) is one byte for both C and C++.

What does int *) mean in C?

int* means a pointer to a variable whose datatype is integer. sizeof(int*) returns the number of bytes used to store a pointer. Since the sizeof operator returns the size of the datatype or the parameter we pass to it.


3 Answers

Types in C can be read with what is informally known as the right-left rule. You start from the name of the variable being declared, then go right while you can, then go left while you can, and start again. Parentheses stop you until all of their content has been considered.

In your example:

char (*p)[sizeof(c)];
       ^               p...                          (hit ')', turn around)
      ^                is a pointer...               (hit '(', turn around and remove '()')
         ^^^^^^^^^^^   to an array of `sizeof(c)`... (end of line, turn around)
^^^^                   chars.                        nothing left, we're done!

Without the parentheses, this becomes:

char *p[sizeof(c)];
      ^^^^^^^^^^^^     p is an array of `sizeof(c)`... (end of line, turn around)
^^^^^^                 pointers to char.

Which indeed is quite different.

like image 187
Quentin Avatar answered Oct 17 '22 05:10

Quentin


In this definition

char (*p)[sizeof(c)];

you define a variable p which is a pointer (the contenct of the brackets are evaluated first) to an array of characters with size [sizeof c]. At this point in your code p does not point anywhere specific as it is not initialized yet.

With the other definition

char *p[sizeof(c)];

you define a variable p which is an array (the * is evaluated later) of pointers to character.

you have a pointer to an array vs an array of pointers.

like image 43
Gerhardh Avatar answered Oct 17 '22 05:10

Gerhardh


Type mismatch in your assignment

p = &c;

is the problem.

c is an array of 10 chars and and &c is a pointer to an array of 10 chars.

In char (*p)[sizeof(c)];, p is a pointer to an array of sizeof(c) (10) chars. So, this matches with the type of &c.

In char *p[sizeof(c)];, p is an array of sizeof(c) (10) pointers. But this doesn't match with the type of &c.

like image 2
P.P Avatar answered Oct 17 '22 05:10

P.P