C指针麻烦

时间:2012-10-05 16:48:47

标签: c sorting pointers struct

这是对这个问题的跟进:

sorting structs in C with pointers

我修改了修改后的代码,我认为排序应该正常,但我觉得我没有正确使用指针。我的printf语句没有出现在控制台上,它们在注释中标出。

我是C的新手所以这可能是显而易见的但我只是在打印时不打印打印语句时如何调试。

当前的编译器警告:

Q1.c: In function 'generate':
Q1.c:28: warning: implicit declaration of function 'time'
Q1.c:35: warning: implicit declaration of function 'dupe'
Q1.c: In function 'output':
Q1.c:61: warning: implicit declaration of function 'sort'
Q1.c: At top level:
Q1.c:68: warning: conflicting types for 'sort'
Q1.c:61: warning: previous implicit declaration of 'sort' was here
Q1.c: In function 'sort':
Q1.c:82: warning: implicit declaration of function 'deallocate'
Q1.c: At top level:
Q1.c:90: warning: conflicting types for 'deallocate'
Q1.c:82: warning: previous implicit declaration of 'deallocate' was here

代码是:

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

int SIZE = 10;
static char c[] = "------------------------------\n";

struct student{
    int id;
    int score;
};

struct student* allocate(){
     /*Allocate memory for ten students*/
     struct student *s = malloc(SIZE* sizeof*s);
     /*return the pointer*/
     return s;
}

void generate(struct student* students){
    /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/
    srand((unsigned int)time(NULL));
    int id[SIZE];
    int y;

    for (int i = 0; i < SIZE; i++){
        do{
        y = rand() % SIZE + 1;
        } while(dupe(id, i, y));
        id[i] = y;
    }

    for (int j = 0; j < SIZE; j++){
        students[j].id = id[j];
        students[j].score = rand() % 101;
        printf("ID: %d\tScore: %d\n", students[j].id, students[j].score);
    }
}

int dupe(int id[], int SIZE1, int i){
    for (int x = 0; x < SIZE1; x++){
        if(id[x] == i)
            return 1;
    }
    return 0;
}

void output(struct student* students){
     /*Output information about the ten students in the format:
              ID1 Score1
              ID2 score2
              ID3 score3
              ...
              ID10 score10*/
    sort(students);
    printf("post sort students.\n %s", c);
    for(int x = 0; x < SIZE; x++){
        printf("ID: %d\tScore: %d\n", students[x].id, students[x].score); //print stmt not showing
    }
}

void sort(struct student* students){
    struct student *sd = allocate();

    struct student *stud;

    for(int i = 0; i < SIZE; i++){
        stud = &students[i];
        sd[stud->id -1] = *stud;
    }
    printf("sorted SD.\n %s", c);
    for(int x = 0; x < SIZE; x++){
        printf("ID: %d\tScore: %d\n", sd[x].id, sd[x].score); //print stmt not showing
    }
    students = sd;
    deallocate(sd);
}

void summary(struct student* students){
     /*Compute and print the minimum, maximum and average scores of the ten students*/

}

void deallocate(struct student* stud){
     /*Deallocate memory from stud*/
    free(stud);
}

int main(){
    struct student* stud = NULL;
    /*call allocate*/
    stud = allocate();
    /*call generate*/
    generate(stud);
    /*call output*/
    printf("%s", c);
    output(stud);
    /*call summary*/

    /*call deallocate*/
    deallocate(stud);

    return 0;
}

2 个答案:

答案 0 :(得分:10)

“我的printf语句没有显示在控制台上”

你确定你的程序在到目前为止没有崩溃吗?

由于stud的类型为student*&stud的类型为student**,但您将其传递给期望student*的函数...只需传递{ {1}},而不是stud。打开编译器中的警告,它会告诉你这些事情。

&stud

这是不正确的做法。 assert(s != 0); 只应用于测试逻辑错误,而不是用于正常故障情况,例如内存不足。

assert

这没关系,但我建议

struct student *s = malloc(size*(sizeof(struct student)));

因为它不那么冗长,也不依赖于类型。

struct student* s = malloc(size * sizeof *s);

在C中,这不是常量(并且不会通过添加static int size = 10; 关键字而成为常量)。由于您将其用作本地数组的大小,因此您正在调用所有C编译器中都不可用的VLA(可变长度数组)功能。在C中,执行

更为正常
const

#define SIZE 10

这会给你带来麻烦:

enum { SIZE = 10 };

(除了应该说“1和SIZE”这一事实)。您分配一个SIZE元素数组,然后使用您的学生ID作为索引,但只有0..SIZE-1是有效索引... SIZE不是。因此,您需要按ID being between 1 and 10 进行索引,或者将您的ID设为0索引。

student->id - 1

可以写成

    y = rand() % size + 1;
    while(dupe(id, i, y)){
        y = rand() % size + 1;
    }

但是,我认为这不符合您的要求。您确定学生ID与索引不同,但没有理由这样做。您要保证的是,没有两个学生ID是相同的,但您没有这样做。一种可能性是扫描所有先前分配的ID,如果已经分配了ID,则选择另一个ID。另一种方法是将所有ID,1 .. SIZE放在一个数组中,然后随机将数据从数组中拉出,将数组的顶部元素移动到该插槽中,并将数组的大小减小1,直到你'已清空阵列并分配了所有ID。

do
{
    y = rand() % size + 1;
} while(dupe(id, i, y));

C有一些等效规则:(students + j)->id === *(x + y)x[y] === x->y。所以,(*x).y === (students + j)->id === (*(students + j)).id,这是写它的首选方式。

students[j].id

此语句不执行任何操作,因为students = &sd; 之后未使用它,并且它是类型错误(students具有类型&sd),再次,您的编译器将警告你,如果你打开警告(-Wall for gcc)。

你在这里要做的是改变来电者的学生,但这不是那样做的。您需要传递学生的地址(即,有一个student**参数然后取消引用以获取struct student** pstudents),或者更好地students新数组(必须在您完成使用之前取消分配。)

这个问题清单并不一定详尽无遗。

答案 1 :(得分:0)

我将指出我在程序中可以找到的有关指针使用的几个错误,

main内,

您应该将generate()output()称为

generate(stud);
output(stud);

sort

students = &sd;应为students = sd;

output

sort(&students);应为sort(students);