为什么指针不重置,在递归函数调用中



我一直在尝试从输入中获取变量。所以我得到每个单词,并检查它是否是保留数组的一部分。如果它是保留数组的一部分,我从输入中获取下一个单词,这是一个变量。

下面是保留数组:

char *reserved[] = {
"char", NULL
};

该程序有两个输入。一个有type.h,另一个有ctype.h。第一个输入有效,但第二个输入无效:

#include <stdio.h>     /*works*/
#include <type.h>
char *reserved[] = {
#include <stdio.h>     /* doesn't work */
#include <ctype.h>
char *reserved[] = {

因此,函数从输入中获取一个字,并检查它是否是保留字。如果是,则将其添加到变量数组中,但如果它不是保留字,则再次运行该函数:

for(w = word, r = reserved; *r!= NULL; w=word, r++)     /* Go to the next reserved word*/
for (; *w == **r; (*r)++, w++)               /* check if the reserved word matches the word */
if (*w == '') {                             /* if it does, what follows is a variable */
getchar();                              /* get the space */
for (v = var, (c=getchar()) =='*'? c = getchar(): c;  c != ';' && c != '['; *v = '', c = getchar())
*v++ = c;                              /* add the variable to the variable array */
return var;                                /* return start of variable array */
}
if ((isalpha(*var)) == 0) {          /* if variable array is empty, recursively run the function */
var = getvar(var, reserved);
}

当程序检查输入ctype时,*r会递增,因为ctype的第一个字符和char保留字的第一个字符匹配。但是单词不匹配,函数这次再次运行,检查输入char。当再次调用保留函数时,指针r设置为保留函数的开头:

for(w = word, r = reserved; *r!= NULL; w=word, r++)

所以**r应该指向char保留字的字符c,但它指向charh

您能否解释一下,为什么指针没有指向开头,即使我只是将其设置为指向数组的开头,当我说r = reserved时。

如果您想通过调试器运行它,我已经附加了下面的代码。

#include <stdio.h>
#include <ctype.h>
char *getvar(char *var, char *reserved[]);
int main() {
char var[100];              /* stored a variable */
char *v;                    /* pointer to the start of variable array variable */
char *reserved[] = {
"char", NULL
};
v = getvar(var, reserved);  /* returns the start of a variable array */
printf("%s", v);            /* prints the variable*/
return 0;
}
char *getvar(char *var, char *reserved[])
{
int c;                       /* a character*/
char *v, *w, **r;           /* a variable, word, and a reserved word character*/
char word[100];             /* an array with a word */
while(((isalpha(c = getchar())) == 0) && c != EOF );  /* skip till you get to a name */
for(w = word; c != ' ' && c!='n' && c!='t' && c != EOF; c=getchar(), *w = '')
*w++ = c;                                           /* add name to a word */
for(w = word, r = reserved; *r!= NULL; w=word, r++)     /* Go to the next reserved word*/
for (; *w == **r; (*r)++, w++)               /* check if the reserved word matches the word */
if (*w == '') {                             /* if it does, what follows is a variable */
getchar();                              /* get the space */
for (v = var, (c=getchar()) =='*'? c = getchar(): c;  c != ';' && c != '['; *v = '', c = getchar())
*v++ = c;                              /* add the variable to the variable array */
return var;                                /* return start of variable array */
}
if ((isalpha(*var)) == 0) {          /* if variable array is empty, recursively run the function */
var = getvar(var, reserved);
}
return var;                                            /* return start of variable array */
}

您的代码逻辑过于复杂,这使得此函数很难调试... 程序的逻辑p中也存在许多错误,这使得无法按原样调试。 我的意思是,修复此指针错误(或错误)无法使该程序立即运行......

您要遵守的第一条规则是,程序是简单算法的集合,分为函数,您可以将这些函数组合成更复杂的算法。

例如:

// You want to write functions that only do one thing at a time, this will 
// make both your life and the reader's life a much more pleasant experience.
//
// This function reads a word from standard input
// params: 
//  - word:       work buffer to hold result.
//  - max_length: number of bytes in work buffer.
// returns:
//  - the address of buffer 'word'
//  - NULL on error
//
const char* read_input(char* word, int max_length)
{
// get a word:
// 1. skip until first alpha char, if EOF function FAILS (used to exit program)
// 2. read until first non-alpha char (EOF implicitely included)
char* w = word;
while (!isalpha(*w = getchar())
if (*w == EOF)
return NULL;

while (isalpha(*(++w) = getchar()) 
if (w >= word + max_length - 1)
return NULL;   // We're overflowing our storage space !!!
// You may want to print an error message here.
*++w = 0;         // NULL terminate the string.
return word;      // we're successful
}
// this function looks for word pointed to by 'word' in 
// NULL terminated array 'keywords'
//
// returns:
//  - if successful returns value of pointer 'word'.
//  - if failed, returns NULL
//
const char* find_keyword(const char* word, const char** keywords)
{
// Loop through array
// compare strings 
// return immediately when found
while (*keywords)
{
if (strcmp(word, *keywords) == 0)
return word;
++keywords;
}
return NULL;
}
int main()
{
char word[100];
const char* w, *kw;
const char *reserved[] = { "char", NULL };
// 1. get next keyword from input, if NULL, exit.
// 2. check if it is a reserved keyword.
// 3. give some visual feedback.

while ((w = read_input(word, sizeof(word))) != NULL)
{
kw = find_keyword(w, reserved);
if (kw)
printf("%sn", kw);
else
printf("keyword '%s' not found!n", w); 
}
return 0;
}

请注意,避免关注会使代码更易于编写和调试。 它还消除了不必要的复杂且容易出错的指针算法。

注意:此代码仅用于说明。 我还没有编译它,没有运行它,但它应该相当接近你想要实现的目标。 如果由于某种原因无法使用 strcmp,比较 2 个字符串是一个非常容易和直接的函数,只要您将其与其余代码隔离即可。

最新更新