【问题标题】:Need clear understanding why value isn't affected even if passed by reference? [duplicate]需要清楚地理解为什么即使通过引用传递值也不会受到影响? [复制]
【发布时间】:2022-01-05 10:04:08
【问题描述】:

我有一个问题,我希望通过指针澄清。我来自 javascript,所以我很难使用指针。我主要是自己编写单链表代码,并且代码可以正常工作。我创建了一个函数来删除链表中的特定项目。 main里面的函数是这样的:

insertAtMiddle(&head, 3, 500);
insertAtMiddle(&head, 100, 500);

有一件事我无法理解。首先我想展示我的删除功能的代码。

void insertAtMiddle(node_t **head, int location, int newData){
    node_t *temp = *head;

    while(temp->next != NULL){
        if (temp->data == location)
        {
            break;
        }
        //Shouldn't that also change the original head or move the head to the left as it is passed by reference
        temp=temp->next;
    }

    if (temp->data != location)
    {
        printf("No location found for replacement!");
    }

    //Create new node 
    node_t *newNode = malloc(sizeof(node_t));
    newNode->data = newData;

    newNode->next = temp->next;
    temp->next = newNode;
}

我的问题不应该是 temp=temp->next; while循环里面也应该影响或修改原来的head? Head 已作为对此函数的引用传递。我的困惑是因为 *temp = *head, temp 已被指定为 head。

我的完整代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
    int data;
    struct node *next;
} node_t;

void viewAllNodes(node_t *head){
    node_t *tmp = head;

    printf("\n");

    while (tmp != NULL)
    {
        printf("%d--->", tmp->data);
        tmp=tmp->next;
    }

    printf("\n");
}

void insertAtBegining(node_t **head, int data){
    node_t *tmp = malloc(sizeof(node_t));
    tmp->data = data;
    tmp->next = *head;
    *head = tmp;
}

void deleteNode(node_t **head,int data){
    
    node_t *tmp = *head, *nodeToDelete = NULL;

    //see two nodes in advance
    while(tmp->next != NULL){

        if (tmp->next->data == data)
        {
            nodeToDelete = tmp->next;
            break;
        }
        tmp = tmp->next;
    }

    if (nodeToDelete == NULL)
    {
        printf("No node found to delete");
        return;
    }
    
    tmp->next = nodeToDelete->next;
    free(nodeToDelete);
}

void insertAtEnd(node_t **head, int data){
    node_t *newNode = malloc(sizeof(node_t));
    newNode->data = data;
    newNode->next = NULL;

    node_t *tmp = *head;
    
    while (tmp->next != NULL)
    {
        tmp = tmp->next;
    }

    tmp->next = newNode;
}

node_t *searchNode(node_t *head, int value){
    node_t *tmp = head;

    while (tmp->next != NULL)
    {
        if(tmp->data == value){
            return tmp;
        }
        tmp=tmp->next;
    }
    
    return NULL;
}

void insertAtMiddle(node_t **head, int location, int newData){
    node_t *temp = *head;

    while(temp->next != NULL){
        if (temp->data == location)
        {
            break;
        }
        //Shouldn't that also change the original head as it is passed by
        temp=temp->next;
    }

    if (temp->data != location)
    {
        printf("No location found for replacement!");
    }

    //Create new node 
    node_t *newNode = malloc(sizeof(node_t));
    newNode->data = newData;

    newNode->next = temp->next;
    temp->next = newNode;
}

int main(){

    node_t *head = NULL;

    insertAtBegining(&head, 1);
    insertAtBegining(&head, 2);
    insertAtBegining(&head, 3);
    insertAtBegining(&head, 4);
    insertAtBegining(&head, 5);
    insertAtBegining(&head, 6);

    insertAtEnd(&head, 8);
    insertAtEnd(&head, 9);

    insertAtBegining(&head, 100);
    viewAllNodes(head);
    
    deleteNode(&head, 1);
    deleteNode(&head, 8);

    insertAtMiddle(&head, 3, 500);
    insertAtMiddle(&head, 100, 500);

    viewAllNodes(head);

    return 0;
}

【问题讨论】:

  • 你永远不会修改*headtemp 只是 *head 的本地副本。
  • head 仍然指向它之前指向的位置。 temp 最初指向 head 指向的位置,稍后在 temp = temp-&gt;next 时更新。
  • @kiner_shah 不应更改 head,因为 temp 已指定为 *temp = *head;对 temp 所做的任何修改也会影响 head?
  • 这一行head的类型是什么:insertAtMiddle(&amp;head, 3, 500);
  • 关于指针的一个重要的事情是它们也是值,指向的内存位置,在 C 参数中是按值传递的,所以如果你将指针作为函数的参数传递,它是仍然是原始值的副本,更改它不会更改原始值。这并不是这里真正的主要问题,但它有助于理解动态。

标签: c pointers linked-list function-pointers


【解决方案1】:

你基本上是这样做的:

#include <stdio.h>

void foo(int* head) {
  int temp = *head;
  temp = 1234;
}

int main()
{
  int bar = 0;
  foo(&bar);
  printf("bar = %d\n", bar);
}

您期望1234 作为输出,但实际输出是0

temp 只是一个本地副本,修改temp 只会修改temp 并没有别的。

【讨论】:

  • 您能帮我了解导致这种情况的原因吗? onlinegdb.com/MX1oFcg83
  • @killerprince182 你应该问一个新问题
  • @killerprince182 快速回答:您从不修改a,也没有指向a 的指针,那么应该如何修改a
  • @killerprince182 here you have some pointers(双关语)关于指针的工作原理,请注意,这根本不能取代你应该进行的学习过程,我是一个老式的人,所以我认为你应该首先让自己成为good book
猜你喜欢
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2021-06-19
  • 2018-04-04
  • 2021-02-27
  • 2017-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多