Since the definition x0 = 1 is based upon division, and division by 0 is not possible, we have stated that x is not equal to 0. Actually, the expression 00 (0 to the zero power) is one of several indeterminate expressions in mathematics. It is not possible to assign a value to an indeterminate expression.
Well, any number raised to the power of zero does equal 1 because the base, or the number being raised to any power, gets divided by itself. For example, 30 equals 3/3, which equals 1, but 00 "equals" 0/0, which equals any number, which is why it's indeterminate.
In mathematics, expressions like 1/0 are undefined. But the limit of the expression 1/x as x tends to zero is infinity. Similarly, expressions like 0/0 are undefined.
Meaning of X = X[:, 1] in Python is: X is a dataset or a array. Say Here X have n rows and n columns. so by doing x=x[:,1] we get all the rows in x present at index 1.
x
is a pointer to an array of 5 pointers to int
.x[0]
is an array of 5 pointers to int
.x[0][0]
is a pointer to an int
.x[0][0][0]
is an int
.
x[0]
Pointer to array +------+ x[0][0][0]
x -----------------> | | Pointer to int +-------+
0x500 | 0x100| x[0][0]----------------> 0x100 | 10 |
x is a pointer to | | +-------+
an array of 5 +------+
pointers to int | | Pointer to int
0x504 | 0x222| x[0][1]----------------> 0x222
| |
+------+
| | Pointer to int
0x508 | 0x001| x[0][2]----------------> 0x001
| |
+------+
| | Pointer to int
0x50C | 0x123| x[0][3]----------------> 0x123
| |
+------+
| | Pointer to int
0x510 | 0x000| x[0][4]----------------> 0x000
| |
+------+
You can see that
x[0]
is an array and will converted to pointer to its first element when used in an expression (with some exceptions). Therefore x[0]
will give the address of its first element x[0][0]
which is 0x500
. x[0][0]
contains address of an int
which is 0x100
. x[0][0][0]
contains an int
value of 10
. So, x[0]
is equal to &x[0][0]
and therefore, &x[0][0] != x[0][0]
.
Hence, x[0] != x[0][0] != x[0][0][0]
.
x[0] != x[0][0] != x[0][0][0]
is, according to your own post,
*(x+0) != *(*(x+0)+0) != *(*(*(x+0)+0)+0)`
which is simplified
*x != **x != ***x
Why should it be equal?
The first one is the address of some pointer.
The second one is the address of another pointer.
And the third one is some int
value.
Here is the memory layout of your pointer:
+------------------+
x: | address of array |
+------------------+
|
V
+-----------+-----------+-----------+-----------+-----------+
| pointer 0 | pointer 1 | pointer 2 | pointer 3 | pointer 4 |
+-----------+-----------+-----------+-----------+-----------+
|
V
+--------------+
| some integer |
+--------------+
x[0]
yields "address of array",x[0][0]
yields "pointer 0",x[0][0][0]
yields "some integer".
I believe, it should be obvious now, why they are all different.
The above is close enough for basic understanding, which is why I wrote it the way I wrote it. However, as haccks rightly points out, the first line is not 100% precise. So here come all the fine details:
From the definition of the C language, the value of x[0]
is the whole array of integer pointers. However, arrays are something you can't really do anything with in C. You always manipulate either their address or their elements, never the entire array as a whole:
You can pass x[0]
to the sizeof
operator. But that's not really a use of the value, its result depends of the type only.
You can take its address which yields the value of x
, i. e. "address of array" with the type int*(*)[5]
. In other words: &x[0] <=> &*(x + 0) <=> (x + 0) <=> x
In all other contexts, the value of x[0]
will decay into a pointer to the first element in the array. That is, a pointer with the value "address of array" and the type int**
. The effect is the same as if you had casted x
to a pointer of type int**
.
Due to the array-pointer decay in case 3., all uses of x[0]
ultimately result in a pointer that points the beginning of the pointer array; the call printf("%p", x[0])
will print the contents of the memory cells labeled as "address of array".
x[0]
dereferences the outermost pointer (pointer to array of size 5 of pointer to int) and results in an array of size 5 of pointer to int
;x[0][0]
dereferences the outermost pointer and indexes the array, resulting in a pointer to int
;x[0][0][0]
dereferences everything, resulting in a concrete value.By the way, if you ever feel confused by what these kind of declarations mean, use cdecl.
Let consider step by step expressions x[0]
, x[0][0]
and x[0][0][0]
.
As x
is defined the following way
int *(*x)[5];
then expression x[0]
is an array of type int *[5]
. Take into account that expression x[0]
is equivalent to expression *x
. That is dereferencing a pointer to an array we get the array itself. Let denote it like y that is we have a declaration
int * y[5];
Expression x[0][0]
is equivalent to y[0]
and has type int *
. Let denote it like z that is we have a declaration
int *z;
expression x[0][0][0]
is equivalent to expression y[0][0]
that in turn is equivalent to expression z[0]
and has type int
.
So we have
x[0]
has type int *[5]
x[0][0]
has type int *
x[0][0][0]
has type int
So they are objects of different types and by the way of different sizes.
Run for example
std::cout << sizeof( x[0] ) << std::endl;
std::cout << sizeof( x[0][0] ) << std::endl;
std::cout << sizeof( x[0][0][0] ) << std::endl;
First thing I have to say that
x [ 0 ] = * ( x + 0 ) = * x ;
x [ 0 ] [ 0 ] = * ( * ( x + 0 ) + 0 ) = * * x ;
x [ 0 ] [ 0 ] [ 0 ] = * ( * ( * ( x + 0 ) + 0 ) ) = * * * x ;
So * x ≠ * * x ≠ * * * x
From the following picture all things are clear.
x[0][0][0]= 2000
x[0][0] = 1001
x[0] = 10
It is just an example, where value of x[0][0][0]=10
and address of x[0][0][0] is 1001
that address is stored in x[0][0]=1001
and address of x[0][0] is 2000
and that address is stored at x[0]=2000
So x[0][0][0] ≠ x[0][0] ≠ x[0]
.
EDITINGS
Program 1:
{
int ***x;
x=(int***)malloc(sizeof(int***));
*x=(int**)malloc(sizeof(int**));
**x=(int*)malloc(sizeof(int*));
***x=10;
printf("%d %d %d %d\n",x,*x,**x,***x);
printf("%d %d %d %d %d",x[0][0][0],x[0][0],x[0],x,&x);
}
Output
142041096 142041112 142041128 10
10 142041128 142041112 142041096 -1076392836
Program 2:
{
int x[1][1][1]={10};
printf("%d %d %d %d \n ",x[0][0][0],x[0][0],x[0],&x);
}
Output
10 -1074058436 -1074058436 -1074058436
If you were to view the arrays from a real-world perspective, it would appear as thus:
x[0]
is a freight container full of crates.x[0][0]
is a single crate, full of shoeboxes, within the freight container.x[0][0][0]
is a single shoebox inside the crate, inside the freight container.
Even if it were the only shoebox in the only crate in the freight container, it is still a shoebox and not a freight container
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With