c语言 - 编译器需要取消引用一次,而我实际上需要这样做两次。 "assigning to struct from incompatible type; remove * "



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

#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("%cn", *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("%cn", *startPtr->value);

我的疑问

  • 为什么如果在函数insert参数中我写**sPtr,那么在if块中我必须使用*sPtr,否则它会给我错误?**sPtr不等于 NULL,因为我主要在其中输入了 NULL 值?在main()中,当我在第 19 行调用insert时,我向那里发送了startPtr地址和,所以要在insert函数中访问其值 NULL,我应该放一个*来实际到达指针,另一个*来实际到达 NULL 值。
  • printlist功能上,几乎与以前的疑问相同。如果我"发送"以printlist链表第一个指针的地址,以实际访问第一个结构,我不应该取消引用以实际到达结构地址,然后再次取消引用->以控制该结构的指针以获取"值"?

首先是你的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("%cn", *startPtr->value);    // get error
}

*startPtr->value应该更改为(*startPtr)->value.

但是,使用打印功能,您不需要使用指向指针的指针,因为在此函数中,您无需更改或更新任何内容。您可以将指针用作:

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

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

printlist(startPtr);

"既然我把NULL值放在里面,**sPtr不等于NULL吗?">

不。

NULL是空指针的宏;它仅用于指针,而不是引用的对象(除非引用的对象也是指针并且您想检查是否为NULL,但这不是这里的重点(。

**sPtr是一个指向类型Mychar的指针,实际上是一个结构体。如果你取消引用sPtr(表示*sPtr(,你访问它指向的指针(实际上是在main中startPtr(,这对于检查NULL是正确的。

如果您使用if (**sPtr == NULL)则尝试取消引用startPtr- 一个NULL指针 - 本身,这是无效的,并尝试检查startPtr指向的对象(实际上没有任何对象(是否NULL,但不是startPtr

"我不应该取消引用以实际到达结构地址,然后再次取消引用->以控制该结构的指针以获取"值"吗?">

您需要先取消引用指向指针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("%cn", (*startPtr)->value);    
}

输出:

b

相关内容

  • 没有找到相关文章

最新更新