[英]Passing Pointers in Functions for Linked List
#include <stdio.h>
#include <stdlib.h>
//why does this work with pointers thought they made a copy?
//am i freeing memory correctly and well?
//Something wrong with freeing
struct Node{
struct Node* next;
int data;
};
void newNode(struct Node* trans, int val)
{
if(trans!=NULL)
{
while(trans->next!=NULL)
{
trans=trans->next;
}
//next is null create heap memory
trans->next=malloc(sizeof(struct Node));
//checking to see if memory is created
if(trans->next==NULL)
{
printf("This has failed");
}
//put in data
trans->next->data=val;
//next is null
trans->next->next=NULL;
}
}
void printList(struct Node* head)
{
if(head!=NULL)
{
struct Node* current;
current=head;
while(current->next!=NULL)
{
//print that current nodes data
printf("list is: %d\n",current->data);
current=current->next;
}
printf("last element is: %d\n",current->data);
}
else
{
printf("list is empty!");
}
}
int removeLastNode(struct Node* trans)
{
//return -1 if its a empty list
int val=-1;
if(trans!=NULL)
{
/*have to access trans->next->next cause you are freeing trans->next->next and getting its val
then you want to set tran->next to NULL!
*/
while(trans->next->next!=NULL)
{
trans=trans->next;
}
//at end of the list?
val=trans->next->data;
//free the heap
free(trans->next);
//next points to null
trans->next=NULL;
}
return val;
}
//LOOK AT ME!
void freeList(struct Node* root)
{
struct Node* temp;
struct Node* current;
current=root;
while(current->next!=NULL)
{
temp=current;
//going to the next one
current=current->next;
//freeing previous
free(temp);
}
//Am I really freeing the last one?
free(current);
root->next=NULL;
root=NULL;
}
void addingHundred(struct Node* trans)
{
int i;
for(i=0;i<100;i++)
{
newNode(trans,i);
}
}
int main()
{
struct Node* root;
//create heap mem for root
root=malloc(sizeof(struct Node));
root->next=NULL;
root->data=10;
//traversal pointer
struct Node* trans;
//setting to point to root
trans=root;
//adding a new node..
newNode(trans,8);
printf("value of trans after function call: %p\n",trans);
newNode(trans,12);
//value does not change
printf("value of trans after function call: %p\n",trans);
addingHundred(trans);
//printing the list
printList(root);
int storage;
//removing last node
storage=removeLastNode(trans);
//returns the last nodes value
printf("value removed: %d\n",storage);
printList(root);
freeList(root);
printList(root);
return 0;
}
我对上面编写的代码有一些疑问。 一般概念上的问题,在被main
我做一个struct Node* tran
这个结构我称之为newNode
函数,它接受一个结构Node*
。 现在,我将tran
作为参数输入,但不传递tran
的地址。 在那种情况下,函数newNode
会不会只是创建tran
的值的副本,并且在函数调用后将撤消对函数的任何操作?
我用打印语句注意到了这一点,至少在newNode
函数调用之后tran
的值没有改变。 我要了解的是如何扩展和跟踪链表? 在这种情况下,将tran
的值作为参数传递是否可行,因为它最初指向的是根值的堆内存,然后简单地遍历堆中的内存,但实际上并未更改内存的内容?
如果是这样,那么为了更改列表中节点的值,我必须将&trans
作为参数传递,但是如果我只是遍历列表以在最后添加节点,我可以将tran
作为参数传递吗?
我的另一个问题是我不相信我的freeList(struct Node* a)
函数可以正常工作。 当我释放root
然后打印它时,它会为我打印一个垃圾值,而应该打印“列表为空”,或者打印垃圾会导致它访问我不拥有的内存?
最后,这里的某人批评我的代码是“最终用户应用程序代码”。 我还是编码的新手,我不确定上面的代码格式不正确,还是最终用户应用程序代码意味着什么。 如果有人解释了如何避免编写“最终用户应用程序代码”,我将不胜感激。
您没有按值传递trans
,而是传递了指向Node
struct的指针,因此将永远不会复制。
你说
我没有传递tran的地址
这是绝对错误的,实际上您所传递的正是这一点。
该值不会更改,因为您没有修改指针,在每次调用newNode
, trans
指针将完全指向它在调用之前所做的相同地址, 因此,不应观察到该值的变化 。
当您调用newNode
,新节点将附加到列表的newNode
,因此,如果您实际上遍历列表,您将看到所有值,以下代码将打印这些值
struct Node *node;
for (node = root ; node != NULL ; node = node->next)
printf("value %d @ %p\n", node->val, node);
在那里,您应该看到每个节点的地址及其值
free
并不意味着将内存设为0
,而是将其free
给操作系统,这就像您放弃了该地址处的内存所有权一样,如果有义务将内存设为0
,那么将会对性能造成巨大的影响对此。
如果要创建列表,根据您的代码将其empty
,则应在调用freeList()
之后执行此操作
root = NULL;
备注 :您的freeList
函数的freeList
有一个free(current)
,它使最后一个节点加倍释放,因此我将其删除,还修复了一些样式问题,并使printList()
函数更具可读性
#include <stdio.h>
#include <stdlib.h>
//why does this work with pointers thought they made a copy?
//am i freeing memory correctly and well?
//Something wrong with freeing
struct Node{
struct Node* next;
int data;
};
void newNode(struct Node* trans, int val)
{
if (trans != NULL)
{
while (trans->next != NULL)
trans = trans->next;
/* next is null create heap memory */
trans->next=malloc(sizeof(struct Node));
/* checking to see if memory is created */
if(trans->next == NULL)
printf("This has failed");
/* put in data */
trans->next->data = val;
/* next is null */
trans->next->next = NULL;
}
}
void printList(struct Node* head)
{
struct Node *node;
if (head == NULL)
printf("empty list\n");
for (node = head ; node != NULL ; node = node->next)
printf("list is: %d\n", node->data);
}
int removeLastNode(struct Node* trans)
{
int val = -1;
/* return -1 if its a empty list */
struct Node *node;
struct Node *last;
if (trans == NULL)
return -1;
/*
* have to access trans->next->next cause you are freeing trans->next->next and getting its val
* then you want to set tran->next to NULL!
*/
node = trans;
last = node->next;
while (last->next != NULL)
{
node = node->next;
last = node->next;
}
trans = node;
node = node->next;
/* at end of the list? */
val = node->data;
/* free the heap */
free(node);
/* next points to null */
trans->next = NULL;
return val;
}
//LOOK AT ME!
void freeList(struct Node* root)
{
struct Node* temp;
struct Node* current;
current = root;
while (current != NULL)
{
temp=current;
/* going to the next one */
current=current->next;
/* freeing previous */
free(temp);
}
}
void addingHundred(struct Node* trans)
{
int i;
for (i=0 ; i < 100 ; i++)
newNode(trans, i);
}
int main()
{
struct Node* root;
int storage;
//create heap mem for root
root = malloc(sizeof(struct Node));
root->next=NULL;
root->data=10;
//adding a new node..
newNode(root, 8);
newNode(root, 12);
addingHundred(root);
//printing the list
printList(root);
//removing last node
storage = removeLastNode(root);
//returns the last nodes value
printf("value removed: %d\n", storage);
printList(root);
freeList(root);
root = NULL;
printList(root);
return 0;
}
对于您在问题正文中的最后评论,我是这样做的。 我不了解,但是可以肯定的是您可以改善代码格式。 不要害怕使用空格字符,编译器还是会忽略它们(当然,在字符串文字中除外)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.