c - 当我实际上需要执行两次时,编译器需要取消引用一次。“从不兼容的类型分配给结构;删除 *”
问题描述
我有以下代码。我知道那是错误的,但问题是我不明白为什么。下面我解释一下我的疑惑。
#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 块中,否则它会给我错误?不应该等于 NULL,因为我已经把 NULL 值放在里面了?在 中,当我在第 19 行调用时,我将地址 &发送到那里,所以要在函数中访问它的值 NULL ,我应该放一个来实际到达指针,另一个来实际到达 NULL 值。*sPtr
**sPtr
main()
insert
startPtr
insert
*
*
- 在
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
has type时Mychar
:具有 type 的值Mychar
。
NULL
用于指针而不是值。因此,如果要比较,可以使用sPtr
withNULL
或*sptr
with进行比较NULL
。您不应将该值**sPtr
与NULL
. 顺便说一句,你的功能可以变成这样:
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
.
但是,使用 print 函数,您不需要使用指向指针的指针,因为在此函数中,您不会更改或更新任何内容。您可以将指针用作:
void printlist(Mychar *startPtr){
printf("%c\n", startPtr->value);
}
如果你这样做,在 main 函数中,当你调用 print 函数时:
printlist(startPtr);
推荐阅读
- visual-studio-code - 如何将主题符号链接到 VSCode 的扩展目录
- javascript - 如何使用 AJAX 验证 Google Recaptcha V3 响应
- markdown - Ghost博客中的嵌套编号列表
- eclipse-cdt - 使用 cdt 添加包含语句 (IASTPreprocessorIncludeStatement)
- lua - 如何随机化 char-rnn 的采样输出?
- java - 在 selenium 中使用 chrome 驱动程序执行脚本时出错
- java - 如何为不同类型的异常设置不同的状态码
- php - 具有多个变量的 Android Kotlin Volley Post String
- html - 基于标题标签的缩进
- scala - 一个类可以扩展自己吗?