我有以下代码。我知道 这是错误的,但问题是,我不明白。何以. 下面我解释一下我的疑问。
#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
链接列表的第一个指针的地址,要实际访问第一个结构体,我是不是应该去引用来实际到达结构体的地址,然后再以 ->
来控制该结构的指针以获得 "值"?首先为你的 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
是用于指针而不是用于值。因此,如果你想比较,你可以比较以下两种情况 sPtr
与 NULL
或 *sptr
与 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
.
但是,对于打印函数,你不需要使用指针到指针,因为在这个函数中,你不改变或更新任何东西。你可以使用指针作为。
void printlist(Mychar *startPtr){
printf("%c\n", startPtr->value);
}
如果你这样做,在主函数中, 当你调用打印函数,
printlist(startPtr);
"不应该
**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)
而不是。
补充说明。
F.e.。
Mychar *newlinkPtr = calloc(1, sizeof(Mychar));
if (newlinkPtr == NULL)
{
fputs("Allocation failed!", stderr);
exit(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