gpt4 book ai didi

c - 使用指针仅打印列表的一些元素

转载 作者:行者123 更新时间:2023-11-30 16:18:47 24 4
gpt4 key购买 nike

创建一个接收两个列表(L1,L2)的函数,初始化L2,并将L1的元素插入L2中,不包括奇数位置的元素(假设列表的第一个元素位于位置0)。然后打印L2。

我的教授给了我们解决方案(如下),但我需要创建一个 main() 来调用这个函数并返回 L2,而且由于我是新手,似乎没有任何效果。

我尝试初始化 L1,然后调用该函数,但得到的只是大量错误。

这就是最终的函数:

struct list{
int value;
struct list * nextPtr;
};
void createSubList(struct list * l1Ptr, struct list ** l2PtrPtr) {
init(l2PtrPtr);
while(l1Ptr!=NULL) {
pre_insert(l2PtrPtr, l1Ptr­>value);
l1Ptr = l1Ptr­>nextPtr;
if (l1Ptr != NULL)
l1Ptr = l1Ptr­>nextPtr;
}
}

我希望在调用该函数后看到 L2 打印出来。这是我的最终文件:

#include <stdlib.h> 
#include <string.h>



struct list {
int value;
struct list *nextPtr;

};


void init( struct list **ptrptr){
*ptrptr!=NULL;

}
void prn (struct list * lptr) {
while (lptr) {
printf (" %d", lptr->value);
lptr = lptr->nextPtr;
}
putchar ('\n'); }
void pre_insert(struct list ** ptrptr, int value){
struct list * tmp_ptr;
tmp_ptr=*ptrptr;
*ptrptr=(struct list *)malloc(sizeof(struct list));
(*ptrptr)->value=value;
(*ptrptr)->nextPtr=tmp_ptr;
}

void createSubList(struct list* l1Ptr, struct list** l2PtrPtr) {
init(l2PtrPtr);
while(l1Ptr!=NULL) {
pre_insert(l2PtrPtr, l1Ptr->value);
l1Ptr = l1Ptr->nextPtr;
if (l1Ptr != NULL)
l1Ptr = l1Ptr->nextPtr;
}
prn(l1Ptr);
}



void main(){
struct list* l1Ptr;
init(&l1Ptr);
struct list* l2ptr;
init(&l2ptr);
pre_insert(&l1Ptr , 1);
pre_insert(&l1Ptr , 2);
pre_insert(&l1Ptr , 3);
pre_insert(&l1Ptr , 4);
pre_insert(&l1Ptr , 5);
pre_insert(&l1Ptr , 6);
createSubList(l1Ptr,&l2ptr);


}



我得到的错误:

[Finished in 0.1s with exit code -11]
[shell_cmd: gcc "/home/vittorio/Scrivania/CProjects/new.c" -o "/home/vittorio/Scrivania/CProjects/new" && "/home/vittorio/Scrivania/CProjects/new"]
[dir: /home/vittorio/Scrivania/CProjects]
[path: /home/vittorio/bin:/home/vittorio/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin]

最佳答案

一旦你得到非 ASCII 字符的平方。逐步实现您的实现。对于初学者来说,除非您使用的是不合格的系统,否则 main 的正确声明是int main (void)int main (int argc, char **argv) (您将看到用等效的 char *argv[] 编写的)。 注意: maintype int 的函数它返回一个值。请参阅:C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570) 。另请参阅:What should main() return in C and C++? .

因此,为了实现一致,main()没有参数应该是:

