2

I'm trying to make a program that uses a structure pointed by an array of 30. Which means, there will be only 30 available structures named Person. Think of this as an Activity line, the Activity line can only have 30 active Persons. Functions used are:

#include <stdio.h>
#include <stdlib.h>

struct Person
{
    char name[40];
    char firstname[40];
    int CIN[12];
};

typedef struct Person *Activity;

main()
{
    Activity act[30];
    return 0;
}

Vacant(searches if there is an empty place in the Activity line).

insertion(Inserts new Persons IF a place is empty in the Activity line).

withdrawal(Removes a Person from the Activity line).

This is the declaration of the structure and the Activity line:

CIN is French for National Card Identity.

The functions are:

vacant(Activity act, int index);
insertion(Activity act, int index);
withdrawal(Activity act);

index is the number of the empty place, must be used in insertion.

My questions are:

  1. Is the declaration I made correct?
  2. If; considering the declaration is correct, the size of the array is 30 and the array points to the structure, does it mean I don't need to allocate the memory dynamically?(Using malloc function).
  3. Considering I'm on the right path. Does accesing field "name" for example go like this: "act.name"?
Danny_ds
  • 11,201
  • 1
  • 24
  • 46
Amine
  • 1,396
  • 4
  • 15
  • 32

1 Answers1

4
  1. In the declaration I cannot find anything terribly wrong

  2. Since it is an array of pointers to structs and not an array of structs, you just have to use malloc when you create a Person and then assign the returned pointer to one position of the array. But you do not need to use malloc at any other time with the code shown.

  3. No, the dot is to access a field of an struct, for example if you have Person peter it would be peter.name. To access the struct from the array it should be (*act[i]).name or act[i]->name.

Hope this helps you; I am learning as you so maybe a more experienced user can help you more.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Lopan
  • 483
  • 1
  • 7
  • 20
  • 1
    You're on the mark until you get to `*act[i].name`. That won't work because of the precedence rules; `act[i]` is a pointer to a struct, so you need to use either `(*act[i]).name` or (more sensibly) `act[i]->name` to obtain a pointer to the character array. – Jonathan Leffler Jan 09 '16 at 21:05
  • Thank you dude! I always forget about the parenthesis... I'll edit my post now to avoid a misunderstanding. P.S: I always forget the parenthesis until I compile and execute -.-' – Lopan Jan 09 '16 at 21:07
  • It's best to forget about the parentheses and to use the arrow `->` operator. All else apart, it is 2 characters shorter (2 vs 4). It also chains more readably. Compare: `(*(*(*(*a).b).c).d.e).f` with `a->b->c->d.e->f`. Then go and look at [The Law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter) and repent. But even `a->b->c` is easier to read than `(*(*a).b).c`. – Jonathan Leffler Jan 09 '16 at 21:20
  • Is (*act+i).name correct? I believe this is the standard use of pointers in structurues. Like that you have to use -> in a standard structure(person->name) and . in a pointed structure(person.name)? – Amine Jan 09 '16 at 21:20
  • @Amine: No — `(*act+i).name` is not correct. It would need to be `(*(act + i)).name` or, better, `act[i]->name`. – Jonathan Leffler Jan 09 '16 at 21:22
  • @JonathanLeffler: I'm using the latest version of Dev C++(5.11) and whenever I use -> while declaring a pointer, it gives me an error that it must be .(a dot)! Is that something I really need to look into? – Amine Jan 09 '16 at 21:25
  • @Amine: My bad — I got caught by your hidden pointers (or some such tawdry excuse). This code compiles cleanly: `Activity act[30]; int i = 0; struct Person p; act[i] = &p; strcpy(act[i]->name, "Fawkes"); strcpy((*(*(act+i))).firstname, "Guy");` On the whole, I think it is a lot easier to understand (and get right first time) the `act[i]->name` notation than the `(*(*(act + i))).firstname` notation. Yes — you need to fix the code since it won't compile if you don't. But you need to fix it correctly. Remember, the C compiler knows a lot more about C than you do at the moment. – Jonathan Leffler Jan 09 '16 at 21:39
  • @JonathanLeffler: What I understood from your replies, that it is better to use act[i]->name as it's a pointer? What I find confusing, is that act is a pointer and must be used with a dot(.)! – Amine Jan 09 '16 at 21:39
  • @JonathanLeffler: I'm terribly sorry for annoying you, but I'd really like to get things clear. [Pastebin](http://pastebin.com/LE1RPPMb). This is a program I made few weeks ago, it sorts a given number of structures using the field name. Now, if you notice in function saisie I used `per[i].nom` and it works, but using `per[i]->nom` returns a compiling error. Using `*(per+i).nom` returns a compiling error, using `(per+i)->nom` works but I can't add more than a signle structure. I'm really confused here and I can't know what's better and whether I'm doing something wrong(and it works) or not! – Amine Jan 09 '16 at 22:04
  • @Amine: Any annoyance was me being annoyed with myself — I shouldn't have made the mistake. My only excuse is it was comment, not formally an answer; code in answers is usually checked with a compiler, whereas code in comments isn't always. As to your code, you have `Activity act[30]`, which is equivalent to `struct Person *act[30]`, or, in other words, `act` is an array of 30 pointers to `struct Person`. When you use `act[i]` or `*act` or `*(act + i)`, you are accessing an element of the array, so you get a `struct Person *` or `Activity` — a pointer to a structure. _[…continued…]_ – Jonathan Leffler Jan 10 '16 at 02:38
  • _[…continuation 1…]_ To access an element of the structure pointed to, you use the arrow operator: `act[i]->name`. If you insist on using the `*` to dereference (which is generally not something experienced programmers will do), then you have to use `(*(*act)).name` or `(*(*(act + i))).name` or equivalent. The sheer number of stars and parentheses should be off-putting — if not confusing. If you have a pointer to a structure, use the arrow `->`; use the `.` if you have a structure. Don't use `*` to convert the pointer to structure into a structure just so you can use `.`. _[…continued…]_ – Jonathan Leffler Jan 10 '16 at 02:48
  • _[…continuation 2…]_ You mention a function `saisie` but I don't see the code in the question. If you have `void saisie(Activity per, int i) { printf("Surname: %s\n", per[i].name); }` for example, then this is fine. `per` is a pointer to a `struct Person` (or the zeroth element of an array of such pointers), so `per[i]` is a `struct Person` — the `i`th element of the array — and then `.` is correct to dereference. Please read up on how to create an MCVE ([How to create a Minimal, Complete, and Verifiable Example?](http://stackoverflow.com/help/mcve)); having an MCVE makes it easier to help. – Jonathan Leffler Jan 10 '16 at 02:54
  • @JonathanLeffler Thank you for your explanation on the `->` operator. I'll try to get used to it. – Lopan Jan 10 '16 at 09:08
  • @JonathanLeffler: Thank you so much for the explanation, things are getting clear now. The function I mentioned is [HERE](http://pastebin.com/LE1RPPMb). (It's a program that sorts of given number of structures). – Amine Jan 10 '16 at 15:44