在C中返回没有指针的结构数组

时间:2021-07-09 15:57:47

I have been working my way through Kochan's "Programming in C" 3rd Edition on my own to get ready for grad school next year, and I am stuck for the first time. I am a chapter away from pointers, yet the exercise at the end of this most recent chapter on character strings has a problem that my own research seems to indicate can only be solved by using pointers.

我自己一直在通过Kochan的“C编程”第3版,为明年的研究生做好准备,我第一次陷入困境。我是一个远离指针的章节,但是最近关于字符串的章节末尾的练习有一个问题,我自己的研究似乎表明只能通过使用指针来解决。

The question has to do with a data structure entry:

问题与数据结构条目有关:

struct entry {
    char word[15];
    char definition[50];
};

We create an array of entries:

我们创建一个条目数组:

struct entry dictionary[10] = 
{{"aardvark", "a burrowing African mammal"},
 {"abyss", "a bottomless pit"},
 {"addle", "to become confused"},
 {"aerie", "a high nest"},
 {"ajar", "partially opened"},
 {"acumen", "mentally sharp; keen"},
 {"affix", "to append; attach"},
 {"agar", "a jelly made from seaweed"},
 {"ahoy", "a nautical call of greeting"},
 {"aigrette", "an ornamental cluster of feathers"}};

The prompt reads: "Write a function called dictionary_sort that sorts a dictionary, as defined [above], into alphabetical order."

提示符为:“编写一个名为dictionary_sort的函数,按照字母顺序对字典进行排序,如上所定义。”

I know there are subtleties to structures and arrays in relation to functions and how functions can take them as arguments or give them back as returned values. The only way that seemed to make sense to me was returning a struct, or specifically an array of structs, but I do not think I applying it correctly here:

我知道结构和数组与函数有关,以及函数如何将它们作为参数或作为返回值返回给它们有微妙之处。对我来说似乎有意义的唯一方法是返回一个结构,或者特别是一个结构数组,但我不认为我在这里正确应用它:

struct entry dictionary_sort(struct entry dictionary)

In total, my current version of the program is as follows:

总的来说,我目前的程序版本如下:

#include <stdio.h>
#include <stdbool.h>

struct entry {
    char word[15];
    char definition[50];
};

// Function to compare two character strings

