nomunomu0504.blog

技術メモ / 車 / 音楽 / 雑記 / etc...

Program using structure

Introduction

When handling information with the same data, it is more convenient to treat common things as a single datum. In that case, we will have to use the structure.

How to operate the structure

Structures are "one that collects various kinds of data into one piece". It refers to data obtained which are then summarized into one datum. For examples are: name, gender, age, height, & weight for one person. An element constituting a structure is called a member of a structure. In the above example, "name" "sex" "age" "height" "weight" corresponds to a member.

Declaration method

A structure is a single data type, and its form must be declared first. After having declared its form, you can now declare the entity (object) of the structure declaring a variable (including its type) and use it.

Declaration of a form of a structure and declaration of a structure variable having that form are made as follows:

struct Structure-tag-name {A row of members};   /* Type declaration */

struct Structure-tag-name Structure-variable-name;     /* Declaration of structure variables */

Apply the above members to the elements mentioned in the second paragraph and declare structure variables. See example below.

struct Person {
    char name[20];
     int sex;
  // char sex;
     int age;
  double height;
  double weight;
};

struct Person p;

Here I wrote int sex and char sex, in the case of char, it is man, woman, int it can be like 0: man, 1: woman so it may be easier. This time I would like to define it as an int. (However, char is 1 in size, but int is 4, so if you want to save memory, char may be better)

Also, if it is troublesome to write a struct when declaring a structure variable, you may try the format below:

typedef struct Person {
    char name[20];
     int sex;
  // char sex;
     int age;
  double height;
  double weight;
} person_s;

person_s p;

If you write it like this, you can reduce the description when declaring the structure object.

Initialization of structure members

The initialization method of each member is as follows.

person_s p = {"Tom", 0, 20, 175.2, 66.5};

// or

person_s p;
strcpy(p.name, "Tom");
p.sex  = 0;

If the value of each member is already known, it is possible to perform batch assignment like the former. However, in most cases, the value of each member is often unknown. In such a case, the latter way would be best to use. Define the structure variable and refer to the structure member and assign it. The way to refer using ".", this is called "direct reference".

Assignment of structure

If structure variables with the same type are used, a structure can be assigned.

person_s p1 = {"Tom", 'M', 19, 175.2, 69.5};
person_s p2;
person_t p3;

p2 = p1; // Assignment possible
p2 = p3; // Assignment impossible

Array of structures

Structs can be declared using arrays as well as int and so on.

#define PERSON_NUM 5

person_s p[PERSON_NUM];

If you want to access the name of p[3] you can access it with p[3].name. Also, the initialization method of the structure array can be done in the same way as the previous method.

person_s p[PERSON_NUM] = {
    {"Bob",      'M', 19, 165.4, 72.5},
    {"Alice",    'F', 19, 161.7, 44.2},
    {"Tom",      'M', 20, 175.2, 66.3},
    {"Stefany",  'F', 18, 159.3, 48.5},
    {"Leonardo", 'M', 19, 172.8, 67.2}
};

// or

person_s p[PERSON_NUM];

strcpy(p[3].name, "Tom");
p[3].sex  = 0;

A structure that has a structure as a member Previously, we declared int and char as structure members, but from now on I declare a structure with structure in a structure member.

typedef struct {
    person_s boy;   /* Information on a boy in a couple */
    person_s girl;  /* Information on a girl in a couple */
    int month;      /* Date of together (months) */
} couple_s;

couple_s cpl = {
    {"Tom",     0, 20, 175.2, 66.3},
    {"Stefany", 1, 18, 159.3, 48.5},
    8
};

At this time, I have declared a structure couple_s with structure person_s in the structure member. From here, when you access the member name of member boy in couple_s you can access it with cpl.boy.name. You can also assign this way:

person_s newboy  = {"Leonardo", 0, 19, 172.8, 67.2};
person_s newgirl = {"Sara",     1, 19, 162.5, 49.3};

cpl.boy  = newboy;
cpl.girl = newgirl;
cpl.month = 1;

Functions and structures

Structure as function argument

So far we have used the structure as a standalone, but I would like to use it together with the function to write more sophisticated programs. Here, as an example, consider a structure representing the composition of a straight line expression.

typedef struct {
    double a;
    double b;
} sample_s;

The following function printFormula(sample_s f) is a function that takes a sample_s structure and displays an expression.

void printFormula( sample_s f ) {

    printf("%.3lf x + %.3lf", f.a, f.b);
}

int main ( void ) {

    // Either 1 or 2 initialization method can be used
    // 1
    sample_s f = { 3.5, 2.0 };

    // 2
    sample_s f;
    f.a = 3.5;
    f.b = 2.0;

    printFormula( f );

    return 0;   
}

3.50 x + 2.00 will be displayed.

Structure in function return value

Define a function by specifying a structure as a return value. The next function addFormula returns a slope of the sample_s structure with two arguments and a sum of intercepts as a sample_s structure.

sample_s addFormula ( sample_s f1, sample_s f2 ) {

    sample_s f3;
    f3.a = f1.a + f2.a;
    f3.b = f1.b + f2.b;

    return f3;
}

int main ( void ) {

    sample_s f1 = { 1.5, 5.0 };
    sample_s f2 = { 4.0, 2.5 };
    sample_s f3;

    f3 = addFormula( f1, f2 );
    printFormula( f3 );

    return 0;
}

I think that 5.50 x + 7.50 will be displayed.

Structure pointer as function argument

The next function takes a structure pointer (3) as an argument and assigns the result to the place pointed to by the last structure pointer.

void addFormulaPtr( sample_s *f1, sample_s *f2, sample_s *f3 ) {

    (*f3).a = (*f1).a + (*f2).a;
    (*f3).b = (*f1).b + (*f2).b;
}

int main ( void ) {

    sample_s f1 = { 5.0, 1.0 };
    sample_s f2 = { 3.3, 1.5 };
    sample_s f3;

    addFormulaPtr( &f1, &f2, &f3 );
    printFormula( f3 );

    return 0;
}

8.30 x + 2.50 is displayed.

Also, addFormulaPtr can be written as follows using the indirect member reference operator (arrow operator) described below.

void addFormulaPtr( sample_s *f1, sample_s *f2, sample_s *f3 ) {

    f3->a = f1->a + f2->a;
    f3->b = f1->b + f2->b;
}

The reference using "->" is called indirect reference.

Union

A structure very similar to a structure is called a union. Like a structure, it is a collection of data of various types, how to define it, how to refer to a member, etc. The only difference, however, is that, its members share the same memory.

Therefore, members of one variable of the union type can not use more than one of them at the same time.

For example, if you create a union of human data (name, gender, age, ...) as a union, its definition is as follows.

union _person {         /* _person is tag name  */
    char name[20];       /* String array type members name */
     int sex;           /* String type member sex */
     int age;           /* Integer type member age */
    double height;      /* Double precision real type member height */
    double weight;      /* Double precision real type member weight */
};

union _person p;        /* Declare a union _person type variable named p */

Members of this union type variable p are arranged so as to overlap on the same memory as shown in the following figure.

Therefore, the memory size of the union matches the maximum memory size of its members. (In the case of this union_person, since the name is maximum by 20 bytes, the size of the union as a whole also becomes 20)

The union has a very special use, but I will not explain it here.