这不能在 Microsoft 下使用 cl 进行编译(下面的错误消息 - 它在提示什么?),但可以使用 gcc 进行编译。有人可以用简单的英语解释下面这行吗?是否有一些具有较少指针逻辑的代码也可以做到这一点?
================================================== =============
*(char *)(new_node->data + i) = *(char *)(new_data + i);
================================================== =============
/* Function to add a node at the beginning of Linked List.
This function expects a pointer to the data to be added
and size of the data type */
void push(struct Node** head_ref, void *new_data, size_t data_size)
{
// Allocate memory for node
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = malloc(data_size);
new_node->next = (*head_ref);
// Copy contents of new_data to newly allocated memory.
// Assumption: char takes 1 byte.
int i; //line 27
for (i=0; i<data_size; i++) //line 28
*(char *)(new_node->data + i) = *(char *)(new_data + i);
// Change head pointer as new node is added at the beginning
(*head_ref) = new_node;
}
MS 错误消息
C:\Temp\c\LinkedLists>cl z.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
z.c
z.c(27) : error C2143: syntax error : missing ';' before 'type'
z.c(28) : error C2065: 'i' : undeclared identifier
z.c(28) : error C2065: 'i' : undeclared identifier
z.c(28) : error C2065: 'i' : undeclared identifier
z.c(29) : error C2065: 'i' : undeclared identifier
z.c(29) : error C2036: 'void *' : unknown size
z.c(29) : error C2065: 'i' : undeclared identifier
z.c(29) : error C2036: 'void *' : unknown size
z.c(29) : error C2106: '=' : left operand must be l-value
z.c(74) : error C2143: syntax error : missing ';' before 'type'
z.c(76) : error C2143: syntax error : missing ';' before 'type'
z.c(78) : error C2065: 'arr2' : undeclared identifier
z.c(78) : error C2109: subscript requires array or pointer type
z.c(78) : error C2065: 'float_size' : undeclared identifier
z.c(78) : warning C4022: 'push' : pointer mismatch for actual parameter 2
z.c(78) : error C2198: 'push' : too few arguments for call
最佳答案
这里
for (i=0; i<data_size; i++)
{
*(char *)(new_node->data + i) = *(char *)(new_data + i);
/* same code again, with ascii-art comment labels...*/
* (char *) ( new_node-> data + i )
/* ^deref cast (in pointed struct) pointer moving offset */
/* v v --- v v */
= * (char *) ( new_data + i );
}
我们有一个指向需要存储在新节点new_data
中的数据的指针,其类型为指向void的指针。
变量i
正在增加以覆盖范围0...data_size
-1。
因此,new_data + i
逐步指向内存位置,从数据指针开始,遍历存储在那里的所有数据。在对 i
求和时(即 (new_data + i)
),实际上将 void 的大小乘以 i
添加到 void 指针(而不是 char
的大小,我认为代码尝试过;幸运的是 char 和 void 的大小相同)。
求和的结果被转换为指向 char
的指针(即 (char *)
部分),并取消引用(即孤独的 *
),其效果是 =
的右侧正在逐个字符地访问输入数据。
= 的左侧类似,只是处理指向最近分配的内存的指针,用于存储数据(从结构体引用,但不包含在结构体中)。所分配的内存被输入数据指针引用的输入数据逐个字符地填充。
在这两种情况下,它都是“计算某些内容,强制将其理解为指向字符的指针,然后取消引用它”。
目标(能够在链表的节点中存储未知类型的任意数据)总是很困惑,并且任何避免这种丑陋的指针算术的方法可能会更加丑陋,因为具有误导性(例如使用数组实际上不是数组的语法...)。
关于c - 我正在复习 c 是为了我自己的启发。此代码用于示例链接列表。我不明白指针逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58806484/