您的位置:首页 > 其它

Array & Pointer & function call practice and result

2016-02-02 17:00 465 查看
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

#define NOBADCALLS
#define NROWS	 3
#define NCOLUMNS 5

#define Arrayval(array, ncolumns, i, j) array[i * ncolumns + j]

int main(int, char *[]);

void f(int array[][NCOLUMNS], int nrows, int ncolumns);
void f2(int *array, int nrows, int ncolumns);
void f3(int **array, int nrows, int ncolumns);
void f4(int nrows, int ncolumns, int array[nrows][ncolumns]);

int not /* = 0 */;

int
main(int argc, char *argv[])
{
int nrows = NROWS;
int ncolumns = NCOLUMNS;
int array[NROWS][NCOLUMNS];  //一次性的分配连续空间的内存,数组名array本身如果作为函数入参会退化为int (*)[NCOLUMNS] 类型
int **array1; //分配了非连续的内存空间来存储整个数组内容
int **array2; //<span style="font-family: Arial, Helvetica, sans-serif;">分配了连续的内存空间来存储整个数组内容</span>
int *array3;
int (*array4)[NCOLUMNS];  //直接分配了连续空间
int i, j;
int *ip;

array1 = (int **)malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
array1[i] = (int *)malloc(ncolumns * sizeof(int));//注意这里,三次分配内存,导致内存空间不一致了

array2 = (int **)malloc(nrows * sizeof(int *));
array2[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
for(i = 1; i < nrows; i++)
array2[i] = array2[0] + i * ncolumns;

array3 = (int *)malloc(nrows * ncolumns * sizeof(int));

array4 = (int (*)[NCOLUMNS])malloc(nrows * sizeof(*array4));

for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncolumns; j++)
{
array[i][j] = 10 * i + j;
array1[i][j] = 100 + 10 * i + j;
array2[i][j] = 200 + 10 * i + j;
Arrayval(array3, ncolumns, i, j) = 300 + 10 * i + j;
array4[i][j] = 400 + 10 * i + j;
}
}

printf("as arrays:\n\n");

printf("array:\n");
f(array, NROWS, NCOLUMNS);

#ifndef NOBADCALLS

printf("\narray1 (shouldn't work):\n");
f((int (*)[NCOLUMNS])array1, nrows, ncolumns);	/* outright wrong cast */  //其实可以换成 <span style="font-family: Arial, Helvetica, sans-serif;">f((int (*)[NCOLUMNS])(*array1), nrows, ncolumns),其结果是能够正确打印第一行的数据,但是却无法正确定位第二行数据,原因就在于使用a[i][j]这种方法定位数据是以首地址a为起始点,然后进行i*j + j这种指针偏移,而偏偏array1的初始化数据的内存空间并不一致</span>

if(not) f(array1, nrows, ncolumns);	/* to check for compiler warnings */

#endif

printf("\narray2:\n");
f((int (*)[NCOLUMNS])(*array2), nrows, ncolumns);	/* questionable cast */
if(not) f(*array2, nrows, ncolumns);	/* to check for compiler warnings */

printf("\narray3:\n");
f((int (*)[NCOLUMNS])array3, nrows, ncolumns);	/* questionable cast */
if(not) f(array3, nrows, ncolumns);	/* to check for compiler warnings */

printf("\narray4:\n");
f(array4, nrows, ncolumns);

printf("\n\nas \"simulated\" arrays:\n\n");

printf("array:\n");
f2(&array[0][0], NROWS, NCOLUMNS);

#ifndef NOBADCALLS

printf("\narray1 (shouldn't work):\n");
f2((int *)array1, nrows, ncolumns);	/* outright wrong cast */
if(not) f2(array1, nrows, ncolumns);	/* to check for compiler warnings */
printf("\narray1 another way (also shouldn't work):\n");
f2(*array1, nrows, ncolumns);

#endif

printf("\narray2:\n");
f2(*array2, nrows, ncolumns);

printf("\narray3:\n");
f2(array3, nrows, ncolumns);

printf("\narray4:\n");
f2(*array4, nrows, ncolumns);
printf("\narray4 another way (should also work):\n");
f2((int *)array4, nrows, ncolumns);	/* questionable cast */
if(not) f2(array4, nrows, ncolumns);	/* to check for compiler warnings */

printf("\n\nas pointers:\n\n");

#ifndef NOBADCALLS

printf("array (shouldn't work):\n");
f3((int **)array, NROWS, NCOLUMNS);	/* outright wrong cast */
if(not) f3(array, NROWS, NCOLUMNS);	/* to check for compiler warnings */
printf("\narray another way (also shouldn't work):\n");
ip = &array[0][0];
f3(&ip, NROWS, NCOLUMNS);

#endif

printf("\narray1:\n");
f3(array1, nrows, ncolumns);

printf("\narray2:\n");
f3(array2, nrows, ncolumns);

#ifndef NOBADCALLS

