int *p = 25; 

It causes an int <<>> int * conversion error, although the * operator is for value-by-address.

 int a,b,c,d,*p,x,y,z; *p=25; 

Works fine, the value at pointer 25, and the variable is declared together with other integers. Why exactly? Suppose so, then int and int * are different data types and should not be specified as a single line, but this works in the example with int a,b,c,d,*p,x,y,z; , the other variables function as they should, not as pointers. And if, for example, to write int* a, b, c; , then the pointer will only be a . And why does the following code not work?

 int *p; p=&25; 
  • The second example writes 25 to an unspecified address (possibly zero, but did not exactly check), because you did not specify any address in *p . This is an undefined behavior that the compiler actually swears at very strongly. This example does not work for me, but falls with a segmentation error - andreymal
  • one
    in the variable declaration string * means that you create a pointer to this type. In all other lines (which are not declarations) * means taking values ​​at the address. As for & 25, this is impossible because the constants are not stored in memory, but directly in the code. And since the constant is not in the memory, then it cannot have an address - Mike
  • p = & int (25) (here I mean it is not such an assignment, but that the pointer is assigned the address of the object), it will work, because the compiler knows how much memory to allocate. Initialization is memory allocation, and how to explain & 25 to the copiler: what is it? After all, many types can be initialized with an integer number .. - AR Hovsepyan
  • The author, saying "не работает" , specify, either does not compile (and give a message to the compiler (as well as what exactly you are compiling)), or when you run for execution (OS also indicate) what you expected to see, and what you directly observe. - avp

3 answers 3

 int *p = 25; 

It causes an int <<>> int * conversion error, although the * operator is for value-by-address.

This sentence does not use a dereference operator * .

This offer is an ad pointer. Compare for example the following ad.

 int a[1] = { 25 }; 

Here, similarly, the indexing operator [], not used [], and the array declaration takes place.

That is, the same tokens have different meanings depending on the context.

The compiler displays an error message in this declaration.

 int *p = 25; 

since there is no implicit conversion of an integer literal 25 of type int to the type of the value of the pointer int * .

As for this ad

 int a,b,c,d,*p,x,y,z; 

then it can be rewritten as

 int ( a ), ( b ), ( c ), ( d ), ( *p ), ( x ), ( y ), ( z ); 

which in this particular case is equivalent to a series of ads

 int ( a ); int ( b ); int ( c ); int ( d ); int ( *p ); int ( x ); int ( y ); int ( z ); 

which is naturally easier to write as

 int a; int b; int c; int d; int *p; int x; int y; int z; 

In general, a simple declaration (in terms of the C ++ standard simple-declaration ) looks as follows:

 decl-specifier-seq init-declarator-list; 

That is, a sequence of declaration specifiers (int, long, bool, etc.) and a sequence of declarators (declared variables).

For example, in a single declaration-declaration you can declare, for example, an object of type int , a pointer of type int * , an array with elements of type int and a function (or pointer to a function) having the type of return value int or even int *

View the following demo.

 #include <iostream> int f() { return 10; } int * g() { static int x = 20; return &x; } int main() { int x, *p, a[1], f(), *g(), ( *pf )() = f, *( *pg )() = g; p = &x; x = 1; std::cout << "x = " << x << '\n'; ++*p; std::cout << "*p = " << *p << '\n'; a[0] = x + 1; std::cout << "a[0] = " << a[0] << '\n'; std::cout << "f() = " << f() << '\n'; std::cout << "*g() = " << *g() << '\n'; std::cout << "pf() = " << pf() << '\n'; std::cout << "*pg() = " << *pg() << '\n'; return 0; } 

Its output to the console:

 x = 1 *p = 2 a[0] = 3 f() = 10 *g() = 20 pf() = 10 *pg() = 20 

Regarding this code snippet from your question

 int a,b,c,d,*p,x,y,z; *p=25; 

then in the first sentence-declaration a pointer is declared with the name p, which is not initialized, provided that this variable has an automatic memory duration (local variable), and therefore has an undefined value, or is initialized with a constant null pointer, if the variable has a static memory duration ( declared outside the function).

The second sentence is an expression sentence. It uses a pointer dereference operator * and an assignment operator.

Since the value of the pointer is either undefined or nullptr , this nullptr leads to undefined program behavior.

As for this proposal

 int *p; p=&25; 

