⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aryptr.c

📁 this is a mirrored site c-faq. thought might need offline
💻 C
字号:
/* *  This code is a "working" version of questions 6.16, 6.18, *  6.19, and 6.20 in the comp.lang.c frequently-asked questions *  (FAQ) list. * *  This code attempts to answer the question "How can I write a *  function which accepts multidimensional arrays of arbitrary *  size, both statically and dynamically allocated?".  As it *  happens, the C language does not provide a good answer to *  this question. * *  This code serves as two different kinds of "torture test." * *  First of all, it is a good test of your understanding of *  arrays and pointers in C.  The code declares five kinds of *  multidimensional arrays, and three or four functions which *  accept various forms of multidimensional arrays, but they *  are not all compatible with each other.  Why do the ones *  which are compatible work (and why are the calls written *  as they are), and why are some incompatible? * *  Secondly, this code is a good test for certain parts of a C *  compiler or lint implementation.  Several of the assignments *  and calls (those marked "should warn" or "to check for *  compiler warnings") are definitely, and deliberately, *  incorrect, and should elicit warning (or error) messages from *  a quality compiler or lint implementation.  (Unless I've *  overlooked something, the only serious messages elicited by *  this code should be 2 about bad pointer assignments, and 9 *  about function argument type mismatches.  Other warnings might *  have to do with arguments not used, or constants in conditional *  contexts, or switches with no case labels, or the signal *  function(s), or other problems with your system's header files.) * *  It is instructive to compare the source code of the functions *  f() and f2(), and particularly f() and f3(). * *  Several of the function calls in this program (those marked *  "shouldn't work", and particularly those to f3()) are almost *  certain to result in Segmentation Violations or Bus Errors. *  The code tries to catch these signals when they occur, printing *  a message and attempting to continue, but depending on where the *  processor leaves the PC after a trap, it can go into quite a *  loop.  Don't run this code in an environment where you won't *  be able to abort it right away with control-C or the like. *  (If necessary, you may want to comment out or otherwise *  disable the troublesome calls.  You can knock them out all at *  once by #defining NOBADCALLS, but that will also mask most of *  the warnings and errors that your compiler ought to report.) * *  The calls that work should all print lines of the form * *	x00	x01	x02	x03	x04 *	x10	x11	x12	x13	x14 *	x20	x21	x22	x23	x24 * *  , where x is 0, 1, 2, 3, or 4, depending on which "array" is *  being printed. * *  This code is in the Public Domain (I wouldn't dream of *  copyrighting something like this!). * *  Steve Summit 5/7/93 (updated 12/2/2001) */#include <stdio.h>#include <stdlib.h>#include <signal.h>#define NROWS	 3#define NCOLUMNS 5#define Arrayval(array, ncolumns, i, j) array[i * ncolumns + j]int main(int, char *[]);void bombsaway(int);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);#ifdef C99void f4(int nrows, int ncolumns, int array[nrows][ncolumns]);#endifint not /* = 0 */;/* ARGSUSED */intmain(int argc, char *argv[]){int nrows = NROWS;int ncolumns = NCOLUMNS;int array[NROWS][NCOLUMNS];int **array1;int **array2;int *array3;int (*array4)[NCOLUMNS];int i, j;int *ip;#ifdef SIGBUSsignal(SIGBUS, bombsaway);#endif#ifdef SIGSEGVsignal(SIGSEGV, bombsaway);#endifarray1 = (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 */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);#endif#ifdef C99printf("\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);#endifreturn 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");	}}#ifdef C99voidf4(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");	}}#endif/* ARGSUSED */voidbombsaway(int sig){switch(sig)	{#ifdef SIGBUS	case SIGBUS:		printf("Bus Error\n");		break;#endif#ifdef SIGSEGV	case SIGSEGV:		printf("Segmentation Violation\n");		break;#endif	default:		printf("Signal %d\n", sig);		break;	}signal(sig, bombsaway);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -