C programming language: enums, structures, unions

Week 10: Enums, Structures, Unions

Tabs (space separated): C


10.1.1 Enumerations: Enumerations

Constant symbolication

  • Use symbols instead of concrete numbers to represent numbers in programs

enumerate

  • Use enums instead of defining separate const int variables
  • An enumeration is a user-defined data type that is declared with the keyword enum in the following syntax:
    • enum enumeration type name{name0,...,namen};
  • Enumeration type names are usually not really used, the names in curly braces are used, because they are constant symbols, their type is int, and their values ​​are in order from 0 to n. Such as:
    • enum colors{red,yellow,green};
  • Three constants are created, the value of red is 0, the value of yellow is 1, and the value of green is 2.
  • When you need some constant values ​​that can be arranged, the point of defining an enumeration is to give these constant values ​​names.
  • Enumerators can be used as values
  • Enumeration types can keep up with enum as a type
  • But in fact, integers are used for internal calculations and external input and output.

Routine: Automatically counted enumeration

  • enum colors{red,yellow,green,NumCOLORS};
    • This is very convenient when you need to traverse all enumerators or need to create an array with enumerators as subscripts

Enumeration amount

  • You can specify a value when declaring an enumerator
    • enum color{red=1, yellow,green=5};

enums are just int

  • There is no warning or error even if a non-existing integer value is assigned to a variable of an enum type
    • Although enumeration types can be used as types, they are actually very (bu) rarely (hao) used
    • Enum is more convenient than const int if it makes sense to rank names
    • Enums are better than macros because enums have type int

10.2.1 Structs: Struct Types

declare structure type

#include <stdio.h>

int main(int argc, char const *argv[])
{
    struct date{
        int month;
        int day;
        int year;
    };

    struct date today;

    today.month = 04;
    today.day = 16;
    today.year = 2018;

    printf("Today's date is %i-%i-%i.\n",
        today.year,today.month,today.day);

    return 0;
 } 
 Today's date is 2018-4-16.

inside/outside the function?

  • Like local variables, struct types declared inside a function can only be used inside the function
  • So usually the struct type is declared outside the function so that it can be used by multiple functions

The form of the declaration structure

 struct point{
    int x;
    int y;
 };

 struct point p1,p2;

 p1和p2都是point,里面有x和y的值 

 struct{
    int x;
    int y;
} p1,p2;

p1和p2都是一种无名结构,里面有x和y

struct point{
    int x;
    int y;
} p1,p2;
p1和p2都是point,里面有x和y的值

structure variable

  • struct date today;
    today.month = 04;
    today.day = 16;
    today.year = 2018;

structure initialization

  • struct date today{04,16,2018};
  • struct date thismonth{.month=4, .year=2018};

structure member

  • Structs are a bit like arrays
  • Arrays use the [] operator and subscripts to access their members
    • a[0] = 10;
  • Structs use the . operator and name to access their members
    • today.day
    • student.firstName
    • p1.x
    • p1.y

Structural operations

  • To access the entire structure, use the name of the structure variable directly
  • For the entire structure, you can do assignments, take addresses, or pass them to function parameters
    • p1 = (struct point){5,10}; //equivalent to p1.x=5, p1.y=10;
    • p1=p2; //equivalent to p1.x=p2.x; p1.y=p2.y; arrays cannot do these two operations

structure pointer

  • Unlike arrays, the name of a structure variable is not the address of the structure variable, and the & operator must be used
  • struct date *pDate = &today;
#include <stdio.h>

int main(int argc, char const *argv[])
{
    struct date{
        int month;
        int day;
        int year;
    };

    struct date today;  
    today=(struct date){04,16,2018};    
    struct date *pDate = &today; 

    printf("Today's date is %i-%i-%i.\n",
        today.year,today.month,today.day);
    printf("address of today is %p\n", pDate);

    return 0;
 } 

10.2.2 Structures: Structures and Functions

struct as function parameter

  • The entire structure can be passed into the function as the value of the parameter
  • At this time, create a new structure variable in the function and copy the value of the caller's structure
  • can also return a struct
  • This is completely different from an array

input structure

  • There is no direct way to scanf one structure at a time
  • If we were to write a function to read in the struct
#include <stdio.h>

struct point {
    int x;
    int y;
}; 

void getStruct(struct point);
void output(struct point);

int main(int argc, char const *argv[])
{
    struct point y = {0,0};
    getStruct(y);
    output(y);
}

void getStruct(struct point p)
{
    scanf("%d", &p.x);
    scanf("%d", &p.y);
    printf("%d, %d\n", p.x, p.y); 
}

