在函数中使用双指针
Using double pointers in functions
我目前正在尝试了解如何将 linked 列为个人项目。我了解核心概念,并且一直在尝试将其实现到 c 中。我的程序看起来应该可以运行,请记住我对编程还是个新手 :D
我创建了一个名为 head 的结构指针。 head 将指向 linked_list 中的第一个节点,startPtr 将包含 head 的地址。每次调用函数 add 都会创建一个新节点并在内存中分配一些 space 然后之前创建的节点将指向新节点。
我知道我的程序在哪里崩溃,但我知道为什么?它编译得很好。
我的代码崩溃上线
(*prevNode)->link = newNode;
这是我看到这段代码的方式:
我将双指针 startPtr 传递给函数 add。然后我使用 malloc 创建了一个新节点。接下来我引用 startPtr(在函数中称为 prevNode),它应该包含 head 的内存地址……对吧?然后我使用“->”表达式指向 head 中名为 link 的结构指针。
程序到此结束,我不知道为什么。我看过其他 linked list c 代码,但其中大多数不使用双指针,它们只是声明全局结构和指针。我正在使用 GCC 作为我的编译器。
有人知道为什么会这样吗?
#include <stdio.h>
#include <stdlib.h>
// STRUCTURES
struct node
{
int data;
struct node *link;
}*head;
void add( int, struct node ** );
int main()
{
struct node *head;
struct node **startPtr;
startPtr = head;
struct node *nodePtr;
int userInput;
int inputData;
do{
printf( "\n\n1: enter new node\n" );
printf( "2: Print Nodes\n" );
printf( "\n\nEnter: " );
scanf( "%d", &userInput );
if ( userInput == 1 )
{
printf( "\n\nEnter data:");
scanf("%d", &inputData );
add( inputData, startPtr );
}
}while( userInput == 1 );
// printing linked list
nodePtr = head->link;
while( nodePtr->link != NULL )
{
printf( "%d\n", nodePtr->data);
nodePtr = nodePtr->link;
}
printf( "%d\n", nodePtr->data);
return 0;
}// END main()
void add( int num, struct node **prevNode )
{
// assigning memory for a new node
struct node *newNode = malloc( sizeof( struct node ) );
(*prevNode)->link = newNode;
newNode->data = num;
newNode->link = NULL;
prevNode = &newNode;
}// END add()
另外,我还有一个问题无法在线找到和回答。当我创建一个指向结构的指针时,例如结构节点 *ptr;。我的默认结构指针是否存储它自身的地址。就其自身而言,我指的是结构体,所以如果我打印 ptr,它会输出结构体 ptr 的地址吗?
struct node *head;
从未初始化
startPtr = head;
初始化为未初始化;超出这一点你的整个程序是未定义的。
这里有很多东西要解压...这些是未初始化的,然后你给一个指针起了别名而不是指向一个地址,所以你真的没有指向一个指针的指针你有两个相同的指针
struct node *head;
struct node **startPtr;
startPtr = head;
struct node *nodePtr;
可能是这样的:
struct node *head = NULL;
struct node **startPtr = &head;
struct node *nodePtr = NULL;
会是一个更好的开始......然后在 C 中你不能取消引用 NULL 指针所以你必须首先检查是否有可能是空指针......注意这不会检查未初始化的垃圾值,哪个局部变量可以是:
if(startPtr && *startPtr)
{
// now you know you can deref startPtr twice,
// once to a pointer to an object (which might be null)
// then after then && you can deref to an actual object
}
除了这个错字
startPtr = head;
^^^^
必须在哪里
startPtr = &head;
^^^^^
代码有几个问题。
第一个是 header 最初没有初始化。因此取消引用此指针会导致未定义的行为。
第二个问题就是这个循环
do{
printf( "\n\n1: enter new node\n" );
printf( "2: Print Nodes\n" );
printf( "\n\nEnter: " );
scanf( "%d", &userInput );
if ( userInput == 1 )
{
printf( "\n\nEnter data:");
scanf("%d", &inputData );
add( inputData, startPtr );
}
}while( userInput == 1 );
构建逻辑错误。例如,如果用户输入了一些不等于 1 或 2 的数字,那么程序将在退出循环后尝试输出列表。
第三个是因为最初 header 可以等于 null。所以函数中的这个语句
(*prevNode)->link = newNode;
再次调用未定义的行为,而且如果 *prevNode
不等于 NULL 那么所有早期附加的节点都将丢失,因为它的引用 link
被覆盖。
函数可以看成下面的样子
int add( struct node **head, int data )
{
struct node *newNode = malloc( sizeof( struct node ) );
int success = newNode != NULL;
if ( success )
{
newNode->data = data;
newNode->link = *head;
*head = newNode;
}
return success;
}
我目前正在尝试了解如何将 linked 列为个人项目。我了解核心概念,并且一直在尝试将其实现到 c 中。我的程序看起来应该可以运行,请记住我对编程还是个新手 :D
我创建了一个名为 head 的结构指针。 head 将指向 linked_list 中的第一个节点,startPtr 将包含 head 的地址。每次调用函数 add 都会创建一个新节点并在内存中分配一些 space 然后之前创建的节点将指向新节点。
我知道我的程序在哪里崩溃,但我知道为什么?它编译得很好。
我的代码崩溃上线
(*prevNode)->link = newNode;
这是我看到这段代码的方式: 我将双指针 startPtr 传递给函数 add。然后我使用 malloc 创建了一个新节点。接下来我引用 startPtr(在函数中称为 prevNode),它应该包含 head 的内存地址……对吧?然后我使用“->”表达式指向 head 中名为 link 的结构指针。
程序到此结束,我不知道为什么。我看过其他 linked list c 代码,但其中大多数不使用双指针,它们只是声明全局结构和指针。我正在使用 GCC 作为我的编译器。
有人知道为什么会这样吗?
#include <stdio.h>
#include <stdlib.h>
// STRUCTURES
struct node
{
int data;
struct node *link;
}*head;
void add( int, struct node ** );
int main()
{
struct node *head;
struct node **startPtr;
startPtr = head;
struct node *nodePtr;
int userInput;
int inputData;
do{
printf( "\n\n1: enter new node\n" );
printf( "2: Print Nodes\n" );
printf( "\n\nEnter: " );
scanf( "%d", &userInput );
if ( userInput == 1 )
{
printf( "\n\nEnter data:");
scanf("%d", &inputData );
add( inputData, startPtr );
}
}while( userInput == 1 );
// printing linked list
nodePtr = head->link;
while( nodePtr->link != NULL )
{
printf( "%d\n", nodePtr->data);
nodePtr = nodePtr->link;
}
printf( "%d\n", nodePtr->data);
return 0;
}// END main()
void add( int num, struct node **prevNode )
{
// assigning memory for a new node
struct node *newNode = malloc( sizeof( struct node ) );
(*prevNode)->link = newNode;
newNode->data = num;
newNode->link = NULL;
prevNode = &newNode;
}// END add()
另外,我还有一个问题无法在线找到和回答。当我创建一个指向结构的指针时,例如结构节点 *ptr;。我的默认结构指针是否存储它自身的地址。就其自身而言,我指的是结构体,所以如果我打印 ptr,它会输出结构体 ptr 的地址吗?
struct node *head;
从未初始化
startPtr = head;
初始化为未初始化;超出这一点你的整个程序是未定义的。
这里有很多东西要解压...这些是未初始化的,然后你给一个指针起了别名而不是指向一个地址,所以你真的没有指向一个指针的指针你有两个相同的指针
struct node *head;
struct node **startPtr;
startPtr = head;
struct node *nodePtr;
可能是这样的:
struct node *head = NULL;
struct node **startPtr = &head;
struct node *nodePtr = NULL;
会是一个更好的开始......然后在 C 中你不能取消引用 NULL 指针所以你必须首先检查是否有可能是空指针......注意这不会检查未初始化的垃圾值,哪个局部变量可以是:
if(startPtr && *startPtr)
{
// now you know you can deref startPtr twice,
// once to a pointer to an object (which might be null)
// then after then && you can deref to an actual object
}
除了这个错字
startPtr = head;
^^^^
必须在哪里
startPtr = &head;
^^^^^
代码有几个问题。
第一个是 header 最初没有初始化。因此取消引用此指针会导致未定义的行为。
第二个问题就是这个循环
do{
printf( "\n\n1: enter new node\n" );
printf( "2: Print Nodes\n" );
printf( "\n\nEnter: " );
scanf( "%d", &userInput );
if ( userInput == 1 )
{
printf( "\n\nEnter data:");
scanf("%d", &inputData );
add( inputData, startPtr );
}
}while( userInput == 1 );
构建逻辑错误。例如,如果用户输入了一些不等于 1 或 2 的数字,那么程序将在退出循环后尝试输出列表。
第三个是因为最初 header 可以等于 null。所以函数中的这个语句
(*prevNode)->link = newNode;
再次调用未定义的行为,而且如果 *prevNode
不等于 NULL 那么所有早期附加的节点都将丢失,因为它的引用 link
被覆盖。
函数可以看成下面的样子
int add( struct node **head, int data )
{
struct node *newNode = malloc( sizeof( struct node ) );
int success = newNode != NULL;
if ( success )
{
newNode->data = data;
newNode->link = *head;
*head = newNode;
}
return success;
}