Asked  7 Months ago    Answers:  5   Viewed   39 times

I've recently decided that I just have to finally learn C/C++, and there is one thing I do not really understand about pointers or more precisely, their definition.

How about these examples:

  1. int* test;
  2. int *test;
  3. int * test;
  4. int* test,test2;
  5. int *test,test2;
  6. int * test,test2;

Now, to my understanding, the first three cases are all doing the same: Test is not an int, but a pointer to one.

The second set of examples is a bit more tricky. In case 4, both test and test2 will be pointers to an int, whereas in case 5, only test is a pointer, whereas test2 is a "real" int. What about case 6? Same as case 5?

 Answers

16

4, 5, and 6 are the same thing, only test is a pointer. If you want two pointers, you should use:

int *test, *test2;

Or, even better (to make everything clear):

int* test;
int* test2;
Tuesday, June 1, 2021
 
themihai
answered 7 Months ago
54

* has different meaning depending on the context.

  1. Declaration of a pointer

    int* ap;  // It defines ap to be a pointer to an int.
    
    void foo(int* p); // Declares function foo.
                      // foo expects a pointer to an int as an argument.
    
  2. Dereference a pointer in an expression.

    int i = 0;
    int* ap = &i;   // ap points to i
    *ap = 10;       // Indirectly sets the value of i to 10
    
  3. A multiplication operator.

    int i = 10*20; // Needs no explanation.
    
Thursday, July 22, 2021
 
barden
answered 5 Months ago
27

There is absolutely no difference in functionality between

int* ptr;

and

int *ptr;

Which you use is up to you, there are multiple conflicting coding styles to choose from.

Monday, August 2, 2021
 
janlindso
answered 5 Months ago
35

TL;DR - that is how C syntax is designed to work.

The * is considered attached to the variable, because, it defines the type of the variable, not the datatype. The type of an object is supposed to be a property of the object itself, so it makes sense to consider the identifier of the property is associated with the object(variable).

To clarify, by saying int * p;, we mean to say, p is a variable of type pointer which points to an int. So, it makes sense to attach the * to the variable, rather than to the datatype.

Saturday, August 7, 2021
 
apokryfos
answered 4 Months ago
48

Good question, with a complicated answer. To really grasp this, you need to understand the internal structure of C++ declarations quite thoroughly.

(Note that in this answer, I will totally omit the existence of attributes to prevent overcomplication).

A declaration has two components: a sequence of specifiers, followed by a comma-separated list of init-declarators.

Specifiers are things like:

  • storage class specifiers (e.g. static, extern)
  • function specifiers (e.g. virtual, inline)
  • friend, typedef, constexpr
  • type specifiers, which include:
    • simple type specifiers (e.g. int, short)
    • cv-qualifiers (const, volatile)
    • other things (e.g. decltype)

The second part of a declaration are the comma-separated init-declarators. Each init-declarator consists of a sequence of declarators, optionally followed by an initialiser.

What declarators are:

  • identifier (e.g. the i in int i;)
  • pointer-like operators (*, &, &&, pointer-to-member syntax)
  • function parameter syntax (e.g. (int, char))
  • array syntax (e.g. [2][3])
  • cv-qualifiers, if these follow a pointer declarator.

Notice that the declaration's structure is strict: first specifiers, then init-declarators (each being declarators optionally followed by an initialiser).

The rule is: specifiers apply to the entire declaration, while declarators apply only to the one init-declarator (to the one element of the comma-separated list).

Also notice above that a cv-qualifier can be used as both a specifier and a declarator. As a declarator, the grammar restricts them to only be used in the presence of pointers.

So, to handle the four declarations you have posted:

1

int i = 0, *const p = &i;

The specifier part contains just one specifier: int. That is the part that all declarators will apply to.

There are two init-declarators: i = 0 and * const p = &i.

The first one has one declarator, i, and an initialiser = 0. Since there is no type-modifying declarator, the type of i is given by the specifiers, int in this case.

The second init-declarator has three declarators: *, const, and p. And an initialiser, = &i.

The declarators * and const modify the base type to mean "constant pointer to the base type." The base type, given by specifiers, is int, to the type of p will be "constant pointer to int."

2

int j = 0, const c = 2;

Again, one specifier: int, and two init-declarators: j = 0 and const c = 2.

For the second init-declarator, the declarators are const and c. As I mentioned, the grammar only allows cv-qualifiers as declarators if there is a pointer involved. That is not the case here, hence the error.

3

int *const p1 = nullptr, i1 = 0;

One specifier: int, two init-declarators: * const p1 = nullptr and i1 = 0.

For the first init-declarator, the declarators are: *, const, and p1. We already dealt with such an init-declarator (the second one in case 1). It adds the "constant pointer to base type" to the specifier-defined base type (which is still int).

For the second init-declarator i1 = 0, it's obvious. No type modifications, use the specifier(s) as-is. So i1 becomes an int.

4

int const j1 = 0, c1 = 2;

Here, we have a fundamentally different situation from the preceding three. We have two specifiers: int and const. And then two init-declarators, j1 = 0 and c1 = 2.

None of these init-declarators have any type-modifying declarators in them, so they both use the type from the specifiers, which is const int.

Sunday, September 5, 2021
 
Folks Coder
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share