标签:
复杂声明。
C语言常常因为声明的语法问题而受到人们的批评,特别是设计到函数指针的语法。C语言的语法力图使声明和使用相一致。对于简单的情况,C语言的这种做法很有效,但是,如果情况比较复杂,则容易让人混淆,原因在于,C语言的声明不能从左至右阅读,而且复杂的声明往往还使用了太多的圆括号。这里看两个声明:
int *f(); /* f: 是一个函数, 它返回一个指向int类型的指针 */
int (*pf)(); /* pf: pf是一个指向函数的指针,该函数返回一个int类型的对象 */
从上面两个例子含义差别说明:*是一个典型的前缀运算符(操作符),其优先级低于小括号(),所以,第二种含义的正确表达离不开小括号,可见,声明中使用小括号可以保证正确的结合顺序。
往往可以如下这样将C语言声明转换为文字描述,比如:
char **argv
argv: argv is a pointer to pointer to char
int (*daytab)[13]
daytab: daytab is a pointer to an array of 13 int
int *daytab[13]
daytab: daytab is an array of 13 pointers to int
void *comp()
comp: comp is a function with 0 arguments and returning a pointer to void
void (*comp)()
comp: comp is a pointer to a function with 0 arguments and returning a void
char (*(*x())[])()
x: x is a function with 0 arguments and returning a pointer to an array of pointer to a function with 0 arguments and returning char
char (*(*x[3])())[5]
x: x is an array of 3 pointer to a function with 0 arguments and returning pointer to an array of 5 char
1 /* 2 * 指针常量与常量指针 3 * */ 4 5 #include <stdio.h> 6 7 main() 8 { 9 int value = 3; 10 const int *p_value = &value;//p_value是常量指针,简称"常指针"。 p_value is pointer to const int. 11 //*p_value = 4;//编译器报错error: assignment of read-only location ‘*p_value‘ 12 { 13 int * const p_value = &value;//p_value是指针常量。 const p_value is a pointer to int 14 (*p_value)++;//特别注意:语句中括号去掉编译器将报错!因为*p_value++被编译器理解为 先使用p_value中记录的数据间接访问,然后给p_value加一。 15 //p_value = NULL;//编译器报错error: assignment of read-only location ‘p_value‘ 16 } 17 p_value = NULL; 18 19 }
1 /* 2 * 二级指针练习 3 * 4 * 切割字符串abcd,efg,hijkl,likk,l为abcd 5 * */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 void split(char *p_str, char **pp_str) { 10 int pos = 0; 11 for (pos = 0; p_str[pos] != ‘\0‘; pos++) 12 if (p_str[pos] == ‘,‘) 13 break; 14 pos--; 15 char *p_result = NULL; 16 p_result = (char *)calloc(pos, sizeof(char)); 17 if (p_result) { 18 for (*(p_result + pos) = ‘\0‘; pos >= 0; pos--) { 19 *(p_result + pos) = *(p_str + pos); 20 } 21 } 22 23 *pp_str = p_result; 24 } 25 26 27 int main() 28 { 29 char *p_str = NULL; 30 split("abc,defg,kjk", &p_str); 31 printf("%s\n", p_str); 32 free(p_str); 33 p_str = NULL; 34 35 return 0; 36 }
1 /* 2 * 函数指针:指向函数的指针练习 3 * 4 * 函数名称代表函数本身整个存储区,函数名称还代表着函数中的第一条语句的地址。函数名取址是函数地址,是整个函数的地址。这和数组名称一样,数组名称代表数组本身的整个存储区,数组名称还代表数组第一个元素的地址。数组名取址是整个数组的地址。 5 * 6 * 函数地址。 从地址信息上看函数地址就是函数中第一条语句所在的地址。 7 * 8 * */ 9 10 #include <stdio.h> 11 12 int main() 13 { 14 int add(int , int); 15 int sub(int , int); 16 printf("add是%p\n", add); 17 printf("&add是%p\n", &add); 18 19 int (*p_f)(int, int); 20 p_f = add; 21 printf("p_f(1, 1)是%d\n", p_f(1, 1)); 22 23 int (*p_func)(int, int) = NULL; 24 p_func = add; 25 printf("p_func(1, 1)是%d\n", p_func(1, 1)); 26 p_func = sub; 27 printf("p_func(1, 1)是%d\n", p_func(1, 1)); 28 29 typedef int (*p_function)(int, int); 30 p_function p_f1 = NULL; 31 p_f1 = sub; 32 printf("p_f1(1, 1)是%d\n", p_f1(1, 1)); 33 34 35 return 0; 36 } 37 38 int add( int value, int value1) 39 { 40 return value + value1; 41 } 42 int sub( int value, int value1) 43 { 44 return value - value1; 45 }
1 /* 2 * 函数指针练习 3 * 4 * 5 * */ 6 #include <stdio.h> 7 8 int add(int, int); 9 int sub(int, int); 10 11 int main() 12 { 13 14 int (*p_func)(int, int) = NULL; 15 16 int opr = 0; 17 printf("输入+将完成1+1计算,输入-将完成1-1运算:"); 18 scanf("%c", &opr); 19 switch (opr) { 20 case ‘+‘: 21 p_func = add; 22 break; 23 case ‘-‘: 24 p_func = sub; 25 break; 26 default: 27 printf("程序错误\n"); 28 return -1; 29 } 30 31 printf("运算 %c 结果是%d\n", opr, p_func(1, 1)); 32 33 return 0; 34 } 35 36 37 int sub(int a, int b) 38 { 39 return a - b; 40 } 41 42 int add(int a, int b) 43 { 44 return a + b; 45 }
标签:
原文地址:http://www.cnblogs.com/libig/p/4741158.html