then there is an attempt to take the address of an integer literal, rather than an object in memory. Therefore, the compiler generates an error message.

  • int *p; p=&25; ... "Therefore, the compiler generates an error message." - not a mistake, but a warning. It does not work correctly, but it compiles and does not produce an error with type conversion. In another answer, we have already found out that the standard was invented so that it misleads the similarity of writing, but different functionality. "Here, similarly, the indexing operator [] is not used, but the array declaration takes place." - I agree, there is also a logical error, “but such a standard” (c) - Gleb
  • @ Gleb The & operator requires lvalue, and integer literals are not lvalue. - Vlad from Moscow
  • Indeed, I initially checked with *p=25; This caused a warning, compiled, but did not work correctly. `p = & 25 'is not compiled, rechecked. - Gleb

Your basic mistake is the belief that

 int *p = 25; 

there is a "operator *" and "assignment".

In fact, there is no "operator *" and "assignment" in this syntax. The symbol * and the symbol = in this case are only elements of the syntax of the pointer declaration and initialization syntax, having nothing to do with either the "operator *" or the "assignment". No need to try to draw parallels between the * and = characters in declarations and the * and = operators in expressions - these are completely different things that are not related to each other.

In this ad

 int *p = 25; 

p declared as a pointer to an int and an attempt is made to initialize this pointer to the value 25 . This is not allowed. In C ++, there is no implicit conversion of the value of the type int to the type int * .

But in this case

 int *p; *p=25; 

your *p=25 is no longer an ad, but an expression in which you already use the * operator and the = operator. The semantic meaning is completely different.


Why from your " int and int* different data types" (which is true) you concluded that they "should not be specified as a single line" is not clear. C and C ++ allow you to declare such variables in one line. Yes, that's right, in int* a, b, c; then the pointer will be just a . A C ++ declaration consists of a common part of decl-specifier-seq and individual declarator

 decl-specifier-seq declarator, declarator, ...; 

In your example, int is decl-specifier-seq , and * a , b and c are individual declarators.


Your question about "why not work"

 int *p; p=&25; 

not clear. First, explain where the question came from. Why should he suddenly "work"? Pointers in C + point to entities located in memory, i.e. on lvalues. 25 is a literal, just some ephemeral, meaning floating in the air. It has no position in memory and it is impossible to apply the address-taking operator & .

  • I did not ask почему не работает? , my question is why from the side of logic the record looks erroneous and misleading. Why not use another way to initialize the pointer immediately in the ad string? If the existing one is misleading, since the entry *p=&b when declaring, assigns a pointer to b to p, but not declaring the same entry will make the value of pointer p equal to address b. - Gleb
  • one
    @Gleb: Denis Ritchie once said that this syntax was chosen so that the syntax of the declaration was similar to the syntax of use . Without a doubt, it was a crazy idea. The syntaxes are similar, but they do completely different things and raise such questions. You just need to remember this. - AnT
  • This is the answer to the question. And someone for such a standard on the hands of the need to give. You could choose a completely different way to initialize the declaration. 2 years the question tormented, in the hell is done that way. - Gleb
  • @AnT, not at all crazy. It allows you to recognize professionally unsuitable at an early stage - avp
  • @Gleb: In the "rudimentary" language C, a different initialization syntax was actually used: without = in general, i.e. they wrote simply int i 42; . But already in K & R, it was decided to add all the same there = . - AnT
 int *p = 25; 

A pointer to an int with the name p declared. Attempting to assign an integer value to a pointer violates the rules for working with C ++ types.

 int a,b,c,d,*p,x,y,z; *p=25; 

Among the variables of type int a pointer to an int with the name p declared. An assignment is made to a variable (place in memory) with the type int , pointed to by p , to a variable of type int - without a type violation, only the value in the variable p unknown, so where exactly 25 is written is unknown. So the behavior of the program is undefined ...

 int* a, b, c 

* refers to a variable name, not a type. It is necessary to read how

 int (*a), b, c 

Here

 int *p; p=&25; 

You are trying to take an address from a number, not a variable. 25 does not have a certain place in the memory associated with it, and getting its address is at least a meaningless operation ...

  • The question is precisely why? int a = 20; - works, int a = 20; int *p = a; int a = 20; int *p = a; - does not work, int a = 20; int *p = &a; int a = 20; int *p = &a; -- works. But at the same time, int a=20; int *p; *p=&a; int a=20; int *p; *p=&a; - will not work correctly, but correctly int a=20; int *p; p=&a; int a=20; int *p; p=&a; . In one case *p= &а , in another case p=&a will be correct. But if we take this into account and begin to designate variables differently, the string int * a, b, c; would have to create 3 pointers. - Gleb
  • @ Gleb int *p is a declaration of a new pointer (and it doesn’t matter whether there is = or not), int *p = чтототам is the announcement of a int *p = чтототам with a pre-written address, p = чтототам write the new address into the pointer, *p = чтототам at the address in the pointer without changing the pointer itself (not to be confused with int *p = чтототам , these are completely different things) - andreymal
  • Well read the tutorial carefully, eh? Why this standard is made is no longer us :) Why I’ve explained your code in this way - according to the rules of the language - I explained. The rules of the language may seem illogical to you, but the compilers will still follow them, not your wishes, however reasonable they might be compared to the proposals of these fools from the standardization committee ... - Harry