What Are the Distinctions Between the Various Symbols (*,&, etc) Combined with Parameters

What are the distinctions between the various symbols (*,&, etc) combined with parameters?

To understand this you'll first need to understand pointers and references. I'll simply explain the type declaration syntax you're asking about assuming you already know what pointers and references are.

In C, it is said that 'declaration follows use.' That means the syntax for declaring a variable mimics using the variable: generally in a declaration you'll have a base type like int or float followed something that looks like an expression. For example in int *y the base type is int and the expression look-alike is *y. Thereafter that expression evaluates to a value with the given base type.

So int *y means that later an expression *y is an int. That implies that y must be a pointer to an int. The same holds true for function parameters, and in fact for whole function declarations:

int *foo(int **bar);

In the above int **bar says **bar is an int, implying *bar is a pointer to an int, and bar is a pointer to a pointer to an int. It also declares that *foo(arg) will be an int (given arg of the appropriate type), implying that foo(arg) results in a pointer to an int.¹ So the whole function declaration reads "foo is a function taking a pointer to a pointer to an int, and returning a pointer to an int."

C++ adds the concept of references, and messes C style declarations up a little bit in the process. Because taking the address of a variable using the address-of operator & must result in a pointer, C doesn't have any use for & in declarations; int &x would mean &x is an int, implying that x is some type where taking the address of that type results in an int.² So because this syntax is unused, C++ appropriates it for a completely different purpose.

In C++ int &x means that x is a reference to an int. Using the variable does not involve any operator to 'dereference' the reference, so it doesn't matter that the reference declarator symbol clashes with the address-of operator. The same symbol means completely different things in the two contexts, and there is never a need to use one meaning in the context where the other is allowed.

So char &foo(int &a) declares a function taking a reference to an int and returning a reference to a char. func(&x) is an expression taking the address of x and passing it to func.


1. In fact in the original C syntax for declaring functions 'declarations follow use' was even more strictly followed. For example you'd declare a function as int foo(a,b) and the types of parameters were declared elsewhere, so that the declaration would look exactly like a use, without the extra typenames.

2. Of course int *&x; could make sense in that *&x could be an int, but C doesn't actually do that.

Meaning of asterisk in these examples

_tempnam is a function.

That function takes two parameters.

The first parameter is a pointer to a char.

Any char referenced by that pointer cannot be written-to (it is const).

The second parameter is a pointer to a char.

Any char referenced by that pointer cannot be written-to (it is const).

The return value of the function is a pointer to char.

The rest of the declaration suggests that the function is a C-Runtime-Implementation (CRTIMP), called using the C-calling convention, and does not throw any exceptions.

Difference between the * and & operator in function calls

& function parameter specifically signifies that this parameter is being passed-in by reference (traditionally compilers implement this as a pointer) which is why you see the effect of this assignment in your main().
static would have nothing to do with that.

The difference in declaring a parameter to a function using & and * is that the second one allows a nullptr (or a non-existent or just a plain invalid address) to be passed-in while the & guarantees that there's a real object being referenced by this function's argument. Other than that both provide similar functionality of allowing an original object to be changed via it's reference.

Confusion about references and pointers

This:

Buf& operator=( const Buf & );

returns a reference to a Buf object, not an address of a Buf object. So when the method returns *this, the caller gets a reference to the object.

This:
Buf* operator=( const Buf * );

returns a pointer to a Buf, so the corresponding function would indeed return this.

Note that here:

Buf& b = <some code returning Buf&>;

b is a reference to Buf, not an address. On the other hand,

Buf c = ...
Buf* pBuf = &c;

&c in the code above is the address of c and can be used to initialize pBuf, which is a pointer to Buf. So the * and & can have different meanings depending on the context.

I don't understand this lesson about pointers

FunctionTwo returns a pointer to a SimpleCat object. As you can see there, it also accepts a pointer to a SimpleCat object as a parameter. It's just accepting the pointer and then returning it in this case.

To call that function, you need to pass a pointer to it. If you want to pass Frisky to the function, you need to pass the address of the object Frisky. This is what is being done when &Frisky is written. A pointer is created with the address of the Frisky object.

However, when a similar statement is written in the parameter list of a function, i.e. SomeFunction(SimpleCat& Frisky) what it is telling you is that objects are passed to the function by reference. This basically allows you to use one of the advantages of pointers without worrying about pointer syntax. You would call the function normally by saying SomeFunction(Frisky), and within the function you would use Frisky with the same syntax as you would within the main function, but you should remember that the object is not copied. Both within main and within SomeFunction, you are performing operations on the exact same object. It is not copied. Only the information required to access Frisky is given to the function.

c++ * vs & in function declaration

My rule is simple: use * when you want to show that value is optional and thus can be 0.

Excluding from the rule: all the _obj_s around are stored in containers and you don't want to make your code look ugly by using everywhere foo(*value); instead of foo(value);
So then to show that value can't be 0 put assert(value); at the function begin.

Why does c++ pointer * associate to the variable declared, not the type?

To keep compatibility with C code, because that's how C works.

Bjarne makes a good point in his style and technique faq:

The choice between int* p; and int *p; is not about right and wrong, but about style and emphasis. C emphasized expressions; declarations were often considered little more than a necessary evil. C++, on the other hand, has a heavy emphasis on types.

A typical C programmer writes int *p; and explains it *p is what is the int emphasizing syntax, and may point to the C (and C++) declaration grammar to argue for the correctness of the style. Indeed, the * binds to the name p in the grammar.

A typical C++ programmer writes int* p; and explains it p is a pointer to an int emphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.

So, the motivation for this working as this in C++ is how it works in C.

The motivation it works like that in C is that, as stated above, C emphasizes expressions rather than types.

why does the value of the function's address is 1 in C++?

Because ostream has an overload of operator<< for void* and any data pointer can be cast to void*, the addresses of ints like j are printed. However, function pointer can't be converted to void*, so this particular overload is out of way.

That's when another operator<< overload comes to play, in this case, it would be an overload for bool. The function pointer can be converted to bool (with true == pointer is non-NULL). The pointer to f is non-NULL, so it yields true in this conversion, which is printed as 1.



Related Topics



Leave a reply



Submit