将数组作为参数传递的问题

时间:2016-04-22 03:32:02

标签: c arrays

我是C的新手程序员,我遇到了一个几乎非常简单的问题。我正在编写一个基本程序,它创建两个数组,一个学生名和一个学生ID号,然后对它们进行排序并以各种方式打印它们,最后允许用户按ID号搜索数组。这是代码:

#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32

int main()
{   
    // Student info arrays
    char NAME[ARRAY_SIZE][MAX_NAME_LENGTH];
    int ID[ARRAY_SIZE];

    // Array for student IDs, shifted twice to the right
    int shiftedID[ARRAY_SIZE];

    // Boolean value to keep while loop running and
    // the ID search prompt repeating
    int loop = 1;

    // Counter variable for the for loop   
    int counter;
    // Gets input values for the student info arrays
    for (counter = 0; counter < ARRAY_SIZE; counter++)
    {   
        printf("Input student name: ");
        scanf("%s", NAME[counter]);

        printf("Input student ID: ");
        scanf("%d", &ID[counter]);
    }

    // Sorts the arrays
    sort(NAME, ID);

    // Prints the arrays
    print_array(&NAME, ID);

    // Shifts the ID value two bits to the right
    shiftright(ID, shiftedID);

    print_array(NAME, shiftedID);

    // Repeatedely prompts the user for an ID to
    // search for
    while(loop == 1)
    {
        search_id(NAME, ID);
    }
}

以下是函数定义:

#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32
// Sorts the two arrays by student ID. (Bubble sort)
void sort(char **nameArray, int idArray[])
{   

    // Counter variables for the for loop
    int firstCounter = 0;
    int secondCounter = 0;
    for(firstCounter = 0; firstCounter < ARRAY_SIZE; firstCounter++)
    {
        for(secondCounter = 0; secondCounter < ARRAY_SIZE - 1;   
                secondCounter++)
        {
            if(idArray[secondCounter] > idArray[secondCounter + 1])
            {

                // Temporary variables for the sort algorithm
                int tempInt = 0;
                char tempName[32];

                tempInt = idArray[secondCounter + 1];
                idArray[secondCounter + 1] = idArray[secondCounter];
                idArray[secondCounter] = tempInt;

                strcpy(tempName, nameArray[secondCounter + 1]);
                strcpy(nameArray[secondCounter + 1],   
                      nameArray[secondCounter]);
                strcpy(nameArray[secondCounter], tempName);
            }
        }
    }
}
// Searches the ID array for a user input student
// ID and prints the corresponding student's info.
void search_id(char **nameArray, int idArray[])
{
    // A boolean value representing whether or not
    // the input ID value was found
    int isFound = 0;

    // The input ID the user is searching for
    int searchID = 0;

    printf("Input student ID to search for: ");
    scanf("%d", &searchID);

    // Counter variable for the for loop
    int counter = 0;
    while (counter < ARRAY_SIZE && isFound == 0)
    {
        counter++;
        if (idArray[counter] == searchID)
        {
            // Prints the name associated with the input ID
            isFound = 1; 
            printf("%s", nameArray[counter]);
        }
    }

    // If the input ID is not found, prints a failure message.
    if (isFound == 0)
    {
        printf("ID not found.\n");
    }
}

// Prints the name and ID of each student.
void print_array(char **nameArray, int idArray[])
{   
    // Counter variable for the for loop
    int counter = 0;

    printf("Student Name & Student ID: \n");
    for (counter = 0; counter < ARRAY_SIZE; counter++)
    {   
        printf("%s --- %d\n", nameArray[counter], idArray[counter]);
    }
} 

// Shifts the ID value to the right by two bits
void shiftright(int idArray[], int shiftedID[])
{
    // Counter variable for the for loop
    int counter = 0;
    for (counter = 0; counter < ARRAY_SIZE; counter++)
    {
        shiftedID[counter] = idArray[counter] >> 2;
    }
}

我知道这个程序本质上是相当基础的,而且最重要的是让我更精通C语言的练习。我已经研究了一段时间了,并且已经工作了通过几个问题,但似乎坚持三个问题:

  1. 如果输入的ID号没有按顺序输入,则会产生分段错误。如果ID编号已经按顺序输入,则sort函数永远不会通过if语句,也不会出现问题。

  2. 将名称/ ID数组传递给print_array函数时,ID打印得很好,但名称将打印为完全空白或一系列奇怪的字符。

  3. 在程序结束时按ID搜索时,首先输入的ID号(因此,ID [0]中的数字)显示ID not found消息,其中索引为1或更大的所有数字将正常工作 - 除了应打印的相应名称打印为空白,如第二期中所述。

  4. 我将非常感谢您能得到的任何建议!我发现C中所需的精细细节背后的力量既非常有趣,又非常令人困惑,令人生畏,这意味着我能得到的任何帮助都会产生很大的不同。

2 个答案:

答案 0 :(得分:5)

问题在于您假设char [ARRAY_SIZE][MAX_NAME_LENGTH]char **可以互换

void sort(char **nameArray, int idArray[])

应该是

void sort(char nameArray[][MAX_NAME_LENGTH], int idArray[])

void sort(char (*nameArray)[MAX_NAME_LENGTH], int idArray[])

为了使用指向MAX_NAME_LENGTH char s数组的指针,对search_id函数使用相同的指针。

看看question 6.13 of C-FAQ

答案 1 :(得分:2)

我建议你重组你的程序。您可以存储一个包含所有必要数据的结构数组,而不是为名称和ID存储两个独立的数组:

typedef struct student
{
    int id;
    char name[MAX_NAME_LENGTH];
} student_t;

student_t students[ARRAY_SIZE];

现在你有一个单独的数组,通过排序没有名称等的ID,永远不会“不匹配”。

您可以使用标准库函数qsort()中对数组进行排序:

qsort(students, ARRAY_SIZE, sizeof(student_t), comparator);

这需要你定义一个比较器,这很简单。一个例子是:

int comparator(const void *lhs, const void *rhs)
{
    const student_t *s1 = lhs, *s2 = rhs;
    return s1->id - s2->id;
}

您可以将同一个比较器与另一个标准库函数bsearch()一起使用,以便在排序后搜索学生数组:

student_t key = { 42 }; // name doesn't matter, search by ID
student_t* result = bsearch(&key, students, ARRAY_SIZE, sizeof(student_t), comparator);

这些标准函数比你的函数更有效,并且要求你编写更少的代码,错误的机会更少。