C语言的声明有时候是及其复杂的,不如char * (* c[10]) (int **p); 这样声明即使让C语言老手看到也会不寒而栗,有没有想过让程序帮我们把这么难懂的声明翻译成比较通俗易懂的语言呢?完全可以!
先来个简单的:int i;
再来个指针: int * p
看看复杂一点的: char * const * (* next) ();
最后看看这个 char * (* c[10]) (int **p);是什么东西:
是不是比你一个一个分析要简单的多了
贴上代码吧
// change_a.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAXTOKENS 100
#define MAXTOKENLEN 64
enum type_tag { IDENTIFIER, QUALIFIER, TYPE };
struct token {
char type;
char string[MAXTOKENLEN];
};
int top = -1;
struct token stack[MAXTOKENS];
struct token this;
#define pop stack[top--]
#define push(s) (stack[++top] = s)
enum type_tag classify_string(void)
/* 推断标示符的类型 */
{
char *s = this.string;
if(!strcmp(s, "const")){
strcpy(s, "read-only");
return QUALIFIER;
}
if(!strcmp(s, "volatile"))
return QUALIFIER;
if(!strcmp(s, "void"))
return TYPE;
if(!strcmp(s, "char"))
return TYPE;
if(!strcmp(s, "signed"))
return TYPE;
if(!strcmp(s, "unsigned"))
return TYPE;
if(!strcmp(s, "short"))
return TYPE;
if(!strcmp(s, "int"))
return TYPE;
if(!strcmp(s, "long"))
return TYPE;
if(!strcmp(s, "float"))
return TYPE;
if(!strcmp(s, "double"))
return TYPE;
if(!strcmp(s, "struct"))
return TYPE;
if(!strcmp(s, "union"))
return TYPE;
if(!strcmp(s, "enum"))
return TYPE;
return IDENTIFIER;
}
void gettoken(void)
{
char *p = this.string;
while ((*p = getchar()) == ' '); /* 略过空白符 */
if (isalnum(*p)){
while (isalnum(*++p = getchar()));
ungetc(*p, stdin);
*p = '\0';
this.type = classify_string();
return;
}
if (*p == '*') {
strcpy(this.string, "pointer to");
this.type = '*';
return;
}
this.string[1] = '\0';
this.type = *p;
return;
}
/* 理解所以分析过程的代码段 */
read_to_first_identifer() {
gettoken();
while(this.type != IDENTIFIER) {
push(this);
gettoken();
}
printf("%s is ", this.string);
gettoken();
}
deal_with_arrays() {
while(this.type == '[') {
printf("array ");
gettoken();
if(isdigit(this.string[0])){
printf("0..%d ", atoi(this.string) - 1);
gettoken();
}
gettoken();
printf("of ");
}
}
deal_with_function_args() {
while (this.type != ')') {
gettoken();
}
gettoken();
printf("function returning ");
}
deal_with_pointers() {
while (stack[top].type == '*') {
printf("%s ", stack[top--].string);
}
}
deal_with_declarator() {
switch (this.type) {
case '[' : deal_with_arrays();
break;
case '(' : deal_with_function_args();
}
deal_with_pointers();
while (top >= 0) {
if(stack[top].type == '(') {
pop;
gettoken();
deal_with_declarator();
}
else {
printf("%s ", pop.string);
}
}
}
main()
{
read_to_first_identifer();
deal_with_declarator();
printf("\n");
return 0;
}