C language learning - Weng Kai (Chapter 11 notes)
C language Chapter 11
11.1.1 enumeration
Constant symbolization
#include<stdio.h> const int red=0; const int yellow=1; const int green=2; int main(int argc,char const *argv[]) { int color=-1; char *colorName=NULL; printf("Please enter your favorite color code:"); scanf("%d",&color) switch(color){ case red:colorNmae="red";break; case yellow:colorName="yellow";break; case green:colorName="green";break; default: colorName="unknown";break; } printf("What color do you like%s\n",colorName); return 0; }
- Use symbols instead of specific numbers to represent numbers in a program
enumeration
#include<stdio.h> enum COLOR {RED,YELLOW,GREEN}; int main(int argc,char const *argv[]) { int color=-1; char *colorName=NULL; printf("Please enter your favorite color code:"); scanf("%d",&color); switch(color){ case RED:colorNmae="red";break; case YELLOW:colorName="yellow";break; case GREEN:colorName="green";break; default: colorName="unknown";break; } printf("What color do you like%s\n",colorName); return 0; }
-
Use enumerations instead of defining independent const int variables
-
Enumeration is a user-defined data type, which is declared with the keyword enum in the following syntax:
enum enumeration type name {name 0,..., name n};
-
Enum type names are usually not really used, but names in braces should be used, because they are constant symbols, their type is int, and their values range from 0 to n, such as:
enum colors {red,yellow,green};
-
Three constants are created. The value of red is 0, yellow is 1, and green is 2
-
When you need some constant values that can be arranged, the meaning of defining enumeration is to give these constant values names.
#include<stdio.h> enum COLOR {RED,YELLOW,GREEN}; void f(enum color c); int main(void) { enum color t=red; scanf("%d",&t); f(t); return 0; } void f(enum color c) { printf("%d\n",c); }
- Enumerators can be used as values
- Enum types can follow enum as types (for example, enum color is equivalent to types such as int)
- But it is actually an integer for internal calculation and external output
Routine: enumeration of automatic counting
#include<stdio.h> enum COLOR {RED,YELLOW,GREEN,NumCOLORS}; int main(int argc,char const *argv[]) { int color=-1; char *ColorNames[NumCOLORS]={"red","yellow","green"}; char *colorName=NULL; printf("Please enter your favorite color code:"); scanf("%d",&color); if(color>=0&&color<NumCOLORS){ colorName=ColorNames[color]; }else{ colorName="unknown"; } printf("What color do you like%s\n",colorName); return 0; }
- This is convenient when you need to traverse all enumerators or create an array with enumerators as subscripts
Enumerator
-
You can specify a value when declaring an enumerator
- enum COLOR {RED=1,YELLOW,GREEN=5};
#include<stdio.h> enum COLOR {RED=1,YELLOW,GREEN=5}; int main(int argc,char const *agrv[]) { printf("color for GREEN is %d\n",GREEN); return 0; }
Enumeration is just int
#include<stdio.h> enum COLOR {RED=1,YELLOW,GREEN=5,NumCOLORS}; int main(int argc,char const *agrv[]) { enum COLOR color=0; printf("color for GREEN is %d\n",GREEN); printf("and color is %d\n",color); return 0; }
-
Even if you assign a non-existent integer value to a variable of enumeration type, there is no warning or error
enumeration
- Although enumeration types can be used as types, they are rarely used
- If there is a meaningful parallelism of names, enumeration is more convenient than const int
- Enumerations are better than macro s because enumerations have int types
11.2.1 structure type
Declaration structure type
#include<stdio.h> int main(int argc,char const *argv[]) { struct date{ int month; int day; int year; };//(the most common mistake for beginners: missing this semicolon!) struct date today; today.month=07; today.day=31; today.year=2014; printf("Today`s date is %i-%i-%i.\n",today.year,today.month,today.day); return 0; }
Inside / outside the function?
#include<stdio.h> struct date{ int month; int day; int year; }; int main(int argc,char const *argv[]) { struct date today; today.month=07; today.day=31; today.year=2014; printf("Today`s date is %i-%i-%i.\n",today.year,today.month,today.day); return 0; }
- Like local variables, structure types declared inside a function can only be used inside a function
- Therefore, the structure type is usually declared outside the function, so that it can be used by multiple functions
Form of declaration structure
struct point{ int x; int y; }; struct point p1,p2;
p1 and p2 are both point s with values of x and y
struct{ int x; int y; }p1,p2;
p1 and p2 are nameless structures with x and y inside
(less common)
struct point{ int x; int y; }p1,p2;
p1 and p2 are both point s with x and y values t
For the first and third forms, the structure point is declared. However, the second form does not declare point, but only defines two variables.
Structural variable
struct date today; today.month=06; today.day=19; today.year=2005;
Initialization of structure
#include<stdio.h> struct date{ int month; int day; int year; }; int main(int argc,char const *argv[]) { struct date today={07,31,2014}; struct date thismonth={.month=7,.year=2014}; printf("Today`s date is %i-%i-%i.\n",today.year,today.month,today.day); printf("Today`s date is %i-%i-%i.\n",thismonth.year,thismonth.month,thismonth.day); return 0; }
Structure member
- Structure is a bit like array (each cell type of array is the same, and the structure can be different)
- An array uses the [] operator and subscript to access its members
- a[0]=10;
- Structure accesses its members with a. Operation matching name
- today.day
- student.firstName
- p1.x
- p1.y
Structural operation
- To access the entire structure, use the name of the structure variable directly
- For the whole structure, you can assign values, take addresses, or pass them to function parameters (arrays cannot do these two operations!)
- p1=(struct point){5,10};// Equivalent to p1.x=5;p2.y=10;
- p1=p2 / / equivalent to p1.x=p2.x;p1.y=p2.y;
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;
11.2.2 structure and function
Structure as function parameter
int numberOfDays(struct date d)
- 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
- You can also return a structure
- This is completely different from arrays
Input structure
-
There is no direct way to scanf one structure at a time
-
If we're going to write a function to read in the structure
-
As follows:
#include<stdio.h> struct point{ int x; int y; }; void getStruct(struct point); void output(struct point); void main(){ 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\n",p.x,p.y); }
(p in getStruct receives the value of Y, but the structure variable with the same content as y cannot be returned, and Y in main cannot be changed)
- But how can the read structure be transmitted back?
- Remember that C passes values when a function is called
- So p in the function is different from y in main
- After the function reads the value of p, nothing returns to main, so y is still {0,0}
Solutions
- In the previous scheme, a structure is passed into the function and then operated in the function, but it does not return
- The problem is that the function is passed in a clone of the outer structure, not a pointer
- The incoming structure is different from the incoming array
- The problem is that the function is passed in a clone of the outer structure, not a pointer
- In this incoming function, you can create a temporary structure variable and return the structure to the caller
void main() { struct point y={0,0}; y=inputPoint(); putput(y); }
struct point inputPoint() { struct point temp; scanf("%d",&temp.x); scanf("%d",&trmp.y); return temp; }
#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\n",p.x,p.y); }
Structure pointer as parameter
- K & R (p.131)
- "If a large structure is to be passed to a function,it is generally more efficient to pass a pointer than to copy the whole 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 indicated by the pointer
Structure pointer parameter
void main() { struct point y={0,0}; inputPoint(&y); output(y); }
struct point* inputPoint(struct point *p) { scanf("%d",&(p->x)); scanf("%d"$(p->y)); return pl }
12.2.3 structure in structure
Structure array
struct date dates[100];
struct date dates[]={{4,5,2005},{2,4,2005}};
Structure in structure
struct dataAndTime{
struct date sdate;
struct time stime;
};
Nested structure
struct point{ int x; int y; }; struct rectangle{ struct point pt1; struct point py2; }; //If there are variables struct rectangle r; //You can have: //r.pt1.x,r.pt1.y //r.pt2.x and r.pt2.y
If there is a variable definition:
struct rectangle r,*rp; rp=&r;
Then the following four forms are equivalent:
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
But there is no RP - > pt1 - > x (because pt1 is not a pointer)
An array of structures in a structure
#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.px.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<1;i++) printRect(rexts[i]); }
11.3.1 type definition
Custom data type (typedef)
-
C language provides a function called * * * typedef * * * to declare a new name of an existing data type. For example:
- typedef int Length;
Make * * * Length * * * an alias of type * * * int * * *.
-
In this way, the name * * * Length * * * can appear in the variable definition and parameter declaration instead of int:
Length a,b,len;
Length numbers[10];
Typedef
Declare the name of the new type
- The new name is some kind of alias
- The readability of the program is improved
typedef struct{ int month; int day; int year; }Date;
typedef int Length;//Length is equivalent to int type typedef *char[10] Strings;//Strings is an array of 10 strings typedef struct node{ int data; struct node *next; }aNode; or typedef struct node aNode;//In this way, arnode can replace struct node
11.3.2 joint
union
choice:
Members are
- Is one int or I
- One is char c
sizeof(union ...)=
Maximum sizeof (per member)
union AnElt{ int i; char c; }elt1,elt2; elt1.i=4; elt2.c='a'; elt2.i=OxDEADBEEF;
- storage
- All members share a space
- Only one member is valid at a time
- The size of a union is its largest member
- initialization
- Initialize the first member
The use 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; }
Little Endian