主題: 玩玩 c 指標
瀏覽單個文章
Adsmt
Golden Member
 
Adsmt的大頭照
 

加入日期: Feb 2004
您的住址: 從來處來
文章: 2,762
玩玩 c 指標

這沒什麼特別意義,純粹好玩而已,以前我故意弄一些很複雜的指標,試試能不能編譯。

後來想說能不能用這些莫名奇妙的指標寫出程式,結果發現可以的。

最近拿出重看,再小改一下....

其實我也覺得很訝異,這樣也能寫出程式。

代碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* func1 is a function which returns a pointer to a function, whose parameter type is char and returning type is void. */
void (*func1(int))(char);
void (*(*func11)(int))(char); // func11 is a pointer to a func1-typed function.

/* func2 is an array of 3 elements, which contents are pointers to functions whose parameter type is int and returning type is void. */
void (*func2[3])(int);

/* Combine func1 and func2. */
void (*(*func3[3])(int))(char);

/* func4 is a pointer to a function which takes int as argument and returns a pointer to an array of 3 elements, which are pointers to char values. */
char *(*(*func4)(int))[3];
char (*func41(int))[30];
char (*(*func42)(int))[30];
char *(*func43(int))[3];

/* %$#^%@........ */
char *(*(*func5)(char *(*(*func6)(int))[3]))(void (*(*func7)[3])(int));
void (*(*func71)[3])(int);

void func1_1(char c)
{
	printf("You input letter '%c'.\n", c);
}

void func1_2(char c)
{
	printf("You input letter '%c', and its next letter is '%c'.\n", c, c+1);
}

void (*func1(int v))(char c)
{
	if(v % 2)
		return func1_1;
	else
		return func1_2;
}

void func2_1(int i)
{
	printf("You got an integer '%d'.\n", i);
}

void func2_2(int i)
{
	int randnum = rand() % 10 + 1;

	printf("Your integer multiplied by %d is: '%d'.\n", randnum, i*randnum);
}

void func2_3(int i)
{
	printf("Your integer is an %s number.\n", i&1? "odd": "even");
}

void (*func3_1(int v))(char c)
{
	printf("You've entered func3_1: ");
	if(v % 2)
		return func1_1;
	else
		return func1_2;
}

void (*func3_2(int v))(char c)
{
	printf("You've entered func3_2: ");
	if(v > 50)
		return func1_1;
	else
		return func1_2;
}

void (*func3_3(int v))(char c)
{
	printf("You've entered func3_3: ");
	if(v % 3)
		return func1_1;
	else
		return func1_2;
}

char (*func41(int s))[30]
{
	int i;
	char (*strs)[30];

	strs = (char (*)[])malloc(sizeof(char) * s * 30);

	for( i = 0; i < s; i++ )
		sprintf(strs[i], "This is string %d.\n", i);

	return strs;
}

char *(*func43(int s))[3]
{
	int i, j;
	char *(*strs)[3];
	char tmpstr[30];

	strs = (char *(*)[])malloc(sizeof(char *) * s * 3);

	for( i = 0; i < s; i++ )
	{
		for( j = 0; j < 3; j++ )
		{
			sprintf(tmpstr, "You got string %d, %d.\n", i, j);
			strs[i][j] = strdup(tmpstr);
		}
	}

	return strs;
}

char *func5_2(void (*(*func7)[3])(int))
{
	int i, ri;

	printf("Here is %s():\n", __func__);

	ri = rand() % 100 + 1;
	for( i = 0; i < 3; i++)
		(*func7)[i](ri);

	return "\nAt the end of this day, one shall stand, one shall fall!\n";
}

char *(*func5_1(char *(*(*func6)(int))[3]))(void (*(*func7)[3])(int))
{
	int i, j;
	char *(*tstrp)[3];

	tstrp = func6(2);

	for( i = 0; i < 2; i++)
	{
		for( j = 0; j < 3; j++)
		{
			printf("func6: %s", tstrp[i][j]);
			free(tstrp[i][j]);
		}
	}

	free(tstrp);

	return func5_2;
}