int main (void) {

struct list *l1Ptr = NULL;
struct list *l2ptr = NULL;
...

(注意:只需放弃 init() 函数,您不需要函数调用开销只是为了设置指针 NULL )

下一期是您的pre_insert必须区分将第一个节点添加到列表中和添加所有其他节点。对于第一个节点,只需设置 *ptrptr初始化tmp_ptr建立列表的头部。对于其余节点,您在设置 tmp_ptr->nextPtr = *ptrptr; 的位置使用链接使新节点中的下一个指针指向列表的旧起点,然后设置 *ptrptr = tmp_ptr;使其成为列表的新起点,例如

void pre_insert (struct list **ptrptr, int value)
{
struct list *tmp_ptr = malloc (sizeof *tmp_ptr); /* don't cast malloc */
if (tmp_ptr == NULL) { /* validate EVERY allocation */
perror ("malloc-tmp_ptr");
exit (EXIT_FAILURE);
}
tmp_ptr->value = value; /* initialize struct members */
tmp_ptr->nextPtr = NULL;

if (!*ptrptr) /* if 1st node, simply assign */
*ptrptr = tmp_ptr;
else {
tmp_ptr->nextPtr = *ptrptr; /* otherwise, set tmp->next to 1st */
*ptrptr = tmp_ptr; /* now set list to point to tmp */
}
}

您的createSubList有类似的冗余逻辑,表明你正在挣扎。您只需要一个简单的 1/0 切换即可从 list1 添加或跳过节点。例如:

void createSubList (struct list *l1Ptr, struct list **l2PtrPtr)
{
int i = 0;

while (l1Ptr != NULL) {
if (i == 0) { /* only store even nodes */
pre_insert (l2PtrPtr, l1Ptr->value);
i = 1;
}
else
i = 0;
l1Ptr = l1Ptr->nextPtr;
}
}

正如评论中所讨论的,您需要一种方法来打印列表,同样重要的是,一种方法来 free分配给完成处理的节点的内存。您只需要简单的功能即可,例如

void prnlist (struct list *lptr)
{
while (lptr) {
printf (" %d", lptr->value);
lptr = lptr->nextPtr;
}
putchar ('\n');
}

void freelist (struct list *lptr)
{
while (lptr) {
struct list *victim = lptr;
lptr = lptr->nextPtr;
free (victim);
}
}

(注意:您知道为什么必须保存指向当前节点的指针,然后在 free 上调用 victim 之前前进该节点吗?)

就是这样,除了我的附加评论。总而言之,你可以这样做:

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

struct list {
int value;
struct list *nextPtr;
};

void pre_insert (struct list **ptrptr, int value)
{
struct list *tmp_ptr = malloc (sizeof *tmp_ptr); /* don't cast malloc */
if (tmp_ptr == NULL) { /* validate EVERY allocation */
perror ("malloc-tmp_ptr");
exit (EXIT_FAILURE);
}
tmp_ptr->value = value; /* initialize struct members */
tmp_ptr->nextPtr = NULL;

if (!*ptrptr) /* if 1st node, simply assign */
*ptrptr = tmp_ptr;
else {
tmp_ptr->nextPtr = *ptrptr; /* otherwise, set tmp->next to 1st */
*ptrptr = tmp_ptr; /* now set list to point to tmp */
}
}

void createSubList (struct list *l1Ptr, struct list **l2PtrPtr)
{
int i = 0;

while (l1Ptr != NULL) {
if (i == 0) { /* only store even nodes */
pre_insert (l2PtrPtr, l1Ptr->value);
i = 1;
}
else
i = 0;
l1Ptr = l1Ptr->nextPtr;
}
}

void prnlist (struct list *lptr)
{
while (lptr) {
printf (" %d", lptr->value);
lptr = lptr->nextPtr;
}
putchar ('\n');
}

void freelist (struct list *lptr)
{
while (lptr) {
struct list *victim = lptr;
lptr = lptr->nextPtr;
free (victim);
}
}

int main (void) {

struct list *l1Ptr = NULL;
struct list *l2ptr = NULL;

for (int i = 1; i < 10; i++)
pre_insert (&l1Ptr , i);

createSubList (l1Ptr, &l2ptr);

prnlist (l2ptr); /* print list 2 */

freelist (l1Ptr); /* don't forget to free what you allocate */
freelist (l2ptr);
}

示例使用/输出

$ ./bin/llcreatesublist
1 3 5 7 9

内存使用/错误检查

在您编写的动态分配内存的任何代码中,对于分配的任何内存块,您都有两个责任:(1) 始终保留指向起始地址的指针内存块,因此,(2) 当不再需要它时可以释放

您必须使用内存错误检查程序来确保您不会尝试访问内存或在分配的 block 的范围之外进行写入,尝试读取或基于未初始化的值进行条件跳转,最后,以确认您释放了已分配的所有内存。

对于 Linux valgrind是正常的选择。每个平台都有类似的内存检查器。它们使用起来都很简单,只需通过它运行您的程序即可。

$ valgrind ./bin/llcreatesublist
==23324== Memcheck, a memory error detector
==23324== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==23324== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==23324== Command: ./bin/llcreatesublist
==23324==
1 3 5 7 9
==23324==
==23324== HEAP SUMMARY:
==23324== in use at exit: 0 bytes in 0 blocks
==23324== total heap usage: 14 allocs, 14 frees, 224 bytes allocated
==23324==
==23324== All heap blocks were freed -- no leaks are possible
==23324==
==23324== For counts of detected and suppressed errors, rerun with: -v
==23324== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认您已释放分配的所有内存并且不存在内存错误。

仔细检查一下,如果您还有其他问题,请告诉我。

关于c - 使用指针仅打印列表的一些元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55807499/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com