如何从主

时间:2015-10-01 18:25:02

标签: c function multidimensional-array

好吧,所以我确定这很简单,但我不知道如何使用功能。到目前为止,我能够完成所有主要内容,但现在我需要使用函数来处理我所做的任何事情。所以从下面的代码中,我如何从main中读取(或者说正确的术语是)函数?

编辑:为了向大家澄清,我的问题是如何访问我在main中返回的数组?

以下代码会记录用户输入指定的不同学生数量的测试分数。

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

int** getTestData();

int main (){

    ///this is where I'm lost..
    int (*a)[];
    a = getTestData();

}

int** getTestData(){
    int students, numberOfTests, testScores, i, j;
    int** testScoreBank;

    // reads in studens
    scanf("%i", &students);
    testScoreBank = (int**) malloc (sizeof(int)*students);

    for(i=0; i<students;i++){
        //how many number of tests there are
        scanf("%i", &numberOfTests);
        testScoreBank = (int*) malloc (sizeof(int)*numberOfTests);
        for(j=0; j<numberOfTests; j++){
            //the tests themselves
            scanf("%i", &testScores);
            testScoreBank[i][j] = testScores;
        }
    }
    return testScoreBank;
}

3 个答案:

答案 0 :(得分:1)

好的,这里有一个全局变量示例,如何在函数内填充数组,并在main()

中访问它
#include <stdio.h>
#include <stdlib.h>

int** getTestData();
int numberOfStudents;
int* studentTestSizes;

int main (){
  int** testScoresBank = getTestData();

  int i, j;

  for (i = 0; i < numberOfStudents; i++) {
    for (j = 0; j < studentTestSizes[i]; j++) {
      printf("%d", testScoresBank[i][j]);
    }
  }

  return 0;
}

int** getTestData() {
    int** testScoreBank;

    // reads in studens
    scanf("%d", &numberOfStudents);
    testScoreBank = malloc(sizeof(int*) * numberOfStudents);
    studentTestSizes = malloc(sizeof(int) * numberOfStudents);

    int i;
    for (i = 0; i < numberOfStudents; i++) {
        //how many number of tests there are
        scanf("%d", studentTestSizes + i);
        testScoreBank[i] = malloc(sizeof(int) * studentTestSizes[i]);

        int j;
        for (j = 0; j < studentTestSizes[i]; j++) {
            //the tests themselves
            int testScore;
            scanf("%d", &testScore);
            testScoreBank[i][j] = testScore;
        }
    }
    return testScoreBank;
}

全局变量的替代方法是使全局变量成为局部变量并将指针传递给getTestData函数,例如:

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

int** getTestData();

int main (){

  int numberOfStudents;   // those variables are now here
  int* studentTestSizes;

  int** testScoresBank = getTestData(&numberOfStudents, &studentTestSizes); // passing the pointers so we can change values that are pointed to

  int i, j;
  for (i = 0; i < numberOfStudents; i++) {
    for (j = 0; j < studentTestSizes[i]; j++) {
      printf("%d", testScoresBank[i][j]);
    }
  }

  return 0;
}

int** getTestData(int* numberOfStudentsPtr, int** studentTestSizesPtr) {
    int** testScoreBank;

    // reads in studens
    scanf("%d", numberOfStudentsPtr); // it's already a pointer so we must omit &
    int numberOfStudents = *numberOfStudentsPtr; // will be constant from now on

    testScoreBank = malloc(sizeof(int*) * numberOfStudents);

    *studentTestSizesPtr = malloc(sizeof(int) * numberOfStudents);
    int* studentTestSizes = *studentTestSizesPtr;

    int i;
    for (i = 0; i < numberOfStudents; i++) {
        //how many number of tests there are
        scanf("%d", studentTestSizes + i);
        testScoreBank[i] = malloc(sizeof(int) * studentTestSizes[i]);

        int j;
        for (j = 0; j < studentTestSizes[i]; j++) {
            //the tests themselves
            int testScore;
            scanf("%d", &testScore);
            testScoreBank[i][j] = testScore;
        }
    }
    return testScoreBank;
}

答案 1 :(得分:1)

除了其他答案之外,您还需要考虑一些微妙的问题。两个只是编写/调试开始应用程序的一般有用提示(1)如果您正在接受用户输入,提示它 - 您可以稍后删除提示,但是输入数据以响应信息提示要比它更容易是想知道闪烁光标在那里做了什么 - 程序冻结了吗? (2)在代码中提供足够的间距 - 您可以随时删除空白行,但将代码分离为逻辑功能块将有助于您保持逻辑正确。

