我在C中编写程序。程序接收从标准输入到包含数据的文件的文件路径。然后根据数据构建链表。链表必须是循环的,但为了简单起见(用于添加节点,打印列表)我将循环列表转换为常规的非循环链表。这是通过uncirc
函数完成的。最后,我使用circ
函数将列表组装回循环结构。
我将指向链表的指针传递给函数printList
,该函数打印列表的内容。但是,在uncirc
内部使用printList
后,列表实际上仍然是" unirc" -ed甚至是主要内容。据我所知,指针是按值传递的,因此对printList
中的列表执行任何操作都不应影响原始列表。
代码如下(我只包含与问题相关的基本功能,否则代码会非常大)。我怀疑有一些你是否可以说我可以轻松打印列表,即使是圆形结构,但真正困扰我的是原始列表是从指针改变。
#include <stdio.h>
#include <stdlib.h>
#define MAX_FILE_NAME_LEN 300
#define MAX_LINE_LEN 300
#define MATERIAL_LEN 100
#define FIELDS_IN_LIGHTING_NUM 8
enum l_type {
TABLE = 1, WALL, CEILING
};
typedef struct Lighting {
enum l_type type;
int length;
int width;
int height;
int bulbs;
char material[MATERIAL_LEN];
int strength;
struct Lighting * next;
} Lighting;
char * getFileName();
int getVolume(Lighting * light);
Lighting * uncirc(Lighting * light);
Lighting * circ(Lighting *light);
void addNode(Lighting **head, FILE *fd);
void printNode(Lighting * light);
void printList(Lighting * light);
int countLines(FILE *fd);
void printMaxLight(Lighting * light);
int main() {
FILE * fd;
char * path;
Lighting * n1 = NULL;
int linesInFile, lightNum, i;
path = getFileName();
if(!(fd = fopen(path, "r+"))) {
printf("Cannot open file %s\n", path);
fprintf(stderr, "Cannot open file %s\n", path);
exit(0);
}
linesInFile = countLines(fd);
lightNum = linesInFile / 7;
for(i = 0; !(feof(fd)) && i < lightNum; i++) {
addNode(&n1, fd); //read file data and create node
//7 lines of data are required to create node
}
fclose(fd);
printList(n1); //print the linked list
return 0;
}
Lighting * uncirc(Lighting * light) {
Lighting * p = light;
if(p == NULL) {
return p;
}
while(p -> next != light) {
p = p -> next;
}
p -> next = NULL;
return light;
}
Lighting * circ(Lighting *light) {
Lighting * p = light;
if(p == NULL) {
return p;
}
while(p -> next != NULL) {
p = p -> next;
}
p -> next = light;
return light;
}
void printList(Lighting * light) {
Lighting * p;
p = uncirc(light);
if(p == NULL) {
printf("Empty list\n");
return;
}
while(p != NULL) {
printNode(p);
p = p -> next;
}
}
答案 0 :(得分:2)
指针中的列表不是包含。只有第一个元素的地址存在。而且你不是要在任何时候修改main中指针所包含的地址。
如果传递第一个元素的地址,然后使用它来遍历列表并修改元素,那么当你再次使用相同的地址进行遍历时,它将自然可见。
旁注
while(p -> next != light) {
如果您传递的列表不是循环的,那么这将是一个无限循环。
答案 1 :(得分:2)
是&#34; 指针按值传递&#34;但指针指向的任何东西都是不&#34;通过值&#34;传递。也就是说,列表本身不会被复制。
因此,如果更改函数中指向的列表,则只会更改列表!