printf("\narray3 (shouldn't work):\n");
f3((int **)array3, nrows, ncolumns);	/* outright wrong cast */
if(not) f3(array3, nrows, ncolumns);	/* to check for compiler warnings */
printf("\narray3 another way (also shouldn't work):\n");
f3(&array3, nrows, ncolumns);

printf("\narray4 (shouldn't work):\n");
f3((int **)array4, nrows, ncolumns);	/* outright wrong cast */
if(not) f3(array4, nrows, ncolumns);	/* to check for compiler warnings */
printf("\narray4 another way (also shouldn't work):\n");
f3((int **)&array4, nrows, ncolumns);	/* outright wrong cast */
if(not) f3(&array4, nrows, ncolumns);	/* to check for compiler warnings */
printf("\narray4 yet another way (also shouldn't work):\n");
ip = array4;				/* should warn */
ip = (int *)array4;			/* outright wrong cast */
f3(&ip, nrows, ncolumns);
printf("\narray4 one last way (certainly shouldn't work):\n");
ip = &array4;				/* should warn */
ip = (int *)&array4;			/* outright wrong cast */
f3(&ip, nrows, ncolumns);

#endif

printf("\n\nas variable-length arrays:\n\n");

printf("array:\n");
f4(NROWS, NCOLUMNS, array);

#ifndef NOBADCALLS

printf("\narray1 (shouldn't work):\n");
f4(nrows, ncolumns, (int (*)[NCOLUMNS])array1);	/* outright wrong cast */
if(not) f4(nrows, ncolumns, array1);	/* to check for compiler warnings */

#endif

printf("\narray2:\n");
f4(nrows, ncolumns, (int (*)[NCOLUMNS])(*array2));	/* questionable cast */
if(not) f4(nrows, ncolumns, *array2);	/* to check for compiler warnings */

printf("\narray3:\n");
f4(nrows, ncolumns, (int (*)[NCOLUMNS])array3);	/* questionable cast */
if(not) f4(nrows, ncolumns, array3);	/* to check for compiler warnings */

printf("\narray4:\n");
f4(nrows, ncolumns, array4);

return 0;
}

void
f(int array[][NCOLUMNS], int nrows, int ncolumns)
{
int i, j;

for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncolumns; j++)
{
if(j != 0)
printf("\t");
printf("%03d", array[i][j]);
}

printf("\n");
}
}

void
f2(int *array, int nrows, int ncolumns)
{
int i, j;

for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncolumns; j++)
{
if(j != 0)
printf("\t");
printf("%03d", Arrayval(array, ncolumns, i, j));
}

printf("\n");
}
}

void
f3(int **array, int nrows, int ncolumns)
{
int i, j;

for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncolumns; j++)
{
if(j != 0)
printf("\t");
printf("%03d", array[i][j]);
}

printf("\n");
}
}

void
f4(int nrows, int ncolumns, int array[nrows][ncolumns])
{
int i, j;

for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncolumns; j++)
{
if(j != 0)
printf("\t");
printf("%03d", array[i][j]);
}

printf("\n");
}
}


not define NOBADCALLS and only compile, to get all warning