void output(struct point p)
{
    printf("%d, %d", p.x, p.y);
}
12 23
12,23
0,0
  • But how is the read structure sent back?
  • Remember that C is pass-by-value when calling a function
    • So p in the function is different from y in main
    • After the function reads the value of p, nothing goes back to main, so y is still {0,0}

solution

  • In the previous scheme, a structure was passed into the function, and then operated in the function, but there was no return
    • The problem is that what is passed into the function is a clone of that struct outside, not a pointer
    • Passing in a structure is different from passing in an array
  • In this input function, it is entirely possible to create a temporary structure variable, and then return this structure to the caller
#include <stdio.h>

struct point {
    int x;
    int y;
}; 

struct point getStruct(void);
void output(struct point);

int main(int argc, char const *argv[])
{
    struct point y = {0,0};
    y = getStruct();
    output(y);
}

struct point getStruct(void)
{
    struct point p;
    scanf("%d", &p.x);
    scanf("%d", &p.y);
    printf("%d, %d\n", p.x, p.y); 
    return p;
}

void output(struct point p)
{
    printf("%d, %d", p.x, p.y);
}
12 23
12, 23
12, 23

Structure pointer as parameter

  • K&R p131
    • "If you have a large structure variable that needs to be passed into a function, it is usually more efficient to pass a pointer instead of copying the entire structure."

pointer to structure

struct date {
    int month;
    int day;
    int year;
} myday;

struct date *p = &myday;

(*p).month = 12;
p -> month = 12;
  • Use -> to represent the member in the structure variable pointed to by the pointer

10.2.3 Structures: Structures within Structures

array of structures

  • struct date dates[100];
  • struct date dates[] = { {4,5,2005},{2,4,2005} };

structure within structure

struct dateAndTime {
    struct date sdate;
    struct time stime;
}; 

nested structure

struct point {
    int x;
    int y;
};
struct rectangle {
    struct point pt1;
    struct point pt2;
};

如果有变量
    struct rectangle r;
就可以有:
    r.pt1.x、 r.pt1.y
    r.pt2.x 和 r.pt2.y 

如果有变量定义:
    struct rectangle r, *rp;
    rp = &r;

那么下面的四种形式是等价的:
    r.pt1.x
    rp->pt1.x
    (r.pt1).x
    (rp->pt1).x
但是没有rp->pt1->x (因为pt1不是指针)

array of structs within structs

#include <stdio.h>

struct point{
    int x;
    int y;
};

struct rectangle {
    struct point p1;
    struct point p2;
};

void printRect(struct rectangle r)
{
    printf("<%d, %d> to <%d, %d>\n", r.p1.x, r.p1.y, r.p2.x, r.p2.y);
}

int main(int argc, char const *argv[])
{
    int i;
    struct rectangle rects[] = {
        {{1,2}, {3,4}},
        {{5,6}, {7,8}}      
    };// 2 rectangles
    for(i=0;i<2;i++) {
        printRect(rects[i]);
    }
}
<1, 2> to <3, 4>
<5, 6> to <7, 8>

10.3.1 Unions: Type Definitions

Custom data type (typedef)

  • The C language provides a function called typedef to declare a new name for an existing data type. for example:
    • typedef int Length;
    • Makes Length an alias for type int.
  • In this way, the name Length can appear in variable definitions and parameter declarations instead of int:
    • Length a,b,len;
    • Length numbers[10];

Typedef

  • Declare the name of the new type
    • The new name is an alias of some kind
    • Improved program readability
typedef long int64_t; //重载已有的类型名字,新名字的含义更清晰,具有可移植性
typedef struct ADate {
    int month;
    int day;
    int year;
} Date; //简化了复杂的数字

int 64_t i = 1000000000;
Date d = {4,17,2018};
typedef int Length;//Length 就等价于int类型

typedef *char[10] Strings;//Strings 是10个字符串的数组的类型

typedef struct node {
    int data;
    struct node *next;
} aNode;


typedef struct node aNode;//这样用aNode就可以代替struct node 

10.3.2 Union: Union

joint

union AnElt {
    int i;
    char c;
} elt1,elt2;

elt1.i = 4;
elt2.c = 'a';
elt2.i = 0xDEADBEEF;
  • choose:
    • member is
      • an int i or
      • a char c
        sizeof(union...) = maximum value of sizeof(each member)
  • storage
    • All members share a space
    • Only one member is active at a time
    • The size of a union is its largest member
  • initialization
    • Initialize the first member

The usefulness of union

#include <stdio.h>

typedef union {
    int i;
    char ch[sizeof(int)];
} CHI; 

int main(int argc, char const *argv[])
{
    CHI chi;
    int i;
    chi.i = 1234;
    for (i=0; i<sizeof(int); i++) {
        printf("%02hhX", chi.ch[i]);
    }
    printf("\n");

    return 0;
}
FFD2040000

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324884169&siteId=291194637