Array & Pointer & function call practice and result

来源:互联网 发布:淘宝如何在团购网引流 编辑:程序博客网 时间:2024/06/07 18:54
#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 */;intmain(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 NOBADCALLSprintf("\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 */#endifprintf("\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 NOBADCALLSprintf("\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);#endifprintf("\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 NOBADCALLSprintf("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);#endifprintf("\narray1:\n");f3(array1, nrows, ncolumns);printf("\narray2:\n");f3(array2, nrows, ncolumns);#ifndef NOBADCALLSprintf("\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);#endifprintf("\n\nas variable-length arrays:\n\n");printf("array:\n");f4(NROWS, NCOLUMNS, array);#ifndef NOBADCALLSprintf("\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 */#endifprintf("\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;}voidf(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");}}voidf2(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");}}voidf3(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");}}voidf4(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.ogcc -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)

makegcc -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:000001002003004010011012013014020021022023024array2:200201202203204210211212213214220221222223224array3:300301302303304310311312313314320321322323324array4:400401402403404410411412413414420421422423424as "simulated" arrays:array:000001002003004010011012013014020021022023024array2:200201202203204210211212213214220221222223224array3:300301302303304310311312313314320321322323324array4:400401402403404410411412413414420421422423424array4 another way (should also work):400401402403404410411412413414420421422423424as pointers:array1:100101102103104110111112113114120121122123124array2:200201202203204210211212213214220221222223224as variable-length arrays:array:000001002003004010011012013014020021022023024array2:200201202203204210211212213214220221222223224array3:300301302303304310311312313314320321322323324array4:400401402403404410411412413414420421422423424

0 0
原创粉丝点击