PCDVD數位科技討論區
PCDVD數位科技討論區   註冊 常見問題 標記討論區為已讀

回到   PCDVD數位科技討論區 > 其他群組 > 七嘴八舌異言堂
帳戶
密碼
 

回應
 
主題工具
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離線中  
supermaxfight
Golden Member
 
supermaxfight的大頭照
 

加入日期: Jun 2002
您的住址: 地獄18層
文章: 3,235
以前寫來玩玩的
給學生練習的

代碼:
<html>
<body>
<script type="text/javascript">
        document.write("<table border=1>")
        for (i = 1; i <= 9; i++) {
            document.write("<tr>")
            for (j = 2; j <= 9; j++) {
                document.write("<td>" + j + "*" + i + "=" + j * i + "</td>")
            }
            document.write("</tr>")
        }
        document.write("</table>")
      </script>
</body>
</html>
 
__________________
徵你不要的AM4 CPU
徵你不要的SATA接頭斷裂SSD
舊 2014-10-12, 01:49 AM #2
回應時引用此文章
supermaxfight離線中  
darkangel
Major Member
 
darkangel的大頭照
 

加入日期: Aug 2001
文章: 211
其實 pointer to function 是很常用的東西,不過實務上我會盡量避免寫出有複雜指標的東西,因為不好維護。
如果會用 pointer to pointer 或 pointer to reference 一定有其理由存在,比如說要傳 pointer 給 function。
__________________
滿招損 謙受益
舊 2014-10-12, 02:02 AM #3
回應時引用此文章
darkangel離線中  
藺無雙
Basic Member
 
藺無雙的大頭照
 

加入日期: Jan 2006
文章: 21
以前學生時代還懂點皮毛,現在工作要用到程式只會寫C# @@
舊 2014-10-12, 03:34 AM #4
回應時引用此文章
藺無雙離線中  
youporn
Major Member
 

加入日期: Mar 2012
文章: 196
這樣也能寫出程式

引用:
#include <stdio.h>

main(t,_,a)
char *a;
{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
main(-86, 0, a+1 )+a)):1,t<_?main(t+1, _, a ):3,main ( -94, -27+t, a
)&&t == 2 ?_<13 ?main ( 2, _+1, "%s %d %d\n" ):9:16:t<0?t<-72?main(_,
t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+\
,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/\
+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){n\
l]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#\
n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;\
#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")
:t<-50?_==*a ?putchar(a[31]):main(-65,_,a+1):main((*a == '/')+t,_,a\
+1 ):0<t?main ( 2, 2 , "%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc \
i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}
舊 2014-10-12, 11:05 AM #5
回應時引用此文章
youporn離線中  
要你命3000
Major Member
 

加入日期: Sep 2008
文章: 203
這看起來比較像是找工作面試的考題

記得之前我被一題打敗了

c = a+++b

a ?
b ?
c ?

當然我

不過實際coding在project時,寫成這樣大概會被......
舊 2014-10-12, 03:15 PM #6
回應時引用此文章
要你命3000離線中  
Adsmt
Golden Member
 
Adsmt的大頭照
 

加入日期: Feb 2004
您的住址: 從來處來
文章: 2,762
引用:
作者youporn
這樣也能寫出程式

這叫obfuscation吧, 還有專門的比賽,也算是一種趣味的程式競賽....
不過其實可以用現有的程式做obfuscation.
舊 2014-10-13, 06:46 PM #7
回應時引用此文章
Adsmt離線中  
27681049
Advance Member
 

加入日期: Jul 2012
您的住址: 新竹
文章: 409
引用:
作者要你命3000
這看起來比較像是找工作面試的考題

記得之前我被一題打敗了

c = a+++b

a ?
b ?
c ?

當然我

不過實際coding在project時,寫成這樣大概會被......


沒錯,
真正做事寫這種程式碼是等著被念而已...
舊 2014-10-13, 07:40 PM #8
回應時引用此文章
27681049離線中  
darkangel
Major Member
 
darkangel的大頭照
 

加入日期: Aug 2001
文章: 211
引用:
作者藺無雙
以前學生時代還懂點皮毛,現在工作要用到程式只會寫C# @@


C# 有 unsafe 關鍵字可以用指標,不過型別跟 C 似乎不是能夠完全對應,因為我曾用 C 寫 DLL,然後在 C# 裡用指標想直接取資料... 後來發現有問題,才改用別的方式。
__________________
滿招損 謙受益
舊 2014-10-13, 07:49 PM #9
回應時引用此文章
darkangel離線中  


回應


POPIN
主題工具

發表文章規則
不可以發起新主題
不可以回應主題
不可以上傳附加檔案
不可以編輯您的文章

vB 代碼打開
[IMG]代碼打開
HTML代碼關閉



所有的時間均為GMT +8。 現在的時間是06:23 AM.


vBulletin Version 3.0.1
powered_by_vbulletin 2025。