Struct Example

Given an example of Student which can be friend with other Student

typedef struct Student {
  char *name;
  int age;
  int friendCount;
  struct Student **friends;
  // struct Student *friends[20]; --- this is also ok
} Student;

Note: inside the struct we cannot use Typedef yet because it doesn't exist. Therefore we have to use struct Student.

We then can malloc this student friends by:

Student student = { "Austin", 5 };
student.friends = (Student**) malloc(sizeof(Student*) * 20);
student.friendCount = 0;

If using

struct Student *friends[20];

We don't even need to malloc since c already reserve the size for this array as of declaration. So:

Student student = { "Austin", 5 };
student.friendCount = 0;
#include <stdio.h>
#include <stdlib.h>

typedef struct Student {
  char *name;
  int age;
  int friendCount;
  struct Student **friends;
  /*struct Student *friends[20];*/
} Student;

void addFriend(Student *student, Student *friend);

int main(void) {

  Student student = { "Austin", 5 };
  student.friends = (Student**) malloc(sizeof(Student*) * 20);
  student.friendCount = 0;

  Student student2 = { "Test", 4 };
  Student student3 = { "Test 3", 5 };
  Student student4 = { "Test 4", 6 };
  addFriend(&student, &student2);

  printf("Student name: %s\nStudent age:%d. Student friend count: %d, \n", student.name, student.age, student.friendCount);

  printf("Student friend name before: %s\n", student.friends[0]->name);
  student2.name = "Test2";
  printf("Student friend name after: %s\n", student.friends[0]->name);

  addFriend(&student, &student3);

  printf("Student friend name before: %s\n", student.friends[1]->name);
  student3.name = "Test 3 name changed";
  printf("Student friend name after: %s\n", student.friends[1]->name);

  printf("Student friend count after: %d\n", student.friendCount);

  addFriend(&student, &student4);

  printf("Student friend count after: %d\n", student.friendCount);
  printf("Student friend name before: %s\n", student.friends[2]->name);
  student4.name = "Test 4 name changed";

  printf("Student friend name after: %s\n", student.friends[2]->name);
  return 0;
}


void addFriend(Student *student, Student *friend) {
  student->friends[student->friendCount++] = friend;
}

Note:
In here we're using **friends as indicating an array of Student pointer for the friend list.

We cannot use *friends and just do friends[1] = ..., friends[2] = ... because as of Pointer subscripting, friends[1] of *friends will take the actual value of Student, not &Student.

Therefore, if we do like that, we can copy the Student value but not the Student pointer for dynamic changes when we update the value of original student.