为数值数组分配空间时,最好将所有值初始化为0作为分配的一部分(或之后)。这绝对可以防止无意间读取未初始化的空间。您可以使用calloc代替malloc一次分配和初始化所有内容。这也为将指针数组分配给char * 时提供了好处。

虽然您可能已经修复了分配,但仍然存在明确问题"How many students and tests do I have?"的问题。这里是传递学生数量的附加指针并将测试数量存储在附加数组索引中的地方。 (还有其他方法,这只是有效的)。您可以在main中声明将其指针传递给getTestData的学生人数。然后,主要提供getTestData中学生价值的更新。但是,"What if the students have a different number of scores? What then?"您已经填充了一个整数数组,如果您只是将学生的测试数存储为第一个整数,则无论您在哪里传递数组,都可以使该值可用。

最后,您需要密切关注您对变量types的选择。对于永远不会为负数的索引和长度,unsignedsize_t是更好的选择,并允许编译器指出您可能错误地使用该值的实例。

每次使用malloccalloc分配内存时,您需要验证,并且您有责任跟踪每个分配和释放开始时的地址它不再需要时。

也就是说,这是一种让它全部工作的方法。试试吧。如果您有任何问题,请与我联系:

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

int **getTestData (size_t *students);

int main (void) {

    int **a = NULL;
    int j;
    size_t i, s = 0;

    if (!(a = getTestData (&s))) {
        fprintf (stderr, "error: getTestData failed to return student data.\n");
        return 1;
    }

    /* print student data */
    putchar ('\n');
    for (i = 0; i < s; i++) 
    {
        printf (" Student[%2zu] scores : ", i+1);

        /* adjust indexes to read no. of tests */
        for (j = 1; j < a[i][0]; j++)
            printf (" %3d", a[i][j]);

        putchar ('\n');
    }
    putchar ('\n');

    /* free allocated memory */
    for (i = 0; i < s; i++)
        free (a[i]);
    free (a);

    return 0;
}

int **getTestData (size_t *students)
{
    size_t tests, testScores, s, t;
    int **testScoreBank;

    /* reads in students */
    printf ("\n No. of students: ");
    scanf ("%zu", students);
    if (!(testScoreBank = calloc (*students, sizeof *testScoreBank))) {
        fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
        return NULL;
    }

    for (s = 0; s < *students; s++) 
    {
        /* how many number of tests there are */
        printf ("\n No. of scores for student[%2zu]: ", s+1);
        scanf ("%zu", &tests);
        tests += 1;    /* allow space for number of tests as [s][0] */
        testScoreBank[s] = calloc (tests, sizeof **testScoreBank);
        testScoreBank[s][0] = tests;

        for (t = 1; t < tests; t++) 
        {
            /* the tests themselves */
            printf ("   student[%2zu]-test[%2zu] score: ", s+1, t);
            scanf ("%zu", &testScores);
            testScoreBank[s][t] = testScores;
        }
    }
    return testScoreBank;
}

使用/输出

$ ./bin/testdata

 No. of students: 2

 No. of scores for student[ 1]: 3
   student[ 1]-test[ 1] score: 88
   student[ 1]-test[ 2] score: 91
   student[ 1]-test[ 3] score: 82

 No. of scores for student[ 2]: 4
   student[ 2]-test[ 1] score: 93
   student[ 2]-test[ 2] score: 95
   student[ 2]-test[ 3] score: 96
   student[ 2]-test[ 4] score: 91

 Student[ 1] scores :   88  91  82
 Student[ 2] scores :   93  95  96  91

答案 2 :(得分:0)

(我认为这只是整个代码的一小部分,还有更多内容,否则您可能会遇到其他问题) 无论如何,您应该能够通过以下修改来设置2D阵列:

scanf("%i", &students);
testScoreBank = malloc (sizeof(int*)*students); //sizeof int* instead of sizeof int.

for(i=0; i<students;i++)
    {
    scanf("%i", &numberOfTests);
    *(testScoreBank + i)= malloc (sizeof(int)*numberOfTests); //You forgot the * operator on testScoreBank and to iterate through it.
    for(j=0; j<numberOfTests; j++)
        {
        scanf("%i", &testScores);
        testScoreBank[i][j] = testScores;
        }
    }