【问题标题】:printCat1(Cat* cat) Vs. printCat2(Cat cat) & More Pointers' QuestionsprintCat1(Cat* cat) 对比。 printCat2(Cat cat) 及更多指针问题
【发布时间】:2022-01-15 03:36:42
【问题描述】:

可能已经有人问过以下问题。另外,我知道有很多帖子讨论这个话题。但是,经过搜索,我找不到这些具体问题的答案。

注意:问题出现在代码下方。

代码:

#include <stdio.h>

#define ARRAY_SIZE 3

typedef struct
{
    const char* name;
    const char* color;
    int age;
}Cat;

void printCat1(Cat* cat)
{
    printf("\n%s\n", cat->name);
    printf("%s\n", cat->color);
    printf("%d\n", cat->age);
    printf("\n");
}

void printCat2(Cat cat)
{
    printf("\n%s\n", cat.name);
    printf("%s\n", cat.color);
    printf("%d\n", cat.age);
    printf("\n");
}

void printCatArray(Cat catArr[])
{
    int i = 0;
    for (i = 0; i < ARRAY_SIZE; i++)
    {
        //WHICH OPTION IS BETTER? (printCat1 OR printCat2)
        //CALLING TO PRINTING FUNCTION.
    }

}

void swap(_____ cat1, _____ cat2)
{
    Cat temp = //cat1 or *cat1 ?
    //cat1 = cat2 or *cat1 = *cat2?
    cat2 = temp;
}

void sortbyage(Cat catarr[])
{
    int i, j;
    for (i = 0; i < ARRAY_SIZE - 1; i++)
        for (j = 1; j < ARRAY_SIZE; j++)
            if (catarr[i].age > catarr[j].age)
                swap(______, ______]);
}
int main() {
    Cat catArray[ARRAY_SIZE] =
    { {"cat1", "white", 1},
      {"cat2", "black", 2},
      {"cat3", "gray", 3} };


    printCatArray(catArray);


    return 0;
}

问题:

1。打印单个 cat 结构数据的两个函数有什么区别?

2。哪种打印功能更好用,为什么?如果您愿意解释,这将是必不可少且有意义的。

3。写什么更好,为什么?无效交换(Cat cat1,Cat cat2)或无效交换(Cat* cat1,Cat* cat2)

4。从函数 soryByAge, swap(&catArr[i], &catArr[j]) 调用交换函数是否正确?你会写得不一样吗?

5。以下代码行是正确的: catArray[2] = catArray[1]; 很高兴了解它的实际作用。

如果有一个或多个问题不够清楚,我很乐意澄清。

非常感谢您!

【问题讨论】:

    标签: arrays c function pointers struct


    【解决方案1】:

    printCat1 使用指针,效率更高,因为它不会产生临时重复。

    printCat2 传递值,它复制了cat,效率较低。

    swap 函数必须使用指针。如果没有,它只会交换复制的值。原始数组将保持不变。

    void swap(Cat *cat1, Cat* cat2)
    {
        Cat temp = *cat1;
        *cat1 = *cat2;
        *cat2 = temp;
    }
    

    将参数传递给swap 时,使用变量的地址。例如,

    swap(&arr[i], &arr[j]);
    printCat1(&arr[i]);
    

    结构:

    typedef struct
    {
        const char* name;
        const char* color;
        int age;
    }Cat;
    
    ...
    Cat catArray[ARRAY_SIZE] =
    { {"cat1", "white", 1},
      {"cat2", "black", 2},
      {"cat3", "gray", 3} };
    

    您想将字符串声明为字符数组。

    typedef struct
    { char name[50]; char color[50]; int age; }Cat;
    

    或者声明为指针并动态分配。

    【讨论】:

    • 按值传递小结构实际上可能更快,尤其是结合内联。这大大简化了混叠分析,从而为优化提供了更多机会
    • @tstanisl 你的意思是编译器优化吗?在这种情况下,编译器应该为const参数找出优化方法
    • @BarmakShemirani 感谢您的回复!据我所知,如果我将数组传递给函数,那么我将能够更改其值,并且更改将保存在发送数组的函数中。如果是这样,为什么在这种情况下需要指向数组的指针?
    • 您没有将数组传递给交换函数。您正在传递数组的单个元素。对于这个元素具有固定长度的数组,您可以编写一个不同的交换函数来交换数组索引。用int arr[3] = {1,5,3};试试这个会更容易理解。
    • @BarmakShemirani 谢谢你的解释。您想解释以下行:catArray[2] = catArray[1]; 吗?
    【解决方案2】:
    1. 我不会将猫的名字和颜色声明为const。如果它们被定义为const,您将无法在运行时更改它,例如从用户那里获取它或使用您的数据库读取文件。

    2. foo(cat cats[])foo(cat *cats) 与数组作为指针传递完全相同。传递大小也很好,因为在现实生活中你不知道数组有多大。

    3. void swap(Cat cat1, Cat cat2)void swap(Cat* cat1, Cat* cat2) - 第一个将在结构的本地副本上工作。它不会影响原始数组。所以只有第二个版本会做一些有意义的事情。

    4. 这是正确的做法。您还可以交换来自不同数组的结构。您还可以为指针添加索引(如下例所示)

    5. 它将整个结构从索引1 复制到索引2 的结构中。之后,您将在索引 12 处拥有相同的元素

    typedef struct
    {
        char* name;
        char* color;
        int age;
    }Cat;
    
    void printCat1(const Cat* cat)
    {
        printf("\n%s\n", cat->name);
        printf("%s\n", cat->color);
        printf("%d\n", cat->age);
        printf("\n");
    }
    
    void printCat2(Cat cat)
    {
        printf("\n%s\n", cat.name);
        printf("%s\n", cat.color);
        printf("%d\n", cat.age);
        printf("\n");
    }
    
    void printCatArray(const Cat *catArr, size_t size)
    {
        for (size_t i = 0; i < size; i++)
        {
            printCat1(catArr + i);
            /* or */
            printCat2(catArr[i]);  // in this case the whole structure will passed to the function
        }
    
    }
    
    void swap(Cat *cat1, Cat *cat2)
    {
        Cat temp = *cat1;
        *cat1 = *cat2;
        *cat2 = temp;
    }
    
    void sortbyage(Cat *catarr, size_t size)
    {
        size_t i, j;
        for (i = 0; i < size - 1; i++)
            for (j = 1; j < size; j++)
                if (catarr[i].age > catarr[j].age)
                    swap(catarr + i, catarr + j);
    }
    int main() {
        Cat catArray[] =
        { {"cat1", "white", 1},
          {"cat2", "black", 2},
          {"cat3", "gray", 3} };
    
    
        printCatArray(catArray, sizeof(catArray) / sizeof(catArray[0]));
    }
    

    https://godbolt.org/z/xodsToqxa

    【讨论】:

    • 感谢您的回复!第三点,你写的不会影响原来的数组,但是我们传数组的时候,其实是传数组的地址。据我所知,如果我将数组传递给函数,那么我将能够更改其值,并且更改将保存在发送数组的函数中。如果是这样,为什么在这种情况下需要指向数组的指针?另外,关于你提到的第五点,第二个节点的地址(从零开始)被复制到第三个节点,那么第三个和第二个节点会指向同一个地址吗?
    猜你喜欢
    • 1970-01-01
    • 2017-08-08
    • 2015-09-15
    • 1970-01-01
    • 2011-05-30
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    相关资源
    最近更新 更多