Why is the dereference operator (*) also used to declare a pointer?

I'm not sure if this is the right programming question, but this is what has always bothered me, and I wonder if I'm not the only one.

When I studied C ++, I understood the concept of links, but the pointers confused me. Why do you ask? Because of how you declare a pointer.

Consider the following:

void foo(int* bar) { } int main() { int x = 5; int* y = NULL; y = &x; *y = 15; foo(y); } 

The foo(int*) function takes an int pointer as a parameter. Since I declared y as an int pointer, I can pass y to foo , but when I first learned C ++, I associated the * character with dereferencing, so I decided to dereference the int needed for the transfer. I would try passing *y to foo , which obviously does not work.

Wouldn't it be easier to have a separate statement for declaring a pointer? (or for dereferencing). For example:

 void test(int@ x) { } 
+49
c ++ syntax pointers dereference notation
Dec 31 2018-11-12T00:
source share
6 answers

In C language development, Dennis Ritchie explains his reasoning in this way:

The second innovation that most clearly distinguishes C from its predecessors is a more complete type structure and especially its expression in the syntax of declarations ... taking into account an object of any type, it should be possible to describe a new object that collects several into an array, returns it from a function or a pointer to it ... [This] led to declaration syntax for names duplicating the syntax of an expression in which names usually appear. In this way,

int i, *pi, **ppi; declare an integer, a pointer to an integer, a pointer to a pointer to an integer. The syntax of these declarations reflects that i, *pi, and **ppi all give an int type when used in an expression.

Similarly, int f(), *f(), (*f)(); declare a function that returns an integer, a function that returns a pointer to an integer, a pointer to a function that returns an integer. int *api[10], (*pai)[10]; declare an array of pointers to integers and a pointer to an array of integers.

In all these cases, the declaration of a variable resembles its use in an expression, the type of which is the one named at the head of the declaration.

A syntax accident contributed to the perceived complexity of the language. The indirection operator, written * in C, is a syntactically unary prefix operator, as in BCPL and B. This works well in simple expressions, but in more complex cases, parentheses are required to guide the analysis. For example, to distinguish indirection through the value returned by the function from the call, the function indicated by the pointer writes *fp() and (*pf)() respectively. The style used in expressions is declarations, so names can be declared

int *fp(); int (*pf)();

In richer, but still realistic cases, things get worse: int *(*pfp)(); - a pointer to a function returning a pointer to an integer.

There are two effects. Most importantly, C has a relatively rich set of description methods (compared, say, to Pascal). Ads in languages ​​such as C-Algol 68, for example, describe objects equally hard to understand, simply because the objects themselves are complex. the second effect is related to the details of the syntax. C declarations must be read inside out, which many people find difficult to understand. Sethi [Sethi 81] noted that many of the nested declarations and expressions would become easier if the indirection operator was accepted as a postfix operator instead of a prefix, but by then it was too late to change.

+81
Dec 31 2018-11-11T00:
source share

The reason is clearer if you write it like this:

 int x, *y; 

That is, both x and y are int. So y is int *.

+13
Dec 31 '11 at 0:59
source share

This is a language solution that precedes C ++, since C ++ inherited it from C. I once heard that the motivation was to declare and use would be equivalent, that is, given the declaration int *p; the expression *p is of type int in the same way as with int i; expression i is of type int .

+9
Dec 31 '11 at 1:00
source share

Since the committee and those who developed C ++ decades before its standardization decided that * should retain its original three values :

  • Pointer type
  • Dereference operator
  • Multiplication

You are right to assume that multiple values * (and, similarly, & ) are confusing. For several years I have been of the opinion that this is a significant barrier to understanding newcomers to the language.




Why not choose a different character for C ++?

Backward compatibility is the main reason ... it is better to use existing characters in a new context than to break C programs by translating previously non-operators into new values.




Why not choose a different character for C?

It is impossible to know for sure, but there are several arguments that may be - and were? did. First of all, the idea is that:

when the identifier [an] appears in an expression of the same form as the declarator, it gives an object of the specified type. {K & R, p216}

This is why C programmers tend to [edit] prefer to align their stars to the right rather than the left, that is:

 int *ptr1; // roughly C-style int* ptr2; // roughly C++-style 

although both species are found in programs of both languages, changing.

+5
Dec 31 '11 at 1:01
source share

Page 65 of C: Deep C Secrets Expert Programming includes the following: And then there is a C philosophy that declaring an object should look like its use.

Page 216 of the C programming language, second edition (aka K & R) includes: the declarator is read as a statement that when its identifier appears in an expression of the same form as the declarator, it gives an object of the specified type.

I prefer how van der Linden does it.

+4
Dec 31 '11 at 1:15
source share

Haha, I feel your pain, I had the same problem.

I thought that the pointer should be declared as &int , because it makes sense that the pointer is the address of something.

After a while I thought about myself, each type in C should be read back , for example

int * const a

for me

a constant something, when dereferenced equals an int . What should be dereferenced must be a pointer.

+1
Apr 09 '15 at 7:39 on
source share



All Articles