Code Bye

额……链表读文件的过程中本人DEBUG发现地址总是有偏移(不对)

程序内容比较多,本人就捡本人这个问题相关的部分来发代码吧:
数据结构非常简单:
typedef struct Node{
 int num;
 struct Node *next;
}

有一个文本文件,里面装满了随机数,用空格或什么的分隔每一个数,这个本人不管怎么分,总之每次fscanf的都是一个int值就对了。
本人最开始的append是每次都遍历一次链表,好把文件中新增的结构放在表的最后。思路是这样的:

对应的代码如下:

/*追加节点*/
int append(NODE *HEAD,int num) {
	if (!HEAD || num < 0) {
		return 0;
	}
	/*设置cur = HEAD*/
	NODE *cur = HEAD;
	/*cur一直遍历到最后*/
	while (cur->next) {
		cur = cur->next;
	}
	/*设置一个temp保存数据*/
	NODE *temp = create_empty();
	set_num(temp,num);
	/*将cur的next指向temp*/
	cur->next = temp;
	return 1;
}

其实问题就已经解决了
但是本人发现假如读取超过100万个内容的时候就开始成几何级的费时间了(其实超过10万个数就已经超过2秒了)。
于是本人就想到每次直接在链表尾部增加不久好了么?于是就有了这个思路:

测试用的文件里面只有两个数,分别是7875和17912
满怀信心的F5,结果发现只输出17912……可是应该从head开始的话应该先有7875才对。
实现的代码还有相应做测试的main函数就一并都发来了:

void file_append(NODE *node,int num) {
	if (!node) {
		return;
	}
	printf("\nbefore_node addr:0x%p\n",&node);
	NODE *temp = create_empty();
	temp->num = num;
	node->next = temp;
	/*这样应该保证每次node都是最后一个节点?*/
	node = node->next;
	printf("\n temp addr:0x%p\n node addr:0x%p\n", &temp,&node);
}
int file_input(NODE *HEAD,const char *filename) {
	if (!HEAD) {
		return 0;
	}
	NODE *tail = HEAD;
	while (tail->next) {
		tail = tail->next;
	}
	/*这样一来,tail最终指向了最后一个节点*/
	FILE *fp = fopen(filename, "r");
	if (!fp) {
		return 0;
	}
	while (!feof(fp)) {
		int temp;
		fscanf(fp, "%d", &temp);
		printf("\n===============%d=================\n",temp);
		file_append(tail, temp);
		printf("\nnode(tail) addr:0x%p\n", &tail);
		printf("\n====================================\n");
	}
	fclose(fp);
	return 1;
}
int main(int argc,char *argv[]) {
	if (argc < 2) {
		printf("请指明文件名\n");
		getchar();
		return 1;
	}
	NODE *head = create_empty();
	clock_t start, end;
	start = clock();
	if(!file_input(head, argv[1])){
		printf("文件不存在!\n");
		getchar();
		return 2;
	}
	end = clock();
	printf("文件加载完毕!共耗时%d毫秒。\n",end - start);
	print_chaintab(head);
	getchar();
	remove_all_nodes(head);
	free(head);
	return 0;
}

运行结果如下:

结果发现每次node地址虽然变了,但都不是temp生成出来的……问一下这是怎么回事?本人的代码到底哪里出现了错误?是逻辑错误?还是本人单纯的不会写?

解决方案

20

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

20

void file_append(NODE **node,int num) {
    if (!*node) {
        return;
    }
    printf("\nbefore_node addr:0x%p\n",*node);
    NODE *temp = create_empty();
    temp->num = num;
    (*node)->next = temp;
    /*这样应该保证每次node都是最后一个节点?*/
    (*node) = temp;
    printf("\n temp addr:0x%p\n node addr:0x%p\n", *node);
}
//...
        file_append(&tail, temp);

5

引用:
Quote: 引用:
void file_append(NODE **node,int num) {
    if (!*node) {
        return;
    }
    printf("\nbefore_node addr:0x%p\n",*node);
    NODE *temp = create_empty();
    temp->num = num;
    (*node)->next = temp;
    /*这样应该保证每次node都是最后一个节点?*/
    (*node) = temp;
    printf("\n temp addr:0x%p\n node addr:0x%p\n", *node);
}
//...
        file_append(&tail, temp);

额……也就是说……假如……本人想将一个指针作为函数的参数,在函数执行后应用参数的变化,就在实现函数时声明一个指向该指针指针而不是获取该指针地址么?

每次都返回头指针,注意改一下函数的类型

5

引用:
Quote: 引用:

每次都返回头指针,注意改一下函数的类型

改函数类型?返回头指针……是这个意思么?

NODE *file_append(NODE **node,int num){
    /*............*/
    return (*node);
}

这样改么?问一下这样改的意义是什么?
……………………
迭代么?

不是这样,当然这样做也是可以,相似strcpy一样;可以通过返回值也可以通过传入传出参数实现返回。
这是两种方式来获取链表的头节点:一种是传二重指针进去,第二种就是传一重指针,但是返回值返回头节点地址;当然,还有第三种,就是两个都做,不过没必要。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明额……链表读文件的过程中本人DEBUG发现地址总是有偏移(不对)