![]() |
||
|
Golden Member
![]() ![]() ![]() ![]() 加入日期: Feb 2004 您的住址: 從來處來
文章: 2,765
|
玩玩 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;
}
|
|||||||
|
|
|
Golden Member
![]() ![]() ![]() ![]() 加入日期: Jun 2002 您的住址: 地獄18層
文章: 3,265
|
以前寫來玩玩的
給學生練習的 代碼:
<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
|
||
|
|
|
Major Member
![]() 加入日期: Aug 2001
文章: 211
|
其實 pointer to function 是很常用的東西,不過實務上我會盡量避免寫出有複雜指標的東西,因為不好維護。
如果會用 pointer to pointer 或 pointer to reference 一定有其理由存在,比如說要傳 pointer 給 function。
__________________
滿招損 謙受益 |
|
|
|
Basic Member
加入日期: Jan 2006
文章: 21
|
以前學生時代還懂點皮毛,現在工作要用到程式只會寫C# @@
|
|
|
|
Major Member
![]() 加入日期: Mar 2012
文章: 196
|
這樣也能寫出程式
引用:
|
|
|
|
|
Major Member
![]() 加入日期: Sep 2008
文章: 203
|
這看起來比較像是找工作面試的考題
記得之前我被一題打敗了 c = a+++b a ? b ? c ? 當然我 不過實際coding在project時,寫成這樣大概會被...... ![]() |
|
|
|
Golden Member
![]() ![]() ![]() ![]() 加入日期: Feb 2004 您的住址: 從來處來
文章: 2,765
|
引用:
這叫obfuscation吧, 還有專門的比賽,也算是一種趣味的程式競賽.... 不過其實可以用現有的程式做obfuscation. |
|
|
|
|
Advance Member
![]() ![]() 加入日期: Jul 2012 您的住址: 新竹
文章: 409
|
引用:
沒錯, 真正做事寫這種程式碼是等著被念而已... |
|
|
|
|
Major Member
![]() 加入日期: Aug 2001
文章: 211
|
引用:
C# 有 unsafe 關鍵字可以用指標,不過型別跟 C 似乎不是能夠完全對應,因為我曾用 C 寫 DLL,然後在 C# 裡用指標想直接取資料... 後來發現有問題,才改用別的方式。
__________________
滿招損 謙受益 |
|
|
|