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)
- member is
- 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