int compare_strings(const char s1[], const char s2[])
{
    int i = 0, answer; 

    while (s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')
        i++;

    if (s1[i] < s2[i])
        answer = -1; // s1 < s2
    else if (s1[i] == s2[i])
        answer = 0; // s1 == s2
    else
        answer = 1; // s1 > s2

    return answer;
}

// Function to sort a dictionary structure

struct entry dictionary_sort(struct entry dictionary[])
{
    int dictionary_length = sizeof(dictionary) / sizeof(dictionary[0]);
    int i, j, minimum;
    struct entry temp;

    for (i = 0; i < dictionary_length; i++) {
        minimum = i;
        for (j = i + 1; j < dictionary_length; j++) {
            if (compare_strings(dictionary[j].word, 
                                dictionary[minimum].definition) == -1)
                minimum = j;
        }
        temp = dictionary[minimum];
        dictionary[minimum] = dictionary[i];
        dictionary[i] = dictionary[minimum];
    }

    return dictionary;
}

int main(void)
{
    struct entry dictionary[10] =
    {{"aardvark", "a burrowing African mammal"},
     {"abyss", "a bottomless pit"},
     {"addle", "to become confused"},
     {"aerie", "a high nest"},
     {"ajar", "partially opened"},
     {"acumen", "mentally sharp; keen"},
     {"affix", "to append; attach"},
     {"agar", "a jelly made from seaweed"},
     {"ahoy", "a nautical call of greeting"},
     {"aigrette", "an ornamental cluster of feathers"}};
    int i, dictionary_length = sizeof(dictionary) / sizeof(dictionary[0]);

    dictionary = dictionary_sort(dictionary);

    for (i = 0; i < dictionary_length; i++)
        printf("%s - %s.\n", dictionary[i].word, dictionary[i].definition);

    return 0;
}

The string comparison function behaves as expected since it is only returning an integer. I am really at a loss as to how to have the desired functionality without knowledge of pointers. There are enough examples with pointers to look up, but I am curious what fundamental principle I am missing here because I feel as though everything else in the book has come very naturally to me.

字符串比较函数的行为与预期的一样,因为它只返回一个整数。我真的不知道如何在不知道指针的情况下获得所需的功能。有足够的例子可以查找指针,但我很好奇我在这里缺少什么基本原则,因为我觉得书中的其他内容对我来说非常自然。

Thank you in advance!

先感谢您!

4 个解决方案

#1


4  

You do not have to return anything at all, you don't even need explicit pointers, none of that. Sort in-place, and don't reinvent the wheel: use strcmp() and qsort() (live demo here):

您根本不需要返回任何内容,甚至不需要显式指针。就地排序,不要重新发明*:使用strcmp()和qsort()(这里的现场演示):

struct entry dictionary[] = {
    { "def", "second entry" },
    { "abc", "first entry" },
    { "ghi", "third entry" },
    { "mno", "fifth entry" },
    { "jkl", "fourth entry" }
};

int compare_entry(const void *l, const void *r)
{
    const struct entry *ll = l;
    const struct entry *rr = r;
    return strcmp(ll->word, rr->word);
}

#define COUNT(x) (sizeof(x) / sizeof(x[0]))

qsort(dictionary, COUNT(dictionary), sizeof(dictionary[0]), compare_entry);

#2


1  

While not perfect and still requiring the explicit definition of pointers, this answer is within the scope of the problem and the book by not just calling libraries.

虽然不完美并且仍然需要指针的明确定义,但这个答案在问题和本书的范围内不仅仅是调用库。

#include <stdio.h>
#include <stdbool.h>

struct entry {
    char word[15];
    char definition[50];
};

// Function to compare two character strings

int compare_strings(const char s1[], const char s2[])
{
    int i = 0, answer; 

    while (s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')
        i++;

    if (s1[i] < s2[i])
        answer = -1; // s1 < s2
    else if (s1[i] == s2[i])
        answer = 0; // s1 == s2
    else
        answer = 1; // s1 > s2

    return answer;
}

// Function to sort a dictionary structure

void dictionary_sort(struct entry *dictionary, int dictionary_length)
{
    int i, j, minimum;
    struct entry temp;

    for (i = 0; i < dictionary_length - 1; i++) {
        minimum = i;
        for (j = i + 1; j < dictionary_length; j++) {
            if (compare_strings(dictionary[j].word, 
                                dictionary[minimum].word) == -1)
                minimum = j;
        }
        temp = dictionary[minimum];
        dictionary[minimum] = dictionary[i];
        dictionary[i] = temp;
    }
}

// Prints the dictionary in its current state

void print_dictionary(struct entry *dictionary, int dictionary_length)
{
    int i;

    for (i = 0; i < dictionary_length; i++) {
        printf("%s - %s.\n", dictionary[i].word, dictionary[i].definition);
    }
}

// Demostrates the dictionary_sort function

int main(void)
{
    struct entry dictionary[10] =
    {{"aardvark", "a burrowing African mammal"},
     {"abyss", "a bottomless pit"},
     {"addle", "to become confused"},
     {"aerie", "a high nest"},
     {"ajar", "partially opened"},
     {"acumen", "mentally sharp; keen"},
     {"affix", "to append; attach"},
     {"agar", "a jelly made from seaweed"},
     {"ahoy", "a nautical call of greeting"},
     {"aigrette", "an ornamental cluster of feathers"}};

    int i, dictionary_length = sizeof(dictionary) / sizeof(dictionary[0]);

    print_dictionary(&dictionary, dictionary_length);
    printf("\nSorting...\n\n");
    dictionary_sort(&dictionary, dictionary_length);
    print_dictionary(&dictionary, dictionary_length);
    printf("\n");

    return 0;
}

#3


0  

When you declare a function parameter with [], you already use pointers. The function definition

使用[]声明函数参数时,您已经使用了指针。功能定义

int compare_strings(const char s1[], const char s2[])

is functionally the same as

在功能上是相同的

int compare_strings(const char *s1, const char *s2)

Same with struct entry dictionary_sort(struct entry dictionary[]).

与struct entry dictionary_sort(struct entry dictionary [])相同。

Since you get a pointer to struct entry as parameter dictionary, return dictionary returns a pointer to struct entry as well.

由于您获得了一个指向struct entry作为参数字典的指针,因此返回字典也返回一个指向struct条目的指针。

And all changes you make to dictionary are already visible outside, because you modify the array itself and not some local array.

您对字典所做的所有更改都已在外部可见,因为您修改了数组本身而不是某些本地数组。

#4


0  

A statement like "Returning an array of structs without pointers in C" is a paradox in C because the only way to pass or return an array in C is through pointers.Even though it may seem that in something like char *foo(char arr_demo[]){} an array is being passed, essentially it's a pointer being passed as it reduces to char *foo(char *arr_demo){}.

像“在C中返回没有指针的结构数组”这样的语句在C中是一个悖论,因为在C中传递或返回数组的唯一方法是通过指针。即使它看起来像char * foo(char arr_demo) []){}正在传递一个数组,基本上它是一个传递的指针,因为它减少为char * foo(char * arr_demo){}。

#1


4  

You do not have to return anything at all, you don't even need explicit pointers, none of that. Sort in-place, and don't reinvent the wheel: use strcmp() and qsort() (live demo here):

您根本不需要返回任何内容,甚至不需要显式指针。就地排序,不要重新发明*:使用strcmp()和qsort()(这里的现场演示):

struct entry dictionary[] = {
    { "def", "second entry" },
    { "abc", "first entry" },
    { "ghi", "third entry" },
    { "mno", "fifth entry" },
    { "jkl", "fourth entry" }
};

int compare_entry(const void *l, const void *r)
{
    const struct entry *ll = l;
    const struct entry *rr = r;
    return strcmp(ll->word, rr->word);
}

#define COUNT(x) (sizeof(x) / sizeof(x[0]))

qsort(dictionary, COUNT(dictionary), sizeof(dictionary[0]), compare_entry);

#2


1  

While not perfect and still requiring the explicit definition of pointers, this answer is within the scope of the problem and the book by not just calling libraries.

虽然不完美并且仍然需要指针的明确定义,但这个答案在问题和本书的范围内不仅仅是调用库。

#include <stdio.h>
#include <stdbool.h>

struct entry {
    char word[15];
    char definition[50];
};

// Function to compare two character strings

int compare_strings(const char s1[], const char s2[])
{
    int i = 0, answer; 

    while (s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')
        i++;

    if (s1[i] < s2[i])
        answer = -1; // s1 < s2
    else if (s1[i] == s2[i])
        answer = 0; // s1 == s2
    else
        answer = 1; // s1 > s2

    return answer;
}

// Function to sort a dictionary structure

void dictionary_sort(struct entry *dictionary, int dictionary_length)
{
    int i, j, minimum;
    struct entry temp;

    for (i = 0; i < dictionary_length - 1; i++) {
        minimum = i;
        for (j = i + 1; j < dictionary_length; j++) {
            if (compare_strings(dictionary[j].word, 
                                dictionary[minimum].word) == -1)
                minimum = j;
        }
        temp = dictionary[minimum];
        dictionary[minimum] = dictionary[i];
        dictionary[i] = temp;
    }
}

// Prints the dictionary in its current state

void print_dictionary(struct entry *dictionary, int dictionary_length)
{
    int i;

    for (i = 0; i < dictionary_length; i++) {
        printf("%s - %s.\n", dictionary[i].word, dictionary[i].definition);
    }
}

// Demostrates the dictionary_sort function

int main(void)
{
    struct entry dictionary[10] =
    {{"aardvark", "a burrowing African mammal"},
     {"abyss", "a bottomless pit"},
     {"addle", "to become confused"},
     {"aerie", "a high nest"},
     {"ajar", "partially opened"},
     {"acumen", "mentally sharp; keen"},
     {"affix", "to append; attach"},
     {"agar", "a jelly made from seaweed"},
     {"ahoy", "a nautical call of greeting"},
     {"aigrette", "an ornamental cluster of feathers"}};

    int i, dictionary_length = sizeof(dictionary) / sizeof(dictionary[0]);

    print_dictionary(&dictionary, dictionary_length);
    printf("\nSorting...\n\n");
    dictionary_sort(&dictionary, dictionary_length);
    print_dictionary(&dictionary, dictionary_length);
    printf("\n");

    return 0;
}

#3


0  

When you declare a function parameter with [], you already use pointers. The function definition

使用[]声明函数参数时,您已经使用了指针。功能定义

int compare_strings(const char s1[], const char s2[])

is functionally the same as

在功能上是相同的

int compare_strings(const char *s1, const char *s2)

Same with struct entry dictionary_sort(struct entry dictionary[]).

与struct entry dictionary_sort(struct entry dictionary [])相同。

Since you get a pointer to struct entry as parameter dictionary, return dictionary returns a pointer to struct entry as well.

由于您获得了一个指向struct entry作为参数字典的指针,因此返回字典也返回一个指向struct条目的指针。

And all changes you make to dictionary are already visible outside, because you modify the array itself and not some local array.

您对字典所做的所有更改都已在外部可见,因为您修改了数组本身而不是某些本地数组。

#4


0  

A statement like "Returning an array of structs without pointers in C" is a paradox in C because the only way to pass or return an array in C is through pointers.Even though it may seem that in something like char *foo(char arr_demo[]){} an array is being passed, essentially it's a pointer being passed as it reduces to char *foo(char *arr_demo){}.

像“在C中返回没有指针的结构数组”这样的语句在C中是一个悖论,因为在C中传递或返回数组的唯一方法是通过指针。即使它看起来像char * foo(char arr_demo) []){}正在传递一个数组,基本上它是一个传递的指针,因为它减少为char * foo(char * arr_demo){}。