Array & Pointer & function call practice and result

#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值