make aa.o
gcc -g -c  aa.c
aa.c: In function ‘main’:
aa.c:67:2: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
if(not) f(array1, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:13:7: note: expected ‘int (*)[5]’ but argument is of type ‘int **’
void f(int array[][NCOLUMNS], int nrows, int ncolumns);
^
aa.c:73:2: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
if(not) f(*array2, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:13:7: note: expected ‘int (*)[5]’ but argument is of type ‘int *’
void f(int array[][NCOLUMNS], int nrows, int ncolumns);
^
aa.c:77:2: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
if(not) f(array3, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:13:7: note: expected ‘int (*)[5]’ but argument is of type ‘int *’
void f(int array[][NCOLUMNS], int nrows, int ncolumns);
^
aa.c:91:2: warning: passing argument 1 of ‘f2’ from incompatible pointer type [enabled by default]
if(not) f2(array1, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:14:7: note: expected ‘int *’ but argument is of type ‘int **’
void f2(int *array, int nrows, int ncolumns);
^
aa.c:107:2: warning: passing argument 1 of ‘f2’ from incompatible pointer type [enabled by default]
if(not) f2(array4, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:14:7: note: expected ‘int *’ but argument is of type ‘int (*)[5]’
void f2(int *array, int nrows, int ncolumns);
^
aa.c:115:2: warning: passing argument 1 of ‘f3’ from incompatible pointer type [enabled by default]
if(not) f3(array, NROWS, NCOLUMNS); /* to check for compiler warnings */
^
aa.c:15:7: note: expected ‘int **’ but argument is of type ‘int (*)[5]’
void f3(int **array, int nrows, int ncolumns);
^
aa.c:132:2: warning: passing argument 1 of ‘f3’ from incompatible pointer type [enabled by default]
if(not) f3(array3, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:15:7: note: expected ‘int **’ but argument is of type ‘int *’
void f3(int **array, int nrows, int ncolumns);
^
aa.c:138:2: warning: passing argument 1 of ‘f3’ from incompatible pointer type [enabled by default]
if(not) f3(array4, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:15:7: note: expected ‘int **’ but argument is of type ‘int (*)[5]’
void f3(int **array, int nrows, int ncolumns);
^
aa.c:141:2: warning: passing argument 1 of ‘f3’ from incompatible pointer type [enabled by default]
if(not) f3(&array4, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:15:7: note: expected ‘int **’ but argument is of type ‘int (**)[5]’
void f3(int **array, int nrows, int ncolumns);
^
aa.c:143:5: warning: assignment from incompatible pointer type [enabled by default]
ip = array4;    /* should warn */
^
aa.c:147:5: warning: assignment from incompatible pointer type [enabled by default]
ip = &array4;    /* should warn */
^
aa.c:162:2: warning: passing argument 3 of ‘f4’ from incompatible pointer type [enabled by default]
if(not) f4(nrows, ncolumns, array1); /* to check for compiler warnings */
^
aa.c:16:7: note: expected ‘int (*)[(sizetype)(ncolumns)]’ but argument is of type ‘int **’
void f4(int nrows, int ncolumns, int array[nrows][ncolumns]);
^
aa.c:168:2: warning: passing argument 3 of ‘f4’ from incompatible pointer type [enabled by default]
if(not) f4(nrows, ncolumns, *array2); /* to check for compiler warnings */
^
aa.c:16:7: note: expected ‘int (*)[(sizetype)(ncolumns)]’ but argument is of type ‘int *’
void f4(int nrows, int ncolumns, int array[nrows][ncolumns]);
^
aa.c:172:2: warning: passing argument 3 of ‘f4’ from incompatible pointer type [enabled by default]
if(not) f4(nrows, ncolumns, array3); /* to check for compiler warnings */
^
aa.c:16:7: note: expected ‘int (*)[(sizetype)(ncolumns)]’ but argument is of type ‘int *’
void f4(int nrows, int ncolumns, int array[nrows][ncolumns]);


define NOBADCALLS and start run (otherwise you will face crash)

make
gcc -g -c  aa.c
aa.c: In function ‘main’:
aa.c:73:2: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
if(not) f(*array2, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:13:7: note: expected ‘int (*)[5]’ but argument is of type ‘int *’
void f(int array[][NCOLUMNS], int nrows, int ncolumns);
^
aa.c:77:2: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
if(not) f(array3, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:13:7: note: expected ‘int (*)[5]’ but argument is of type ‘int *’
void f(int array[][NCOLUMNS], int nrows, int ncolumns);
^
aa.c:107:2: warning: passing argument 1 of ‘f2’ from incompatible pointer type [enabled by default]
if(not) f2(array4, nrows, ncolumns); /* to check for compiler warnings */
^
aa.c:14:7: note: expected ‘int *’ but argument is of type ‘int (*)[5]’
void f2(int *array, int nrows, int ncolumns);
^
aa.c:168:2: warning: passing argument 3 of ‘f4’ from incompatible pointer type [enabled by default]
if(not) f4(nrows, ncolumns, *array2); /* to check for compiler warnings */
^
aa.c:16:7: note: expected ‘int (*)[(sizetype)(ncolumns)]’ but argument is of type ‘int *’
void f4(int nrows, int ncolumns, int array[nrows][ncolumns]);
^
aa.c:172:2: warning: passing argument 3 of ‘f4’ from incompatible pointer type [enabled by default]
if(not) f4(nrows, ncolumns, array3); /* to check for compiler warnings */
^
aa.c:16:7: note: expected ‘int (*)[(sizetype)(ncolumns)]’ but argument is of type ‘int *’
void f4(int nrows, int ncolumns, int array[nrows][ncolumns]);
^
gcc -g -o  aa aa.o
./aa
as arrays:

array:
000	001	002	003	004
010	011	012	013	014
020	021	022	023	024

array2:
200	201	202	203	204
210	211	212	213	214
220	221	222	223	224

array3:
300	301	302	303	304
310	311	312	313	314
320	321	322	323	324

array4:
400	401	402	403	404
410	411	412	413	414
420	421	422	423	424

as "simulated" arrays:

array:
000	001	002	003	004
010	011	012	013	014
020	021	022	023	024

array2:
200	201	202	203	204
210	211	212	213	214
220	221	222	223	224

array3:
300	301	302	303	304
310	311	312	313	314
320	321	322	323	324

array4:
400	401	402	403	404
410	411	412	413	414
420	421	422	423	424

array4 another way (should also work):
400	401	402	403	404
410	411	412	413	414
420	421	422	423	424

as pointers:

array1:
100	101	102	103	104
110	111	112	113	114
120	121	122	123	124

array2:
200	201	202	203	204
210	211	212	213	214
220	221	222	223	224

as variable-length arrays:

array:
000	001	002	003	004
010	011	012	013	014
020	021	022	023	024

array2:
200	201	202	203	204
210	211	212	213	214
220	221	222	223	224

array3:
300	301	302	303	304
310	311	312	313	314
320	321	322	323	324

array4:
400	401	402	403	404
410	411	412	413	414
420	421	422	423	424
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: