函数似乎 return 正确的值,但外部调用者永远不会在 C 中获取它
Function seems to return the correct value, but the outside caller never gets it in C
我使用链表实现了一个队列。我还创建了一个 getter 来读取此队列中任何条目的数据。当我从测试人员调用此函数时,我发现作为队列内条目值返回的值与在 getter 中读取的值不同。
struct entry{
double data;
attribute_value time_stamp;
struct entry* next;
};
typedef struct queue_struct{
struct entry* front;
struct entry* end;
int size;
} queue;
下面的getter接受队列的一个条目和returns数据结构变量的值,如果当前条目不为空:
double get_data(struct entry *current){
// The value is correct here
printf("!!!!!!!!!!!!! %lf\n", current->data);
if(current) return current->data;
return 0;
}
我使用这个助手来获取队列的第一个条目:
struct entry* get_front(queue *Q){
return Q->front;
}
测试人员来了。它创建一个队列(它简单地为其分配 space 并分配 first = NULL、end = NULL 和 size = 0)。然后它将值 10 推入队列。 (忽略零!它与数据没有任何关系)。然后,它通过从第一个元素开始并打印 "data" 变量直到遇到 NULL 元素来成功打印队列。然后,我要求它打印队列中第一个 entry/element 的数据。这是我得到错误值的地方。
void test_queue_push(bool enable_print){
printf(TESTING, "Testing push in queue.c");
queue* Q = construct_queue();
push(Q, 10, 0);
if(enable_print) print_queau(Q); // This prints the queue correctly!
// The wrong value is printed here!
printf("GET DATA: %lf\n", get_data(get_front(Q)));
}
此测试打印出以下内容:
10.000000 -> // This is result of print_queue
!!!!!!!!!!!!! 10.000000 // This is data of first entry printed INSIDE the getter function itself
GET DATA: 0.000000 // This is the returned data of first entry, printed inside the tester
我不明白为什么我没有得到第二行和第三行的值“10.0000”。
I just tried using "long long int" instead of "double" for the entry's data variable and all of the other functions. The error disappears if I use a different data type. No idea why.
打印队列也使用了get_data函数,打印出来的第一行反映了print_queue里面的get_data工作正常。这是函数:
void print_queau(queue* Q) {
struct entry* temp = get_front(Q);
while(temp != NULL) {
printf("%lf -> ", get_data(temp));
temp = get_next(temp);
}
printf("\n");
}
以防万一,推送函数如下所示:
void push(queue* Q, double input, attribute_value time_stamp){
if(Q){ //if Queue exists
struct entry* in; //create a new entry object
if(in = calloc(1, sizeof(struct entry))){ //if allocating space for the entry object succeeds
Q->size = Q->size + 1;
in->data = input; //enter the input as its current data
in->next = NULL; //set next to null because the end of the queue can have no next entry that follows it
in->time_stamp = time_stamp; //set the time stamp to the Power On Hours on the system
if(get_front(Q) == NULL && get_end(Q) == NULL){ //if front and end of the queue have not yet been set
set_front(Q, in); //then this entry is both the front
set_end(Q, in); //and the end
return;
}
set_next(get_end(Q), in); //next value of the entry at the end is now our new entry
set_end(Q, in);
//printf("The End is: %i\n", Q->size);
}
}
}
构造队列如下所示:
/*Constructor for the Queue structure instance
@param none
@return pointer to queue or NULL pointer in case of memory allocaion failure
*/
queue* construct_queue(){
queue* Q;
if(Q = calloc(1, sizeof(queue))){
Q->front = NULL; //at first the queue does not have any entries
Q->end = NULL; //therefore it has no front and no end
Q->size = 0; //its size starts off at zero to indicate that there are no entries.
}
if(Q == NULL){
fprintf(stderr, "Ran out of memory when allocating memory for queue in construct_queue in queue.c\n");
}
return Q;
}
我使用以下代码来构建上面的代码:https://gist.github.com/mycodeschool/7510222
有很多缺失的代码需要重建。这段代码仔细确保所有函数在使用前都已声明,似乎可以正常工作:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int attribute_value;
#define TESTING "%s\n"
struct entry
{
double data;
attribute_value time_stamp;
struct entry *next;
};
typedef struct queue_struct
{
struct entry *front;
struct entry *end;
int size;
} queue;
double get_data(struct entry *current);
queue *construct_queue(void);
struct entry *get_front(queue *Q);
struct entry *get_end(queue *Q);
void print_queau(queue *Q);
void push(queue *Q, double input, attribute_value time_stamp);
void test_queue_push(bool enable_print);
struct entry *get_next(struct entry *curr);
void set_front(queue *Q, struct entry *in);
void set_end(queue *Q, struct entry *in);
void set_next(struct entry *E, struct entry *in);
void set_front(queue *Q, struct entry *in)
{
if (Q != 0)
Q->front = in;
}
void set_end(queue *Q, struct entry *in)
{
if (Q != 0)
Q->end = in;
}
void set_next(struct entry *E, struct entry *in)
{
if (E != 0)
E->next = in;
}
struct entry *get_next(struct entry *curr)
{
if (curr != 0)
return curr->next;
return 0;
}
double get_data(struct entry *current)
{
if (current)
{
printf("!!!!!!!!!!!!! %lf\n", current->data);
return current->data;
}
return 0;
}
struct entry *get_end(queue *Q)
{
return Q->end;
}
struct entry *get_front(queue *Q)
{
return Q->front;
}
void test_queue_push(bool enable_print)
{
printf(TESTING, "Testing push in queue.c");
queue *Q = construct_queue();
push(Q, 10, 0);
if (enable_print)
print_queau(Q);
printf("GET DATA: %lf\n", get_data(get_front(Q)));
}
void print_queau(queue *Q)
{
struct entry *temp = get_front(Q);
while (temp != NULL)
{
printf("%lf -> ", get_data(temp));
temp = get_next(temp);
}
printf("\n");
}
void push(queue *Q, double input, attribute_value time_stamp)
{
if (Q)
{
struct entry *in;
if ((in = calloc(1, sizeof(struct entry))) != 0)
{
Q->size = Q->size + 1;
in->data = input;
in->next = NULL;
in->time_stamp = time_stamp;
if (get_front(Q) == NULL && get_end(Q) == NULL)
{
set_front(Q, in);
set_end(Q, in);
return;
}
set_next(get_end(Q), in);
set_end(Q, in);
}
}
}
queue *construct_queue(void)
{
queue *Q;
if ((Q = calloc(1, sizeof(queue))) != 0)
{
Q->front = NULL;
Q->end = NULL;
Q->size = 0;
}
if (Q == NULL)
{
fprintf(stderr, "Ran out of memory when allocating memory for queue in construct_queue in queue.c\n");
}
return Q;
}
int main(void)
{
test_queue_push(true);
return 0;
}
编译:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Werror queue.c -o queue
$
这是 Mac OS X 10.10.4 上的 GCC 5.1.0,选项设置繁琐且没有警告。 'prototypes' 选项确保函数在定义或使用之前被声明——或者是 static
函数。我这里什么都没做static
;我通常在只有一个源文件时这样做。
示例输出:
Testing push in queue.c
!!!!!!!!!!!!! 10.000000
10.000000 ->
!!!!!!!!!!!!! 10.000000
GET DATA: 10.000000
可以假设问题要么是缺少一个或多个函数原型,要么是其中一个函数存在错误。请注意,我修复了 get_data()
中的代码,因此如果 current
指针为 NULL,它不会崩溃 — 无论 current
是否为 NULL,您的代码都试图打印 current->data
中的值是否为 null(即使它随后检查了值 current
— 有点太晚了)。
我使用链表实现了一个队列。我还创建了一个 getter 来读取此队列中任何条目的数据。当我从测试人员调用此函数时,我发现作为队列内条目值返回的值与在 getter 中读取的值不同。
struct entry{
double data;
attribute_value time_stamp;
struct entry* next;
};
typedef struct queue_struct{
struct entry* front;
struct entry* end;
int size;
} queue;
下面的getter接受队列的一个条目和returns数据结构变量的值,如果当前条目不为空:
double get_data(struct entry *current){
// The value is correct here
printf("!!!!!!!!!!!!! %lf\n", current->data);
if(current) return current->data;
return 0;
}
我使用这个助手来获取队列的第一个条目:
struct entry* get_front(queue *Q){
return Q->front;
}
测试人员来了。它创建一个队列(它简单地为其分配 space 并分配 first = NULL、end = NULL 和 size = 0)。然后它将值 10 推入队列。 (忽略零!它与数据没有任何关系)。然后,它通过从第一个元素开始并打印 "data" 变量直到遇到 NULL 元素来成功打印队列。然后,我要求它打印队列中第一个 entry/element 的数据。这是我得到错误值的地方。
void test_queue_push(bool enable_print){
printf(TESTING, "Testing push in queue.c");
queue* Q = construct_queue();
push(Q, 10, 0);
if(enable_print) print_queau(Q); // This prints the queue correctly!
// The wrong value is printed here!
printf("GET DATA: %lf\n", get_data(get_front(Q)));
}
此测试打印出以下内容:
10.000000 -> // This is result of print_queue
!!!!!!!!!!!!! 10.000000 // This is data of first entry printed INSIDE the getter function itself
GET DATA: 0.000000 // This is the returned data of first entry, printed inside the tester
我不明白为什么我没有得到第二行和第三行的值“10.0000”。
I just tried using "long long int" instead of "double" for the entry's data variable and all of the other functions. The error disappears if I use a different data type. No idea why.
打印队列也使用了get_data函数,打印出来的第一行反映了print_queue里面的get_data工作正常。这是函数:
void print_queau(queue* Q) {
struct entry* temp = get_front(Q);
while(temp != NULL) {
printf("%lf -> ", get_data(temp));
temp = get_next(temp);
}
printf("\n");
}
以防万一,推送函数如下所示:
void push(queue* Q, double input, attribute_value time_stamp){
if(Q){ //if Queue exists
struct entry* in; //create a new entry object
if(in = calloc(1, sizeof(struct entry))){ //if allocating space for the entry object succeeds
Q->size = Q->size + 1;
in->data = input; //enter the input as its current data
in->next = NULL; //set next to null because the end of the queue can have no next entry that follows it
in->time_stamp = time_stamp; //set the time stamp to the Power On Hours on the system
if(get_front(Q) == NULL && get_end(Q) == NULL){ //if front and end of the queue have not yet been set
set_front(Q, in); //then this entry is both the front
set_end(Q, in); //and the end
return;
}
set_next(get_end(Q), in); //next value of the entry at the end is now our new entry
set_end(Q, in);
//printf("The End is: %i\n", Q->size);
}
}
}
构造队列如下所示:
/*Constructor for the Queue structure instance
@param none
@return pointer to queue or NULL pointer in case of memory allocaion failure
*/
queue* construct_queue(){
queue* Q;
if(Q = calloc(1, sizeof(queue))){
Q->front = NULL; //at first the queue does not have any entries
Q->end = NULL; //therefore it has no front and no end
Q->size = 0; //its size starts off at zero to indicate that there are no entries.
}
if(Q == NULL){
fprintf(stderr, "Ran out of memory when allocating memory for queue in construct_queue in queue.c\n");
}
return Q;
}
我使用以下代码来构建上面的代码:https://gist.github.com/mycodeschool/7510222
有很多缺失的代码需要重建。这段代码仔细确保所有函数在使用前都已声明,似乎可以正常工作:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int attribute_value;
#define TESTING "%s\n"
struct entry
{
double data;
attribute_value time_stamp;
struct entry *next;
};
typedef struct queue_struct
{
struct entry *front;
struct entry *end;
int size;
} queue;
double get_data(struct entry *current);
queue *construct_queue(void);
struct entry *get_front(queue *Q);
struct entry *get_end(queue *Q);
void print_queau(queue *Q);
void push(queue *Q, double input, attribute_value time_stamp);
void test_queue_push(bool enable_print);
struct entry *get_next(struct entry *curr);
void set_front(queue *Q, struct entry *in);
void set_end(queue *Q, struct entry *in);
void set_next(struct entry *E, struct entry *in);
void set_front(queue *Q, struct entry *in)
{
if (Q != 0)
Q->front = in;
}
void set_end(queue *Q, struct entry *in)
{
if (Q != 0)
Q->end = in;
}
void set_next(struct entry *E, struct entry *in)
{
if (E != 0)
E->next = in;
}
struct entry *get_next(struct entry *curr)
{
if (curr != 0)
return curr->next;
return 0;
}
double get_data(struct entry *current)
{
if (current)
{
printf("!!!!!!!!!!!!! %lf\n", current->data);
return current->data;
}
return 0;
}
struct entry *get_end(queue *Q)
{
return Q->end;
}
struct entry *get_front(queue *Q)
{
return Q->front;
}
void test_queue_push(bool enable_print)
{
printf(TESTING, "Testing push in queue.c");
queue *Q = construct_queue();
push(Q, 10, 0);
if (enable_print)
print_queau(Q);
printf("GET DATA: %lf\n", get_data(get_front(Q)));
}
void print_queau(queue *Q)
{
struct entry *temp = get_front(Q);
while (temp != NULL)
{
printf("%lf -> ", get_data(temp));
temp = get_next(temp);
}
printf("\n");
}
void push(queue *Q, double input, attribute_value time_stamp)
{
if (Q)
{
struct entry *in;
if ((in = calloc(1, sizeof(struct entry))) != 0)
{
Q->size = Q->size + 1;
in->data = input;
in->next = NULL;
in->time_stamp = time_stamp;
if (get_front(Q) == NULL && get_end(Q) == NULL)
{
set_front(Q, in);
set_end(Q, in);
return;
}
set_next(get_end(Q), in);
set_end(Q, in);
}
}
}
queue *construct_queue(void)
{
queue *Q;
if ((Q = calloc(1, sizeof(queue))) != 0)
{
Q->front = NULL;
Q->end = NULL;
Q->size = 0;
}
if (Q == NULL)
{
fprintf(stderr, "Ran out of memory when allocating memory for queue in construct_queue in queue.c\n");
}
return Q;
}
int main(void)
{
test_queue_push(true);
return 0;
}
编译:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Werror queue.c -o queue
$
这是 Mac OS X 10.10.4 上的 GCC 5.1.0,选项设置繁琐且没有警告。 'prototypes' 选项确保函数在定义或使用之前被声明——或者是 static
函数。我这里什么都没做static
;我通常在只有一个源文件时这样做。
示例输出:
Testing push in queue.c
!!!!!!!!!!!!! 10.000000
10.000000 ->
!!!!!!!!!!!!! 10.000000
GET DATA: 10.000000
可以假设问题要么是缺少一个或多个函数原型,要么是其中一个函数存在错误。请注意,我修复了 get_data()
中的代码,因此如果 current
指针为 NULL,它不会崩溃 — 无论 current
是否为 NULL,您的代码都试图打印 current->data
中的值是否为 null(即使它随后检查了值 current
— 有点太晚了)。