简体   繁体   English

指针算术在链表指针中不起作用?

[英]Pointer arithmetic not working in a linked list pointer?

I have a linked list, and I want to do decrement the pointer to the linked list pointer, but there are some issues. 我有一个链表,并且我想减小指向链表指针的指针,但是存在一些问题。

For below C program: 对于以下C程序:

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

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

int main()
{
    /*Create an empty list*/
    struct node *head = NULL;

    /*Set the first node of list*/
    head = malloc(sizeof(struct node));
    head->data = 1;
    head->next = NULL;

    struct node *head1 = head;

    /*Set the second node of list*/
    head1->next = malloc(sizeof(struct node));
    head1 = head1->next;
    head1->data = 2;
    head1->next = NULL;

    /*Print 1st and 2nd node data*/
    printf("%d ",head->data);
    head = head->next;
    printf("%d ",head->data);

    /*Decrement head. As head was pointing to 2nd node, after head-- it should point to first node ??*/
    head--;
    printf("%d \n",head->data);

    return 0;
}

I am expecting below output: 我期望以下输出:

1 2 1 

However I am getting below output: 但是我得到下面的输出:

User $ ./a.out
1 2 0 
User $

So it looks like the head-- I did at the end did not really decrement head by 1 (if it did head would be pointing to the first node before executing last printf). 因此,它看起来像head--我在最后所做的实际上并没有将head减1(如果这样做, head将在执行最后一个printf之前指向第一个节点)。

So cant do increment or decrement a linked-list pointer ? 那么不能增加或减少链接列表指针吗? Like we do for normal pointer ? 像我们为普通指针所做的一样? For ex: For a[] we do a++ or a-- to make a point to next or precious index. 例如:对于a [],我们执行a ++或a--指向下一个索引或珍贵索引。

NOTE: I JUST REALIZED THAT LINKED LIST NODES ARE NOT IN CONTIGUOUS MEMORY LOCATION, SO DOING A HEAD-- TO POINT TO PREVIOUS NODE DOES NOT MAKE SENSE. 注意:我只是意识到链接列表节点不在连续的内存位置中,所以要说的是-指向以前的节点是没有意义的。

Thank you all who answered or commented. 谢谢所有回答或评论的人。

When you use malloc() , you allocate new memory location from RAM (cash, or register), which located in a random area. 当使用malloc() ,您将从随机区域中的RAM(现金或寄存器)中分配新的内存位置。 So, when you write head--; 所以,当你写head--; , you move to completely different area, that you want. ,您将移至所需的完全不同的区域。 Try use doubly linked list. 尝试使用双向链表。

Simple pointer arithmetic only works for contiguous data structures. 简单指针算法仅适用于连续的数据结构。 A linked list is non-contiguous. 链表是不连续的。

When you allocate a new object, it is given a new memory location that is not contextually bound by the memory location of the previous item in the list. 分配新对象时,将为其赋予新的存储位置,该位置在上下文上不受列表中上一项的存储位置的限制。

When you increment or decrement a pointer the value of the pointer is changed by the size of the type of the pointer. 当您增加或减少指针时,指针的值将根据指针类型的大小而改变。 This is more than likely going to point outside the linked list. 这很有可能指向链接列表之外。

What you are trying to do works with arrays since array items are allocated in contiguous memory. 由于数组项是在连续内存中分配的,因此您要尝试对数组进行的操作。

You need a doubly linked list with both next and previous pointers. 您需要一个带有下一个和上一个指针的双链表。 So you can get back to an element's predecessor. 因此,您可以返回到元素的前身。

Your pointer head points to the memory you allocated for the node it points to - nothing else. 指针head指向分配给它指向的节点的内存-没有别的。 You have no information as to what's in the vicinity of that pointer and can't assume anything about where memory from malloc() is located outside of it being 'suitably aligned for any purpose', if I remember the standard correctly. 您没有关于该指针附近内容的信息,并且如果我正确地记住了标准,则无法假设malloc()内存位于其外部的位置是否“适合于任何目的”。

The answer is NO , you can only use the pointer arithmetic to move the pointer a number of units of the pointer type, like this 答案为NO ,您只能使用指针算法将指针移动多个指针类型的单位,例如

char array[2] = {'a', 'b'};

print("%c\n", *(array + 0));
/*             ~~~~~~~~~~~                         */
/*                  ^ points to the address of 'a' */
print("%c\n", *(array + 1));
/*             ~~~~~~~~~~~                                                */
/*                  ^ points to 'b', i.e. 1 byte after the address of 'a' */

will output 将输出

a
b

but the linked list, is linked to the next element by a pointer which is a member of the list structure, so incrementing it doesn't make sense, list++ is actually equivalent to 但是链接列表是通过指针(它是列表结构的成员)链接到下一个元素的,所以增加它没有意义, list++实际上等效于

list = ((char *)list) + sizeof(*list)

so when you increment the pointer like this, it's not pointing to the next node it's pointing sizeof(struct node) bytes after the location it was pointing to prior to the incrementation. 因此,当您像这样递增指针时,它并不指向下一个节点,而是指向递增之前指向的位置之后的sizeof(struct node)个字节。

To make the pointer, point to the next node you need 要创建指针,请指向您需要的下一个节点

list = list->next;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM