0

The following questions might have been asked already. In addition, I am aware of the fact that there are a lot of posts that discuss the topic. However, after searching, I couldn't find answers to those specific questions.

Note: the questions appear under the code.

The code:

#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(Cat cat1, Cat cat2)
{
   Cat temp = cat1;
   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(catarr[i], catarr[j]);
}
int main() {
    Cat catArray[ARRAY_SIZE] =
                { {"cat1", "white", 1},
                  {"cat2", "black", 2},
                  {"cat3", "gray", 3} };

    printCatArray(catArray);
    

    return 0;
}

The questions:

  1. What is the difference between both functions that print the data of a single cat structure?
  2. Which printing function is better to use and why? it will be essential and meaningful if you would like to explain.
  3. What is better to write and why? void swap(Cat cat1, Cat cat2) OR void swap(Cat* cat1, Cat* cat2)
  4. Is the calling to swap function from the function soryByAge, swap(&catArr[i], &catArr[j]), correct? Would you write it differently?
  5. The following line of code is correct: catArray[2] = catArray[1]; It will be great to get an explanation about what it actually does.

Note: except swap's declaration, I am not allowed to change the other functions' declarations.

If one or more of the questions are not clear enough, I will be glad to clarify them.

Thank you very much beforehand!

Modern
  • 75
  • 2
  • 9
  • 3 & 4. Function `void swap(Cat cat1, Cat cat2)` only swaps the *copies* that were passed, so it has no effect on the caller's `struct`s. The compiler should be warning about the call `swap(&catArr[i], &catArr[j]);` which tries to pass the wrong type. The solution would be to change the function itself, not the call. – Weather Vane Nov 22 '21 at 19:43
  • To answer 1. and 2., compile and examine the assembly. – stark Nov 22 '21 at 19:46
  • All of the "better" questions are opinion based. In reality you won't find many libraries with functions that accept a struct as an argument or return a struct. Almost all of them use pointers. Mostly for compatibility reasons. – Cheatah Nov 22 '21 at 19:48
  • Although passing and returning `struct`s is legal, if they are large it can put a big performance overhead on copying them around behind the scenes. – Weather Vane Nov 22 '21 at 19:52
  • [Does C have references?](https://stackoverflow.com/questions/4305673/does-c-have-references) :-) – danadam Nov 22 '21 at 19:56
  • @WeatherVane You are right, the compiler did warn about the call. Sorry about the mistake, I edited the post. So, you suggest to change the declaration of the function swap? – Modern Nov 22 '21 at 19:56
  • And its implementation. `*cat2 = temp;` etc. – Weather Vane Nov 22 '21 at 19:57
  • @stark I know that in printCat1 function there is an access to the value it self and not to the copy of it, as happens in printCat2, but which option is better? It is something that you are unable to discover from compiling... – Modern Nov 22 '21 at 20:00
  • @Cheatah Thank you for replying. If you are asked what is better, what would you answer? – Modern Nov 22 '21 at 20:02
  • @WeatherVane Thank you for replying. If the following line: Cat temp = ______; is a given line and you can't change it, would you still continue to use the pointers? I understood from your comment that I must use them in order to change the values and not the copy of the values, is that right? – Modern Nov 22 '21 at 20:04
  • `void swap(Cat *cat1, Cat *cat2) { Cat temp = *cat1; *cat1 = *cat2; *cat2 = temp; }` – Weather Vane Nov 22 '21 at 20:06
  • @WeatherVane When you do the following Cat temp = *cat1, do you copy the address that cat1 points to temp? – Modern Nov 22 '21 at 20:16
  • @Modern no, *cat1 dereferences the pointer, so in fact this is comparable to `memcpy(&temp, cat1, sizeof temp);`, as in: it copies all of the bytes that *cat1 points to. It understands the size of that struct. – Cheatah Nov 22 '21 at 20:25
  • Better is subjective. There are cases where copying is better than using a pointer, and vice versa. – stark Nov 22 '21 at 20:31
  • @stark the question is discussing the case of printing. – Modern Nov 22 '21 at 20:36
  • @Cheatah But by adding the asterisk * (the pointer symbol) there is a dereference to the values that cat1 holds – Modern Nov 22 '21 at 20:39
  • In `void printCat2(Cat cat)` there is no *need* to pass a copy of the whole `struct` instead of a pointer in the other version. Even this small `struct` comprises two pointers: twice the amount of data to pass around than a single pointer to the `struct`. The performance difference here (if any) isn't significant, but for a large `struct` it can be. – Weather Vane Nov 22 '21 at 20:47
  • @WeatherVane I see. However, when it is all about printing, isn't there a "risk" that the real values can be changed? When sending a copy, then you don't have that "risk". – Modern Nov 22 '21 at 20:52
  • Not if you define it as `void printCat1(const Cat* cat)` – Weather Vane Nov 22 '21 at 21:07
  • @WeatherVane thanks again for replying. All the point is that I can't change the functions' declarations... As I posted, there are two functions that print. I can use only one of them, without changing them. Which one of them is better to use on this case. – Modern Nov 23 '21 at 13:26
  • As mentioned it doesn't matter much in the case of a small `struct`. It's a simple function and you *aren't* writing to it. – Weather Vane Nov 23 '21 at 18:12
  • @WeatherVane assume that the size of the struct doesn't matter. Which option is better? – Modern Nov 29 '21 at 12:45
  • Help is still needed. – Modern Dec 08 '21 at 12:52

0 Answers0