对C指针和内存地址有一些疑问
Having some doubts about C pointers and memory address
我真的是 C 的新手,我有一段关于 C 中 LinkedList 的代码:
struct ListNode* addnode(struct ListNode *head,int val)
{
struct ListNode* newnode = malloc(sizeof(struct ListNode));
newnode->val = val;
newnode->next = NULL;
if (!head) head = newnode;
else {
struct ListNode *this = head;
while(this->next)
this = this->next;
this->next = newnode;
}
return head;
}
int main(void)
{
struct ListNode *head = NULL;
head = addnode(head,4);
addnode(head,9);
addnode(head,1);
return 0;
}
我的问题是:主要是为什么我要写
addnode(head,4);
addnode(head,9);
addnode(head,1);
而不是
head = addnode(head,4);
addnode(head,9);
addnode(head,1);
不起作用?第一个是创建以下链表:4->9->1,第二个是创建 3 个不同的链表头。但这不就和我们一直使用 head 的内存地址一样吗?所以head总是在保存他之前的节点。
提前致谢,非常感谢您的回答
最初指针head
被初始化为空指针
struct ListNode *head = NULL;
此指针按值传递给函数addnode
addnode(head,4);
该函数处理在 main 中声明的指针 head
值的副本,用作函数的参数表达式。更改副本不会影响原始指针 head
.
所以在调用之后指针 head
仍然是一个空指针。
函数returns指针副本的修改值
struct ListNode* addnode(struct ListNode *head,int val)
{
//...
if (!head) head = newnode;
//...
return head;
}
要改变原来的指针head
你需要将返回值赋值给指针head
like
head = addnode(head,4);
现在指针head
指向列表的第一个节点。
该函数的所有其他调用
addnode(head,9);
addnode(head,1);
将新节点追加到列表的尾部。也就是说,这些调用不会影响指向列表第一个节点的指针的值。所以没有必要将函数的返回值分配给指针 head
尽管你可以写
head = addnode(head,9);
head = addnode(head,1);
为了更清楚地考虑一个非常简单的例子
#include <stdio.h>
int f( int x )
{
x += 1;
return x;
}
int main( void )
{
x = 0;
f( x );
printf( "x = %d\n", x );
}
如果您不会替换此声明
f( x );
为
x = f( x );
那么调用函数f
后变量x
不会在main中改变,因为函数f
改变了变量x
值的副本用作函数参数。
我真的是 C 的新手,我有一段关于 C 中 LinkedList 的代码:
struct ListNode* addnode(struct ListNode *head,int val)
{
struct ListNode* newnode = malloc(sizeof(struct ListNode));
newnode->val = val;
newnode->next = NULL;
if (!head) head = newnode;
else {
struct ListNode *this = head;
while(this->next)
this = this->next;
this->next = newnode;
}
return head;
}
int main(void)
{
struct ListNode *head = NULL;
head = addnode(head,4);
addnode(head,9);
addnode(head,1);
return 0;
}
我的问题是:主要是为什么我要写
addnode(head,4);
addnode(head,9);
addnode(head,1);
而不是
head = addnode(head,4);
addnode(head,9);
addnode(head,1);
不起作用?第一个是创建以下链表:4->9->1,第二个是创建 3 个不同的链表头。但这不就和我们一直使用 head 的内存地址一样吗?所以head总是在保存他之前的节点。
提前致谢,非常感谢您的回答
最初指针head
被初始化为空指针
struct ListNode *head = NULL;
此指针按值传递给函数addnode
addnode(head,4);
该函数处理在 main 中声明的指针 head
值的副本,用作函数的参数表达式。更改副本不会影响原始指针 head
.
所以在调用之后指针 head
仍然是一个空指针。
函数returns指针副本的修改值
struct ListNode* addnode(struct ListNode *head,int val)
{
//...
if (!head) head = newnode;
//...
return head;
}
要改变原来的指针head
你需要将返回值赋值给指针head
like
head = addnode(head,4);
现在指针head
指向列表的第一个节点。
该函数的所有其他调用
addnode(head,9);
addnode(head,1);
将新节点追加到列表的尾部。也就是说,这些调用不会影响指向列表第一个节点的指针的值。所以没有必要将函数的返回值分配给指针 head
尽管你可以写
head = addnode(head,9);
head = addnode(head,1);
为了更清楚地考虑一个非常简单的例子
#include <stdio.h>
int f( int x )
{
x += 1;
return x;
}
int main( void )
{
x = 0;
f( x );
printf( "x = %d\n", x );
}
如果您不会替换此声明
f( x );
为
x = f( x );
那么调用函数f
后变量x
不会在main中改变,因为函数f
改变了变量x
值的副本用作函数参数。