编译器要求我在实际需要做两次的情况下进行一次去引用。"从不兼容的类型分配到结构体;删除*"

问题描述 投票:0回答:1

我有以下代码。我知道 这是错误的,但问题是,我不明白。何以. 下面我解释一下我的疑问。

#include <stdio.h>


struct mychar {
    char value;
    struct mychar *nextPtr;
};

typedef struct mychar Mychar;


void insert(Mychar **, char );    // line 19
void printlist(Mychar **);


int main(){
    Mychar *startPtr = NULL;

    insert(&startPtr, 'b');

    printlist(&startPtr);

}


void insert(Mychar **sPtr, char myvalue){
    Mychar *newlinkPtr = calloc(1, sizeof(Mychar));

    if (**sPtr == NULL){    // if I put two ** I get errors
        newlinkPtr->value = myvalue;
        newlinkPtr->nextPtr = **sPtr;    // same here
        **sPtr = newlinkPtr;    // same here
    }
}


void printlist(Mychar **startPtr){
    printf("%c\n", *startPtr->value);    // get error
}

下面是错误的地方。

liste_collegate.c:29:13: error: invalid operands to binary expression ('Mychar' (aka 'struct mychar') and 'void *')
        if (**sPtr == NULL){
            ~~~~~~ ^  ~~~~
liste_collegate.c:31:23: error: assigning to 'struct mychar *' from incompatible type 'Mychar' (aka 'struct mychar'); remove *
                newlinkPtr->nextPtr = **sPtr;
                                    ^ ~~~~~~
liste_collegate.c:32:10: error: assigning to 'Mychar' (aka 'struct mychar') from incompatible type 'Mychar *' (aka 'struct mychar *'); dereference with *
                **sPtr = newlinkPtr;
                       ^ ~~~~~~~~~~
                         *
liste_collegate.c:38:26: error: member reference base type 'Mychar *' (aka 'struct mychar *') is not a structure or union
        printf("%c\n", *startPtr->value);

我的疑惑:

  • 为什么如果在论点中 insert 我写的函数 **sPtr,然后在if块中 我必须要 使用 *sPtr否则它会给我错误的?不应该 **sPtr 等于NULL,因为我在主文件中已经把NULL值放在里面了。在 main() ,当我打电话 insert 在第19行,我发送 的地址&startPtr所以要访问其值NULL中的 insert 函数,我应该把一个 * 以实际到达指针,而另一个 * 实际达到NULL值。
  • printlist 功能,和之前的疑问差不多。如果我 "发送 "到 printlist 链接列表的第一个指针的地址,要实际访问第一个结构体,我是不是应该去引用来实际到达结构体的地址,然后再以 -> 来控制该结构的指针以获得 "值"?
c pointers data-structures struct linked-list
1个回答
1
投票

首先为你的 insert 功能。

void insert(Mychar **sPtr, char myvalue){
    Mychar *newlinkPtr = calloc(1, sizeof(Mychar));

    if (**sPtr == NULL){    // if I put two ** I get errors
        newlinkPtr->value = myvalue;
        newlinkPtr->nextPtr = **sPtr;    // same here
        **sPtr = newlinkPtr;    // same here
    }
}

sPtr 有类型 Mychar **: 指向指针的指针。

*sPtr 具有类型 Mychar *:指向类型的指针 Mychar.

现在当你使用 **sPtr 有型 Mychar价值:类型为 Mychar.

NULL 是用于指针而不是用于值。因此,如果你想比较,你可以比较以下两种情况 sPtrNULL*sptrNULL. 你不应该比较的值 **sPtrNULL. 另外,你的功能可以变成这样。

void insert(Mychar **sPtr, char myvalue){
    Mychar *newlinkPtr = calloc(1, sizeof(Mychar));
    if (!newlinkPtr) {return;} // you should check the return value of calloc funciton because it may be failed

    if (*sPtr == NULL) {  
        newlinkPtr->value = myvalue;
        newlinkPtr->nextPtr = *sPtr;   
        *sPtr = newlinkPtr;  
    }
}

对于打印功能,

void printlist(Mychar **startPtr){
    printf("%c\n", *startPtr->value);    // get error
}

*startPtr->value 应该改成 (*startPtr)->value.

但是,对于打印函数,你不需要使用指针到指针,因为在这个函数中,你不改变或更新任何东西。你可以使用指针作为。

void printlist(Mychar *startPtr){
    printf("%c\n", startPtr->value);
}

如果你这样做,在主函数中, 当你调用打印函数,

printlist(startPtr);

0
投票

"不应该 **sPtr 等于 NULL,因为我已经把 NULL 里面的值在主?"

不是的。

NULL 是一个空指针的宏;它只用于指针,而不是它的引用对象(除非被引用的对象也是一个指针,而你想检查它是否为 NULL但这不是重点)。)

**sPtr 是指向类型的指针 Mychar,实际上是一个结构。如果你对 sPtr ( 指 *sPtr)访问它所指向的指针(实际上是 startPtr 中的),这对于检查 NULL.

如果您使用 if (**sPtr == NULL) 你试图取消引用 startPtr - a NULL 指针--本身是无效的,并试图检查对象的 startPtr 是指向(其实什么也没有)为 NULL但不是 startPtr.

"我是不是应该通过dereferenciate来实际到达结构地址,然后再通过 -> 来控制该结构的指针获得 "值"?"

你需要将指针去引用到指针上 startPtr 先后 value->. 使用 (*startPtr)->value) 而不是。


补充说明。

  1. 总是检查内存管理函数的返回值,如果分配成功。

F.e.。

Mychar *newlinkPtr = calloc(1, sizeof(Mychar));
if (newlinkPtr == NULL)
{
    fputs("Allocation failed!", stderr);
    exit(1);
}
  1. (可能只是一个复制和粘贴的错误 但值得一提) #include <stdlib.h>,这对于使用 calloc().

结果:

#include <stdio.h>
#include <stdlib.h>


struct mychar {
    char value;
    struct mychar *nextPtr;
};

typedef struct mychar Mychar;


void insert(Mychar **, char );    
void printlist(Mychar **);


int main (void) {
    Mychar *startPtr = NULL;

    insert(&startPtr, 'b');

    printlist(&startPtr);

}


void insert(Mychar **sPtr, char myvalue){
    Mychar *newlinkPtr = calloc(1, sizeof(Mychar));
    if (newlinkPtr == NULL)
    {
        fputs("Allocation failed!", stderr);
        exit(1);
    }

    if (*sPtr == NULL){    
        newlinkPtr->value = myvalue;
        newlinkPtr->nextPtr = *sPtr;    
        *sPtr = newlinkPtr;    
    }
}


void printlist(Mychar **startPtr){
    printf("%c\n", (*startPtr)->value);    
}

输出:

b
© www.soinside.com 2019 - 2024. All rights reserved.