What Is the Purpose of a Declaration Like Int (X); or Int (X) = 10;

What is the purpose of a declaration like int (x); or int (x) = 10;

The fact that this rule is applicable in your case is not deliberate: It's ultimately a result of keeping the grammar simple. There is no incentive to prohibit declarations such as yours, but there are great disincentives to complicate rules, especially if those are intricate as they are.

In short, if you don't want to use this needlessly obfuscated syntax, don't.

C++ rarely forces you to write readable code.

Surprisingly there are scenarios in which parentheses can save the day, though:

std::string foo();

namespace detail
{
int foo(long); // Another foo

struct Bar
{
friend std::string ::foo(); // Doesn't compile for obvious reasons.

friend std::string (::foo)(); // Voilà!
};
}

Difference between int *x[10] and int (*x)[10]

Type *x[10];

defines x as an array of 10 pointers to Type. So x itself is an array that contains pointers to Type. On the other hand,

Type (*x)[10];

defines x as a pointer to array-10 of Type. Hence x points to the befinning of an array of size 10, and the array contains objects of type Type. See this for a great introduction to how to read complicated declarations in C, and also try cdecl.org.

Why can't I set a value of a pointer int *x to, say, 10?

Your confusion has to do with the difference between an initialization and an assignment. These are examples of initialization:

int a = 5;    // valid; "a" is an int which is initialized with the value 5
int *b = &a; // valid; "b" is an int * which is initialized with the address of "a"
int *c = 10; // invalid; "c" is an int * which is initialized with the value 10

While these are assignments:

a = 5;    // valid; "a" is assigned the value 5
b = &a; // valid; "b" is assigned the address of "a"
*b = 10; // valid; "b" points to "a", and the value "b" points to is set to 10

Note that the use of * differs between the two. In an initalization * means that the given variable is a pointer, while * in an assignment (or any expression) means that the pointer is dereferenced.

Using newly declared variable in initialization (int x = x+1)?

With the expression:

int x = x + 1;

the variable x comes into existence at the = sign, which is why you can use it on the right hand side. By "comes into existence", I mean the variable exists but has yet to be assigned a value by the initialiser part.

However, unless you're initialising a variable with static storage duration (e.g., outside of a function), it's undefined behaviour since the x that comes into existence has an arbitrary value.

C++03 has this to say:

The point of declaration for a name is immediately after its complete declarator (clause 8) and before its initializer (if any) ...

Example:

int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value.

That second case there is pretty much what you have in your question.

Can anyone help me to understand typedef in this program?

You are confusing typedef with #define. The preprocessor #define is the one that does simply text replacing.

typedef, on the other hand, is not part of preprocessor, but syntactically like keyword extern, static, etc. It gives a certain type a new name.

typedef int RowArray[COLS]; 

RowArray defines a type of an int array with COLS elements. So

RowArray *rptr; 

rptr is a pointer to an int array with COLS elements.

I need help understanding the proper usage of pointer to array of n integers initialization

For starters according to the C Standard the function main without parameters shall be decalred like

int main( void )

In the shown program you declared an uninitialized pointer

int (*x)[12], i;

that has an indeterminate value. So dereferencing the pointer

(*x)[i] = i;

results in undefined behavior.

Instead you could write for example

#include <stdio.h>

int main( void )
{
enum { N = 12 };
int a[N];

int (*x)[N] = &a;

for ( size_t i = 0; i < N; i++ )
{
(*x)[i] = i;
printf( "%d\n", (*x)[i] );
}
}

Though the program will look simpler if to write it like

#include <stdio.h>

int main( void )
{
enum { N = 12 };
int a[N];

int *x = a;

for ( size_t i = 0; i < N; i++ )
{
x[i] = i;
printf( "%d\n", x[i] );
}
}

In this declaration

int *x = a;

is implicitly converted to a pointer to its first element of the type int *.

In this declaration

int (*x)[N] = &a;

the initializing expression &a is already a pointer of the type int ( * )[N].

So in the expression

(*x)[i] = i;

the subexpression *x yields lvalue of the array a. So in fact the above expression is equivalent to

a[i] = i;

Pay attention to that in the both declarations

int *x = a;

and

int ( *x )[N] = &a;

the pointers x store the starting address of the memory extent occupied by the array a but have different types. Dereferencing the first pointer you will get the first element of the array a. Dereferencing the second pointer you will get the whole array itself.



Related Topics



Leave a reply



Submit