int main(int argc, char *argv[])
{
	int i, j, ri;
	void (*pfunc)(char);

	// Test of func1 and func11
	printf("Test func1 and func11:\n");

	func11 = func1;
	pfunc = func1(1);
	pfunc('A');
	pfunc = func11(2);  // Since func11 is a pointer to a function, (*func11)(2) is the correct format, but simplified form func11(2) is also valid.
	pfunc('A');

	/* Results:
		Test func1 and func11:
		You input letter 'A'.
		You input letter 'A', and its next letter is 'B'.
	*/

	// Test of func2
	printf("\nTest func2:\n");

	func2[0] = func2_1;
	func2[1] = func2_2;
	func2[2] = func2_3;

	srand(time(NULL));
	ri = rand() % 100 + 1;

	for( i = 0; i < 3; i++)
		func2[i](ri);

	/* Results:
		Test func2:
		You got an integer '82'.
		Your integer multiplied by 4 is: '328'.
		Your integer is an even number.
	*/

	// Test of func3
	printf("\nTest func3:\n");

	func3[0] = func3_1;
	func3[1] = func3_2;
	func3[2] = func3_3;

	for( i = 0; i < 3; i++)
	{
		ri = rand() % 90 + 10;
		printf("%d: ", ri);

		pfunc = func3[i](ri);
		pfunc('A');
	}

	/* Results:
		Test func3:
		20: You've entered func3_1: You input letter 'A', and its next letter is 'B'.
		93: You've entered func3_2: You input letter 'A'.
		57: You've entered func3_3: You input letter 'A', and its next letter is 'B'.
	*/

	// Test of func41
	printf("\nTest func41:\n");
	char (*tstr)[30];

	tstr = func41(3);

	for( i = 0; i < 3; i++)
		printf("%s", tstr[i]);

	free(tstr);

	/* Results:
		Test func41:
		This is string 0.
		This is string 1.
		This is string 2.
	*/

	// Test of func42
	printf("\nTest func42:\n");

	func42 = func41;
	tstr = func42(5);

	for( i = 0; i < 5; i++)
		printf("%s", tstr[i]);

	free(tstr);

	/* Results:
		Test func42:
		This is string 0.
		This is string 1.
		This is string 2.
		This is string 3.
		This is string 4.
	*/

	// Test of func43
	printf("\nTest func43:\n");
	char *(*tstrp)[3];

	tstrp = func43(2);

	for( i = 0; i < 2; i++)
	{
		for( j = 0; j < 3; j++)
		{
			printf("%s", tstrp[i][j]);
			free(tstrp[i][j]);
		}
	}

	free(tstrp);

	/* Results:
		Test func43:
		You got string 0, 0.
		You got string 0, 1.
		You got string 0, 2.
		You got string 1, 0.
		You got string 1, 1.
		You got string 1, 2.
	*/

	// Test of func4
	printf("\nTest func4:\n");

	func4 = func43;
	tstrp = func4(2);

	for( i = 0; i < 2; i++)
	{
		for( j = 0; j < 3; j++)
		{
			printf("%s", tstrp[i][j]);
			free(tstrp[i][j]);
		}
	}

	free(tstrp);

	/* Results:
		Test func4:
		You got string 0, 0.
		You got string 0, 1.
		You got string 0, 2.
		You got string 1, 0.
		You got string 1, 1.
		You got string 1, 2.
	*/

	// Test of func71
	printf("\nTest func71:\n");

	func71 = &func2;
	ri = rand() % 100 + 1;

	for( i = 0; i < 3; i++)
		(*func71)[i](ri);

	/* Results:
		Test func71:
		You got an integer '62'.
		Your integer multiplied by 8 is: '496'.
		Your integer is an even number.
	*/

	// Test of func5
	printf("\nTest func5:\n");
	char *strp;
	char *(*pfunc2)(void (*(*func7)[3])(int));

	func5 = func5_1;

	pfunc2 = func5(func43);
	strp = pfunc2(&func2);
	puts(strp);

	/* Results:
		Test func5:
		func6: You got string 0, 0.
		func6: You got string 0, 1.
		func6: You got string 0, 2.
		func6: You got string 1, 0.
		func6: You got string 1, 1.
		func6: You got string 1, 2.
		Here is func5_2():
		You got an integer '38'.
		Your integer multiplied by 6 is: '228'.
		Your integer is an even number.

		At the end of this day, one shall stand, one shall fall!
	*/

	return 0;
}
     
      
舊 2014-10-12, 01:44 AM #1
回應時引用此文章
Adsmt離線中