Lies in education [was Re: The "loop and a half"]
Thomas Jollans
tjol at tjol.eu
Thu Oct 12 10:12:59 EDT 2017
On 2017-10-12 15:16, Ben Bacarisse wrote:
> Gregory Ewing <greg.ewing at canterbury.ac.nz> writes:
>
>> Ben Bacarisse wrote:
>>> That's a different type. I think you mean that a human writing C
>>> (rather than bartc's code generator) would probably design the code to
>>> use tokenrec ** then I agree, but the latter is not just a different way
>>> to write the former.
>>
>> Yes, I was translating his English description of the type
>> into C, using C's meaning of the word "array". It seems that
>> arrays in the original language (Algol? One of Bart's
>> inventions?) are somewhat richer things.
>
> Probably, but you can have pointers to array types in C which is what
> the posted type used. Humans pass arrays in C by passing a pointer to
> the first element. Pointers to arrays therefore crop up when passing 2D
> (or higher) arrays, even when the code is hand written by a person.
>
No, actually. Multi-dimensional arrays in C are not arrays of arrays.
They look very similar, but when the dimensions of the array are known
at compile time, arrays of any rank are a continuous region of memory
with the data, and a pointer to the start.
Casting int[3][3] to int** will not do what you want it to do.
If, say, you have variables of the types:
int a[M][N], **b;
then a[i][j] is equivalent to *(a+(i*M)+j), while b[i][j] is equivalent
to *(*(b+i)+j).
Observe:
---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv)
{
int i,j;
/* multi-dimensional array: the compiler knows the dimensions! */
short multi_array[3][3] = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};
short *array_array[3];
/* fill array_array elements of multi_array */
for(i=0; i<3; ++i) {
array_array[i] = calloc(3, sizeof(short));
/* This works because C arrays are row-major */
memcpy(array_array[i], &multi_array[i][0], 3*sizeof(short));
}
/* print out the arrays */
puts("multi_array:");
for (i=0; i<3; ++i) {
for (j=0; j<3; ++j) {
printf("%d ", multi_array[i][j]);
}
puts("");
}
puts("array_array:");
for (i=0; i<3; ++i) {
for (j=0; j<3; ++j) {
printf("%d ", array_array[i][j]);
}
puts("");
}
printf("&multi_array = 0x%llX\n", (long long)&multi_array);
printf("*multi_array = 0x%llX\n", (long long)(*(short**)multi_array));
printf("&array_array = 0x%llX\n", (long long)&array_array);
printf("*array_array = 0x%llX\n", (long long)(*(short**)array_array));
/* clean up */
for (i=0; i<3; ++i) {
free(array_array[i]);
}
return 0;
}
---------------------------------------------------------------------------
[OUTPUT]
multi_array:
1 0 0
0 1 0
0 0 1
array_array:
1 0 0
0 1 0
0 0 1
&multi_array = 0x7FFE0E736470
*multi_array = 0x1
&array_array = 0x7FFE0E736450
*array_array = 0x1A42010
More information about the Python-list
mailing list