指针算法在链表指针中不起作用?
Pointer arithmetic not working in a linked list pointer?
我有一个链表,我想把指针递减到链表指针,但是有一些问题。
对于以下 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;
}
我期待以下输出:
1 2 1
但是我的输出低于:
User $ ./a.out
1 2 0
User $
所以看起来我最后做的 head--
并没有真正将 head
减 1(如果它确实 head
将指向最后执行之前的第一个节点打印)。
所以不能递增或递减链表指针?就像我们对普通指针所做的那样?例如:对于 a[] 我们做 a++ 或 a-- 指向下一个或珍贵的索引。
注意:我刚刚意识到链表节点不在连续的内存位置,所以做一个 head-- 指向前一个节点没有意义。
感谢所有回答或评论的人。
当您使用malloc()
时,您从位于随机区域的RAM(现金或寄存器)分配新的内存位置。所以,当你写 head--;
时,你会移动到你想要的完全不同的区域。尝试使用双向链表。
您的指针 head
指向您为它指向的节点分配的内存 - 没有别的。您没有关于该指针附近有什么的信息,也不能假设 malloc()
的内存位于 'suitably aligned for any purpose' 之外,如果我没记错的话。[=12] =]
答案是否,只能用指针运算将指针移动指针类型的单位数,像这样
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' */
会输出
a
b
但是链表通过一个指针链接到下一个元素,该指针是列表结构的成员,因此递增它没有意义,list++
实际上等同于
list = ((char *)list) + sizeof(*list)
所以当你像这样递增指针时,它不会指向下一个节点,它指向递增之前指向的位置之后 sizeof(struct node)
个字节。
要制作指针,请指向您需要的下一个节点
list = list->next;
简单的指针算法只适用于连续的数据结构。链表是不连续的。
当您分配一个新对象时,它会获得一个新的内存位置,该位置不受列表中前一项内存位置的上下文约束。
当您递增或递减指针时,指针的值会根据指针类型的大小而改变。这很可能指向链表之外。
由于数组项是在连续内存中分配的,因此您尝试对数组进行操作。
您需要一个包含下一个和上一个指针的双向链表。所以你可以回到元素的前身。
我有一个链表,我想把指针递减到链表指针,但是有一些问题。
对于以下 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;
}
我期待以下输出:
1 2 1
但是我的输出低于:
User $ ./a.out
1 2 0
User $
所以看起来我最后做的 head--
并没有真正将 head
减 1(如果它确实 head
将指向最后执行之前的第一个节点打印)。
所以不能递增或递减链表指针?就像我们对普通指针所做的那样?例如:对于 a[] 我们做 a++ 或 a-- 指向下一个或珍贵的索引。
注意:我刚刚意识到链表节点不在连续的内存位置,所以做一个 head-- 指向前一个节点没有意义。
感谢所有回答或评论的人。
当您使用malloc()
时,您从位于随机区域的RAM(现金或寄存器)分配新的内存位置。所以,当你写 head--;
时,你会移动到你想要的完全不同的区域。尝试使用双向链表。
您的指针 head
指向您为它指向的节点分配的内存 - 没有别的。您没有关于该指针附近有什么的信息,也不能假设 malloc()
的内存位于 'suitably aligned for any purpose' 之外,如果我没记错的话。[=12] =]
答案是否,只能用指针运算将指针移动指针类型的单位数,像这样
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' */
会输出
a
b
但是链表通过一个指针链接到下一个元素,该指针是列表结构的成员,因此递增它没有意义,list++
实际上等同于
list = ((char *)list) + sizeof(*list)
所以当你像这样递增指针时,它不会指向下一个节点,它指向递增之前指向的位置之后 sizeof(struct node)
个字节。
要制作指针,请指向您需要的下一个节点
list = list->next;
简单的指针算法只适用于连续的数据结构。链表是不连续的。
当您分配一个新对象时,它会获得一个新的内存位置,该位置不受列表中前一项内存位置的上下文约束。
当您递增或递减指针时,指针的值会根据指针类型的大小而改变。这很可能指向链表之外。
由于数组项是在连续内存中分配的,因此您尝试对数组进行操作。
您需要一个包含下一个和上一个指针的双向链表。所以你可以回到元素的前身。