回值类型是一个指向整型的指针.
接下来的一个声明更为有趣:
int (*f)();
确定括号的含义是分析这个声明的一个重要步骤.这个声明有两对括号,每对的含义各不相同.第2对括号是函数调用操作符,但第1对括号只起到聚组的作用.它迫使间接访问在函数调用之前进行,使f成为一个函数指针,它所指向的函数返回一个整型值.
现在下面这个声明应该是比较容易弄懂了:
int *(*f)();
它和前一个声明基本相同,f也是一个函数指针,只是的所指向的函数的返回值是一个整型指针,必须对其进行间接访问操作才能得到一个整型值.
int (*f[])();
对于这个声明,首先你必须找到所有的操作符,然后按照正确的次序执行它们.同样,这里有两对括号,它们分别具有不同的含义.括号内的表达式*f[]首先进行求值,所以f是一个元素为某种类型的指针的数组.表达式末尾的()是函数调用操作符,所以f肯定是一个数组,数组元素的类型是函数指针,它所指向的函数的返回值是一个整型值.
如果搞清楚了上面最后一个声明,下面这个应该是比较容易的了:
int *(*f[])();
它和上面那个声明的唯一区别就是多了一个间接访问操作符,所以这个声明创建了一个指针数组,指针所指向的类型是返回值为整型指针的函数.
字符串常量:
当一个字符串常量出现于表达式中时,它的值是个指针常量.编译器把这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针.但是,当数组名用于表达式中时,它们的值也是指针常量.
下面这个表达式是什么意思呢
“xyz” + 1;
对于绝大多数程序员而言,它看上去像堆垃圾.它好像是试图在一个字符串上面执行某种类型的加法运算.但是,当你记得字符串常量实际上是指针时,它的意义就变得清楚了.这个表达式计算”指针值加上1”的值.它的结果是个指针,指向字符串中的第2个字符:y.
那么这个表达式又是什么呢
*”xyz”;
对一个指针执行间接访问操作时,其结果是指针所指向的内空.字符串常量的类型是”指向字符的指针”,所以这个间接访问的结果就是它所指向的字符:x,注意表达式的结果并不是整个字符串,而只是它的第1个字符.
下一个例子看上去也是有点奇怪,不过现在你应该对够推断出这个表达式的值就是字符z.
“xyz”[2];
下面这个语句是把二进制转换为字符:
putchar(“0123456789ABCDEF”[value%16]);
字符串,字符,字节
库函数strlen的原型:
size_t strlen(char const *string);
注意strlen返回一个类型为size_t(无符号整型),下面两个表达式看上去是相等的:
if(strlen(x) >= strlen(y))…..
if(strlen(x) – strlen(y) >= 0)….
但事实上它们是不相等的.第1条语句将接照你预想的那样工作,但第2条语句的结果将永远是真的.
字符串查找基础
在一个字符串中查找一个特定的字符最容易的方法是使用strchr和strrchr函数,它们的原型如下所示:
char *strchr(char const *str, int ch);
char *strchr(char const *str, int ch);
注意它们的第2个参数是一个整型值,但是它包括了一个字符值.strchr在字符串str中查找字符ch第1次出现的位置,找到后函数返回一个指向该位置的指针.如果该字符并不存在于字符串中,函数就返回一个NULL指针.strrchr的功能和strchr基本一致,只是它所返回的是一个指向字符串中该字符最后一次出现的位置(最右边那个).
查找任何几个字符
strpbrk是个更为常见的函数.它并不是查找某个特定的字符,而是查找任何一组字符第1次在字符串中出现的位置.它原型如下:
char *strpbrk(char const *str, char const *group);
这个函数返回一个指向str中第1个匹配group中任何一个字符的字符位置.如果未找到匹配,函数返回一个NULL指针.
在下面的代码段中:
char string[20] = “hello there, honey.”
char *ans;
ans = strpbrk(string, “aeiou”);
ans所指向的位置是string+1,因为这个位置是第2个参数中的字符e第一次出现的位置.这个函数是区分大小写的.
高级字符串查找
查找一个字符串前缀:
strspn和strcspn函数用于在字符串的起始位置对字符计数.它们的原型如下所示:
size_t strspn(char const *str, char const *group);
size_t strcspn(char const *str, char const *group);
group字符串指定一个或多个字符串.strspn返回str起始部分(从第一个字符开始)匹配group中任意字符的字符数.例如,如果group包含了空格,制表符等空白符,那么,这个函数将返回str起始部分空白字符的数目.str的下一个字符就是它的第一个非空白字符.
考虑下面这个例子:
int len1, len2;
char buffer[]=”25,142,330,Smith,J,239-4123”;
len1 = strspn(buffer, “0123456789”);
len2 = strspn(buffer, “,123456789”);
len1的值为2,从第一个字符开始,只有25可以匹配,再遇到”,”号时就结束匹配了.
len2的值为11,从第一个字符开始,匹配的内容为:”25,142,330,”当遇到字符S时匹配结束,因为字符S并不是第二个参数中的字符.
strcspn函数和strspn函数的功能正好相反,它对str字符串起始部分中不与group中任何字符匹配的字符进行计数.strcspn这个名字中字母c来源于对一组字符求补这个概念,也就是把这些字符换成原先并不存在的字符.如果你使用”\n\r\f\t\v”作为group参数,这个函数将返回第一个参数字符串起始部分所有非空白字符的值.
分隔字符串
一个字符串常常包含几个单独的部分,它们彼此被分隔开来.每次为了处理这些部分,你首先必须把它们从字符中抽取出来.
这个任务正是strtok函数所实现的功能.它从字符串中分离出被分隔符(由第二个参数字义)隔离的部分,并丢弃分隔符.它的原型如下:
char *strtok(char *str, char const *sep);
sep参数是个字符串,定义了用作分隔符的字符集合.第1个参数指定一个字符串,它包含零个或多个由sep字符串中一个或多个分隔符分离隔的子串.strok找到str的下一个子串,并将其它NULL结尾,然后返回一个指向这个子串的指针.
警告:
当strtok函