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
相关文章推荐
- 基于TWL6032 PWM控制液晶背光亮度
- 如何开发Linux内核?
- 仿知乎安卓client滑动删除撤销ListView
- Python【基础第三篇】
- zTree设置选中节点之后出现重复节点
- HDU2050(分平面问题)
- Quartz1.8.5例子(十四)
- uva 10891
- SDL2源代码分析1:初始化(SDL_Init())
- Swift 特殊关键字 与符号
- git warning: LF will be replaced by CRLF in 解决办法
- python 将字符串转化成16进制进行UDP的发送
- 面向对象程序设计 ——第二次作业(2)
- MVC 自定义错误处理
- PHPCMS V9 QQ登录无法正常登录解决方案
- linux shell 编程6 函数获取参数
- Xcode 工程文件“.xcodeproj”文件夹解析
- Ubuntu下软件的相关操作
- 二维码
- 【Elasticsearch】打分策略详解与explain手把手计算