【问题标题】:Parameters and pointers with function inside function in CC中函数内部函数的参数和指针
【发布时间】:2016-03-14 00:03:12
【问题描述】:

我在尝试将指针用作另一个函数内的函数的参数时遇到了一些麻烦。我的目标是在每个函数中保留变量“counter”的值,换句话说,当最低的函数声明一个“counter++”时,它的值必须为程序中的每个其他“counter”变量递增。

我的代码如下所示:

int main(int argc, const char * argv[]) {

    Hash tableHash;
    char command[6];
    int id = 0, counter = -1;
    int flags[4] = {0, 0, 0, 0};

    while(1) {
         identifyCommand(command, id, &tableHash, flags, &counter);
    }

    return 0;
    }

在我的 .h 中:

void identifyCommand(char* command, int id, Hash* tableHash, int* flag, int* counter){

    scanf("%s", command);

    /* ... */

    if(strcmp(command, "INSERT") == 0){
        scanf("%i", &id);
        commandInsert(id, tableHash, counter, flag);
    }

    /* ... */

    return;
}

void commandInsert(int id, Hash* tableHash, int* counter, int* flag){

    Registry x;
    x.key = id;

    if(flag[MALLOCFLAG]){
        tableHash->trees[*counter] = create_tree(x);
        counter++;
        flag[MALLOCFLAG] = 0;
    }
    else {
        insert_element(tableHash->trees[*counter], x);
    }
    return;
}

我的主要问题是:当我运行代码时,即使在 commandInsert() 函数中运行了“counter++”命令后,它也会继续发送计数器的“-1”值。为什么会发生这种情况,我该如何解决?

我认为问题可能出在 commandInsert(id, tableHash, counter, flag) 调用上,因为我没有使用参考符号 (&),但是在 identifyCommand() 内部时,'counter' 已经是一个指针,因为它的参数,所以我在这里缺少什么?

【问题讨论】:

    标签: c function pointers parameters dereference


    【解决方案1】:

    既然你想改变counter指向的,你应该改变这个值。但是你正在增加指针。

    counter++;
    

    应该是

    (*counter)++;
    

    正如@szczurcio 所说,您传递的command 数组最多只能包含5 个字符(1 个用于NUL 终止符)。所以command数组的大小需要至少为7才能读取"INSERT"。为防止缓冲区溢出,可以使用scanf()中的宽度如:

    char command[7];
    scanf("%6s", command); 
    

    或者你可以使用fgets()

    char command[7];
    fgets(command, sizeof command, stdin);
    
    char *p = strchr(command, '\n');
    if (p) *p = 0;
    

    但是,由于您将command 传递给函数,因此您不能在函数内部使用sizeof command,因为这将返回sizoof(char*)(当传递给函数时,数组衰减为指向其第一个元素的指针)。所以你必须通过另一个参数传递大小信息:

    来自调用者:

       while(1) {
         identifyCommand(command, sizeof command, id, &tableHash, flags, &counter);
       }
    

    并在函数中:

    void identifyCommand(char* command, size_t size, int id, Hash* tableHash,
     int* flag, int* counter){
    
       fgets(command, size, stdin);
    
       /* To remove the trailing newline, if any */
       char *p = strchr(command, '\n');
       if (p) *p = 0;
    
       ...
    

    【讨论】:

    • 编程时一个有用的约定是在变量名的末尾或开头使用“p”或“ptr”来提醒自己它是指针而不是值。所以在 OP 的情况下使用 int *counterp 作为参数。这样可以很容易地在心理上将这些点联系起来。
    • 哇,我完全没看到。愚蠢的错误,花了我几个小时哈哈。非常感谢!!
    • @StephenG 确实如此。在我的工作中,有一个约定是使用_p 后缀作为指针,_pp 作为指向指针的指针。这样一来,您就不必每次都查看声明,并且有助于解决此类事故。
    • 值得一提的是char command[6] 不能持有“INSERT”,这似乎是有效的命令之一。通常 OP 不应该在不指定缓冲区宽度的情况下使用scanf
    • @szczurcio 感谢您的指出。我已经更新以涵盖这一点。
    猜你喜欢
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    相关资源
    最近更新 更多