1, What is C language
C language is a strongly typed language. Once the type of variable is determined, it can not be changed in its whole life cycle.
int main()//Main function framework { return 0; /// * * / cannot be nested in c language }
- A c language source program can be composed of multiple source files, but there can only be one main function
- A source file can consist of multiple functions
- Each statement needs to use; ending
2, Basic data type
//integer char;//1 byte short; //2 bytes int; //4 bytes long int;//4 bytes long long;//8 bytes //float float;//4 bytes double;//8 bytes long double;//8/12/16 // bool;//Only true and false values are 1 byte // void//No type no size
When defining variables for each type, the number of storage units allocated is different
3, Variable, constant, identifier
- Variable: readable and writable;
- Constant: readable only;
- Identifier: see the meaning of the name
- Variable: allocate space for a variable and assign a variable name (identifier). The variable is co stored with the allocated space, and the memory location will not change. A variable name cannot be defined repeatedly in the same scope.
- Statement:
1. Variable:
Variables are divided into: global variables (defined outside the function), local variables (defined inside the function) and intra block variables (defined inside {} in the function, only valid in {})
int a=100;//overall situation void fun() { int b=100;//local variable } int main() { int b; //The visibility of b is only within its function, so it does not conflict { int c;//Intra block variable } }
Note: when the global variable name is the same as the local variable name, the principle of proximity (proximity to the previous statement) is adopted
int a=100; void fun() { int b=a; int a=50; int c=a; int d=::a//Use global variables { int c=60;//The statement is valid only within this block } } //b=100 c=50
2. Constant:
Constants are divided into literal constants, constants defined with #defien, constants modified with const (initial value must be assigned), enumeration constants, character constants and string constants
#define MAX 5 / / the macro constant has no type and does not allocate space enum week={mon=1}; int main() { int a=10;//10 is a literal constant int b=3*MAX;//In the precompiling process, MAX will be replaced with 5, so the macro constant plays the role of replacement. //. i file, the statement int b=3*5 const int c=50;//Not writable, readable const int ARR[10]={1,2,3,4}//Each quantity of the array becomes a constant enum week d=mon;//If the enumeration constant is not assigned a value, the next quantity is accumulated by 1 (only integers are received) starting from 0 return 0; }
Note:
- The type is recognized only during compilation
- . C. I files are text files
- . i file, the macro constant does not exist, that is, it has been replaced
3. Escape character
- '' character delimiter; "" string delimiter\ Escape character (normal - > special; special - > normal)
Escape character | function | ASCII |
---|---|---|
\n | Newline character | 10 |
\r | Carriage return | 13 |
\t | Horizontal tab | 9 |
\000 | 1 ~ 3 are characters represented by octal |
char ch='\''//Single quotation mark
char ch = '0' (character 0) | ASCII 48 |
---|---|
char ch=0 | 0(false) |
char ch = '\ 0' (empty character) | 0(false) |
char ch='a' | 97 |
int *p=NULL | 0(false) |
- The string ends with '\ 0'
character | ASCII |
---|---|
'(space) | 32 |
'0' | 48 |
A | 65 |
a | 97 |
enter | CR |
Line feed | LF |
4, Scope and lifetime
Code area |
---|
Data area |
Heap area |
Stack area |
1. Scope
-
The scope is the scope in which the indicator identifier can be used. (this stage is for the compilation and linking process) variables can only be used within the available range.
-
When a global variable scope is defined, it is visible to the statements below it
-
The scope of a local variable is visible within the function it defines
int a=20;//overall situation void fun() { int b=0; int b=a;//a is visible to b, and this sentence is executable int b=c;//c is invisible to b, so the assignment operation cannot be performed } int c=15; int main() { int b=20;//b in the main function does not conflict with b in fun, and the scope of local variables is different }
2. Lifetime (allocate memory space)
-
Lifetime refers to the execution process of the function. The survival time of variables is different under different scopes. (the program will not be executed until the compilation link passes)
-
Lifetime is that variables are created during program execution, and the corresponding memory is allocated. They are destroyed at the end of the program, and the memory space is also recycled.
-
Global variables are stored in the data area and local variables are stored in the stack area.
-
Global variables are stored in the data area before the main function is executed and released after the program is completed
-
Local variables are stored in the stack frame when the function is executed, and are released after the function is completed.
void fun() { int a,b; } int main() //Only when the main function executes the void() function will the stack allocate space to a and b { void() }
5, Operands and operators
1. Operand
int a; int b=a+10; //a. B, 10 are operands
Operands are variables, constants, logical values, etc. in the program can be called operands (data entities operated by the program)
2. Left and right values
Left = left value, right value; If it is an lvalue, it means that the value is readable and writable; Only the right value is readable and not writable (the value can be assigned to other variables, but cannot be assigned by other variables).
int a=0; a=10; 10=a;//Cannot execute. Constants cannot be modified
3. Operator
- Operate on operands accordingly
- Classification: unary operator, binocular operator, and binocular operator
- The ternary operator solves simple if statements ((a > b)? A: b)
1. Front and rear++
-
++In the assignment statement:
int a=1,b=0; b=a++;//Post + + is to take out the value in a and put it into a temporary space, assign a to b, and then write back the value of a + + to a (assign it first and then + +) b=++a;//Pre + + is to take out the value of a and put it into the temporary space, write a back to a and assign it to b
-
Without assignment
for(int i=0;i<100;i++/++i)No difference
2. Remainder operator
//Print even numbers from 0 to 100 for(int i=0;i<100;i++) { if(i%2==0) { printf(....) } } // n%(10,100,....)The result is (0~10,0~100 (within range)
3. Assignment operator
✨ If you want to change the value of a variable (except + +), you must assign a value
6, Keywords
-
Data type keyword:
Char int short float double signed unsigned struct union enum typedef sizeof auto static register extern const volatile
-
Process control Keywords:
if else switch case default for while do return continue break goto
1,sizeof
sizeof: neither macro nor function
int a=10; int b=sizeof(++a);//sizeof only resolves the type size, and + + a does not operate
2,typedef
typedef: give a simple alias to the name of a complex type (legal variable definition); Cannot appear in the same expression as other keywords; And attention should be paid to the scope. (convert variable name to type)
typedef char ch; typedef int Array[10]; typedef int *PIN; struct student { char name[10]; int age; }stud,*sp; //stud=>struct student stud //*sp=>struct student *sp typedef struct student { char name[10]; int age; }stud, * sp;//Study, * SP is defined as the type name int main() { char a = 'A'; ch b = 'B'; //ch is no longer a variable name, but a type name Array br = { 1,5,6,3,7,9 }; PIN p=NULL;//p is an integer pointer }
3,static
-
static keyword can extend the production cycle of variables and store them in the data area
-
The variable value modified by static is initialized once (scope problem)
void fun(int x) { int a = 0; int static b = 0; a += x; b += x; printf("%d %d\n", a, b); } int main() { for (int i = 0; i < 10; i++) { fun(i); } return 0; }
4,extern
- extern: used to declare that a variable / function comes from other files under the same project and is used under this file. (external cannot be used for local variables and variables modified by static)
7, Sequence, loop, select statement
bool type
- There are many kinds of true (non-0) in c language, but only 0 is false
- The bool type has only two values, true and false
- bool type one byte 0000 000 0 the last bit is used to indicate true or false
- The operation result of relational expression / logical expression is bool value (A & & B: when a is false, expression B will not participate in the operation; when a|b A is true, expression B will not participate in the operation)
- ! Although it is a unary operator, it has no writeback ability. Unlike + + / – it needs to be assigned.
- Priority: = < & & and | < relational operator < arithmetic operator < not (!)
1. Sequential statement
Execute line by line
int main() { int a=10; int b=a; printf(.....); }
2. Select statement
1. if statement
if(true) { ...... } else { ...... }
Note: when making conditional judgment in if statement, it is necessary to make equal judgment==
2,switch
-
A switch statement is a multi branch statement
switch(Integer variable expression) { case constant:Statement block break; default: break; }
-
break is used to exit the switch.
3. Circular statement
1. while loop
while(condition) { ..... }
Judgment before execution
2. do... while loop
do { ...... }while(condition)
Execute before Judge
3. for loop
-
For (expression 1; expression 2; expression 3)
{loop statement}
-
The expression is executed only once, and then judged by expression 2 (true Or false). If it is true, execute expression 3 and execute the loop body.
4. Empty statement
-
Empty statements consist only of semicolons and do nothing
int a=10; ;
-
Problems caused by empty statements: if empty statements are added after if, while and for, their own logical structure will be destroyed and their functions will not be completed.
if(true) ; for(int i=0;i<n;i++) ; while(true) ;
5. Comma expression
Comma expressions have the lowest priority and are executed from left to right.
8, Functions
-
Function is used to complete a specific and single function; Functions are divided into library functions and user-defined functions
-
Library functions: library functions are provided by the system itself.
-
User defined function: written by the user. It is composed of return type, function name, formal parameter list and function body
int fun(int a,int b) { int c=0; c=a+b; return c;//return, store c in the temporary space and assign c to max. because of the scope problem, c cannot play a role in fun and main at the same time } int main() { int a=10,b=20; int max=fun(a,b); }
-
-
Formal and argument
- Formal parameters are parameters passed in when a function is called. Space will be allocated only when the function is called, and the space will be released after the function is completed
- Arguments are parameters (constants, variables, expressions, functions) passed to formal parameters when a function is called
- The data transfer in function call is one-way. You can pass the value of the argument to the formal parameter, but you can't pass the value of the formal parameter back to the argument
- Pass the argument value to the stack of formal parameters, also known as arguments (right to left)
-
Value passing and address passing
void fun(int a, int b) { int temp = a; a = b; b = temp; } int main() { int a = 10; int b = 20; fun(a, b); printf("%d %d\n", a, b); }
The exchange of values cannot be realized because the direction of value transfer is one-way
Address transfer:
void fun_2(int* a, int* b) { int temp = *a; *a = *b; *b = temp; }
void fun(int a, int b) { int temp = a; a = b; b = temp; } int main() { int a = 10; int b = 20; fun(a, b); printf("%d %d\n", a, b); }
-
void Prin_ar(int br,int n) { sizeof(br);//==4; When the array passes parameters, the array will degenerate into a pointer, so the size of the array needs to be passed in together. } int main() { int ar[4]={0,1,2,3} Prin_arr(ar,4); }
9, Array
-
Array = type + number of elements
int arr[10]={};//When defining an array, the number of elements must be an integer constant expression greater than zero
-
Arrays are stored continuously in memory
-
When accessing an array, it is accessed through the array name and subscript, which starts from 0. (subscripts are integer constants or variables)
for(int i=0;i<5;i++) { printf("%d",arr[i]); } printf("%d",arr[3]);
-
How arrays are printed
int main() { int arr[5] = { 23,34,45,56,67 }; int* p = arr; for (int i = 0; i < 5; i++) { printf("%d %d %d\n", arr[i], *(arr + i), i[arr]); }//arr[i]=>*(arr+i) i[arr]=>*(i+arr) return 0; }
10, Pointer
-
Pointer variable is a variable used to access the storage address (storage address); A pointer is the address of memory
-
No matter what type of pointer, the size is 4 bytes (under 32-bit platform).
-
Pointers are divided into wild pointers (declared but uninitialized) and null pointers (initialized to null)
-
*Meaning in different cases:
int a*b;//*Represents the multiplication operator int *a;//*Represents a declaration that a is a pointer variable *a=20;//*Indicates pointing and dereferencing
In the definition pointer, * is combined with the variable name
int *a,b;//a is the pointer and b is the integer variable
-
int *p=NULL;//Declare pointer variable p int a=10; //int *p=&a; p=&a;//p address where a is stored *p=100;//*p is a itself. Changing the value of * p means changing the value of a (dereference)
-
A pointer has two values, one is its own value (stored address) and the other is the value it points to (dereference)
-
The pointer stores the first address (low address value) of various types of variables. The address is composed of 32-bit binary, so the size of the pointer is 4 bytes.
int main() { int arr[5] = { 12,23,34,45,56 }; int* p = arr; int x = 0, y = 0; //*It has the same priority as + + so it is combined from right to left x = *++p; y = *p; printf("%d %d\n", x, y);//23 23 x = ++ * p; y = *p; printf("%d %d\n", x, y);//24 24 x = *p++; y = *p; printf("%d %d\n", x, y);// 23 34 x = (*p)++; y = *p; printf("%d %d\n", x, y);//34 35 return 0; }
-
Pointer operation
-
The pointer can be added to the integer (increasing the size of bytes occupied by the variable type)
-
Pointers cannot be added (for example, dates cannot be added)
-
Pointers of the same type point to continuous space and can be subtracted. The result of subtraction is the size of data elements (the result of int type is the number of integer elements)
int main() { const int n = 5; int arr[n] = { 10,20,30,40,50 }; int* pl = &arr[0]; int* pf = &arr[4]; printf("(pf-pl)=%d\n", (pf - pl)); return 0; }
-
Functions and pointers
void fun(int* p) { int a = 200; *p = 100; p = &a; } int main() { int x = 0; int* s = &x; fun(s); printf("%d %d\n", x, *s); return 0; }
Arrays and pointers
-
The array name of the array only represents the entire array in sizeof(). In other cases, it represents the address of the first element of the array.
-
Add one to a type pointer to increase the bytes occupied by the type
-
int main() { const int n = 5; int arr[n] = { 12,23,34,45,56 }; int* p = arr; for (int i = 0; i < n; i++) { //printf("%d %d\n", arr[i], *(arr + i),i[arr]); //arr[i]==*(arr+i),i[arr]=*(i+arr) printf("%d %d\n", p[i], *(p + i)); } return 0; } //Arr is an array that stores int type data. Arr is a pointer to the first element of the array. When arr+1, arr points to the second element of the array, but the size of int type is four bytes, so arr+1 is equivalent to the pointer skipping four bytes.
-
When parameters are passed, the array is degenerated into a pointer (saving time and space)
Pointer variable and const
int const *p; const int *p;
From right to left, p is combined before * and then with const. Therefore, the value of p can be modified and point to another address, but the value of * p cannot be modified
int *const p;
As above, p is combined before const, and the address it points to cannot be modified, but the value stored in the address can be changed
const int * cosnt p;
Its own value and direction are not allowed
Typeless pointer
-
void cannot define variables, but can define pointer variables
-
A typeless pointer can hold any type of address
int main() { const int n = 5; int ar[n] = { 1,2,3,4,5 }; void* p = ar;//p address where ar can be stored //int* ip = p;// However, P cannot be read directly, and forced rotation is required int* ip = (int*)p; }
-
The size of the untyped pointer is still 4 bytes, but the untyped pointer cannot be + 1 because the memory cannot resolve the corresponding size of the untyped pointer (int type plus 1, address plus 4)
11, Two dimensional array
Two dimensional arrays are stored row first and continuously in memory.
-
int a = 10, b = 20; int* p = nullptr;//*Combined with variable name int** s = nullptr; s = &p;//s stores the address of pointer p *s = &a;//Dereference s, * s is the address where p itself stores variable a, which is equivalent to P = & A* s=>*&p=>p=&a **s = 100;//Dereference * s, * s and are * P, which is equivalent to * P = 100** s=>*p=>a=100 return 0;
The first level pointer stores the address of the variable, and the second level pointer stores the address of the first level pointer
s int**(type) *s int* **s int -
double a_3 = 0, a_2 = 0, a_1 = 0, a_0 = 0; double* p_3 = &a_3, * p_2 = &a_2, * p_1 = &a_1, * p_0 = &a_0; double** s = &p_0;
s+1 increases by 4 bytes because the size of the pointer is 4 bytes, while * s+1 increases by 8 bytes because double type variables account for 8 bytes
-
int *p[4];//Open up an array of 4 storage units, and each element in the array is an integer pointer int a=4,b=5,c=6,d=7; p[4]={&a,&b,&c,&d}; int (*s)[4];//s is the address where the pointer stores the array. The array opens up four spaces, each element is an integer, and the array can only store array addresses of type int [4] (arrays of the same type) int ar[3];
-
int ar[4]; ar;//Represents the address of the first element ar+1;//Points to the next element of the array &ar;//Represents the address of the array &ar+1;//Address to the next array //The values of ar and & ar are the same
-
Relationship between two-dimensional array and secondary pointer
int ar0[4],ar1[4],ar2[4],ar3[4]; int (*s)[4]={&ar0,&ar1,&ar2,&ar3}; //Change the value of ar3[3] by s *(*(s+3)+3)=10;//*(*(s+3)+3)=10=>*(s[3]+3)=s[3][3]
A two-dimensional array is composed of multiple one-dimensional arrays
int arr[3][4] is composed of three one-dimensional arrays, and the size of each one-dimensional array is 4
-
When defining a two-dimensional array, the high order can be defaulted (arr[][4])
-
int ar[4]; sizeof(ar);//16 int* p = ar; int(*s)[4] = &ar;//The same type can store its array address int br[3][4]; sizeof(br);//48 int(*k)[4] = br;//The first element of a two-dimensional array is the address of a one-dimensional array int(*l)[3][4] = &br;
-
Two dimensional array parameter transfer
//void Print_arr_1(int **br, int row, int col)//error the low order of a two-dimensional array cannot be defaulted void Print_arr_2(int(*br)[3], int row, int col) { int size = sizeof(*(br[3])); printf("%d", size);//size=4 } int main() { int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; Print_arr_2(arr, 3, 3); return 0; }
12, Structure
-
User designed data types
struct Structure name { Member list (can be basic data type, pointer, array, other structure types) }
-
struct student { char id[20]; char name[20];//A variable in a structure is not assignable, and it is not allocated space int age; char sex[4]; };//; Is indispensable
Structure is a data type. The designed structure is a template for creating variables and does not occupy memory space. The variables declared in the structure are attributes.
-
int a;//Built in types can create variables struct student s1;//Structure types can also create variables
-
Initialization of structure
struct student { char id[20]; char name[20]; int age; char sex[4]; }; int main() { struct student s1={10001,"qiao",20,"man"};//The uninitialized part will be automatically zeroed, which is the same as the array; The initialization sequence shall be in accordance with the structure design sequence }
Both structure and array declaration need to use {}, but the data type stored in the array is the same, and the structure is not necessarily the same
-
struct studentA { const char*s_id; const char *s_name; const char *s_sex; int age; }; struct studentB { char id[20]; char name[20]; int age; char sex[4]; }; int main { struct studentA s1={10001,"qiao",20,"man"};//sizeof(s1)=16 struct studentB s2={10001,"qiao",20,"man"};//sizeof(s2)=48 }
-
Nesting of structures
struct date { int year; int month; int day; }; struct student { char id[20]; char name[20]; struct date birthdat; }; int main() { struct student s1={"10001","qiao",2001,12,4}; struct student s2={"10001","qiao",{2001,12,4}}; }
-
struct studentB { char id[20]; char name[20]; int age; char sex[4]; struct studentB s; }; struct studentC { char id[20]; char name[20]; int age; char sex[4]; struct studentB *s; }; int main() { struct studentB s1; //s1 is an incomplete type and sizeof cannot calculate its size struct studentC s2;//It can be compiled to define structure variables }
-
The structure needs to be accessed by '.' operator (Object Access), and the pointer uses - > to access
struct student { char name[20]; int age; char sex[5]; }; int main() { struct student s_1={"xiaotutou",19,"man"};//s_1 structure variable struct student s_2=s_1;//Structure variables can be assigned to each other struct student* p=&s_1;//Structure variable *p=s_1; printf("%s %d %s\n",s_1.name,s_1.age,s_1.sex); printf("%s", (*p).name); printf("%s", p->name);//- > (member pointer) when accessing with pointer return 0; }
```c struct student { char name[20]; int age; char sex[5]; }; void print_A(struct studnet s)//s 29 bytes { printf("%s",s.name); printf("%d",s.age); } void print_B(struct student *s) //4 bytes { printf("%s",s->name); printf("%d",s->age); ```
- Output of structure array
void Print_stu(struct student stu[], int n)//stu is the pointer, accounting for four bytes { assert(stu != NULL); for (int i = 0; i < n; i++) { //printf("%-8s % -8s %-8s %-8d", stu[i].s_no, stu[i].s_name ,stu[i].s_sex, stu[i].age);//- Align left //printf("%-8s % -8s %-8s %-8d", (*(stu+i)).s_no, (*(stu + i)).s_name, (*(stu + i)).s_sex, (*(stu + i)).age); printf("%-8s % -8s %-8s %-8d",stu->s_no,stu->s_name,stu->s_sex,stu->age); stu++; printf("\n"); } }
11, Reference (alias)
int main() { int a=10; int b=a; int &c=a;//A is c, c is also a, and their addresses are the same //Reference must be initialized. There is no empty reference //int &&b=c;// Is not feasible, there is no reference int &x=c; }
void swap(int &a,int &b) { int tem=a; a=b; b=tem; } int main() { int x=10; int y=20; } a by x Your alias, b by y Alias, so for a,b That's right x,y Exchange of.
12, Structure size and Consortium
-
Size of structure
- The first address of the structure variable must be an integer multiple of the byte occupied by the largest basic data type in the structure variable
- The offset of each member in the structure variable relative to the first address of the structure is an integer multiple of the bytes occupied by the basic data type of the member
- The total size of the structure variable is an integer multiple of the bytes occupied by the largest basic data type in the structure variable
struct sdata { int year; int month; int day; }; struct node { char s_id[10]; char s-name[8]; struct sdata birthady; double grade; };
Starting from the 0 address, the size of the structure is 40; s_ Although ID [10] is an array, the size of char calculated according to its basic data type size is 1. The basic data type int of data structure is still 4. The size of this structure is (10 + 8 + 2) + (4 + 4 + 4) + (8)
-
Consortium (Consortium)
In a consortium, all members share a space whose size is the longest length variable among the members.
-
Dummy element structure
Nameless structure
struct Node { char ch; union { int a; float f; }; };//The size of the structure is 8 struct Node { char ch; union Af { int a; float f; }; };//The structure size is 1. At this time, the union is of type, not an attribute
13, String
-
String must end with '\ 0'
-
int main() { int size = sizeof("copxyw"); printf("%d", size);//7 const char* sp = "copxyw"; char ch_1 = sp[1];//*(sp+1) ch_1==o char ch_2 = "copxyw"[1];//ch_2==o return 0; }
14, Recursive function
-
Divide and conquer strategy: divide a large-scale problem into the same small-scale problem
-
Recursion: function calls themselves
-
Recursive functions are divided into recursive and regression processes. The function recurses continuously during execution until the stop condition of recursion is executed, and then regresses. The stack frame is allocated continuously in the recursive process
-
When performing regression, you need to use return to store the value in the temporary space
15, Bit operation
-
int main() {//Integers can perform bit operations //Floating point and arbitrary pointer types cannot perform bit operations char a = 12;//0000 1100 char b = 27;//0001 1011 char c = 0; c = a & b;//(bit and) //c = a && b; (logical and) the result is 1, true c = a | b; //(bit or) //c = a || b; Concise or / logical or c = a ^ b;//XOR c = !a;//The logical inverse c is false, the value of a remains unchanged, and there is no assignment operation c = ~a;//Bit inversion a=a>>1;//Shift right one bit b=b<<1;//Shift left one bit }
-
When you want to set the bit of a bit of integer data to 1, set the number changed to 1 and its phase or to 0 and its phase and
char a=0;//To set the seventh bit of a to 1; //A = 0 = 0000 (1 byte = 8bit) a=a|0x80;//1000 0000 a=a|0x10;//1001 0000 //Set bit 4 to 0 a=a&0x80;//1000 0000
16, Library function
printf:
int len=printf("a=%d to b=%d\n",a,b);
Returns the length of the formatted string
scanf:
int s=scanf_s("%d %d",&a,&b)
The returned value is the number of correctly received data
17, Byte alignment problem
1. What is byte alignment
When reading and writing memory, the cup does not read byte by byte, but reads and writes memory in bytes multiple of 2, 4 and 8; 32-bit data can be read in one read cycle from the even address, while the 32-bit data can be obtained by reading two cycles from the odd address and splicing the data. The purpose of byte alignment is to improve efficiency. The alignment of different platforms is also different, and the information transmission process may be disordered.
2. Specify alignment values
The default number of alignments can be changed through the preprocessing instruction #pragma pack(n). N can be 1, 2, 4, 8, 16
#pragma pack (1) //size=17 #pragma pack (2) //size=18 #pragma pack (4) //size=20 #pragma pack (16) //size=24 //When the specified alignment value is larger than the largest basic type in the structure, the largest basic type in the structure is taken as the alignment value struct date { char year; int month; int day; double time; }; int main() { date d; int size = sizeof(d); printf("%d\n", size); return 0; }
18, Dynamic memory allocation malloc
-
Manually apply for a continuous memory space of a specified size from the heap using malloc function; free() is required to release after the application is completed
void *malloc (size_t size);//Allocate size by byte
int main() { int n = 0; int i = 0; int* ip = NULL; scanf_s("%d", &n); ip = (int*)malloc(sizeof(int) * n); if (NULL == ip) exit(1);//ip needs to be judged null for (int i = 0; i < n; i++) { ip[i] = i; } for (int i = 0; i < n; i++) { printf("%2d", ip[i]); } printf("\n"); free(ip);//At this time, ip is a null pointer ip = NULL;//After free, the ip still points to the first address of the open space, so you need to set the ip to null return 0; }
-
Although dynamic allocation is similar to array, it also has its own advantages. The size of array must be constant, and it cannot be run when its size exceeds the memory size of stack area. malloc is used to open up a continuous space, and its size can be customized, and scanf can be used for input. The size of the heap is much larger than the stack.
-
Four functions of dynamic memory management: malloc, calloc, realloc (to apply for space) and free (to release space)
-
When malloc application is successful, the pointer to newly allocated memory is returned. To avoid memory leakage, free() or realloc() must be used to reallocate the returned pointer; Null pointer will be returned if the application fails
-
The space applied by malloc has upper and lower bounds. Users can only use the space within the upper and lower bounds. The upper and lower bounds are the system default and cannot be modified
int main() { int* ip; ip = (int*)malloc(sizeof(int) * 5); if (ip == NULL) exit(1); for (int i = 0; i < 5; i++) { ip[i] = i; } return 0; }
-
int main() { int* ip = (int*)malloc(sizeof(int)); if (NULL == ip) exit(1);//We must judge the air space int* is = (int*)malloc(sizeof(int)); if (NULL == is) exit(1); *ip = 200; printf("%d\n", *ip); free(ip); //ip=NULL; *is = 1000; printf("%d\n", *ip); *ip = 100;//The ip still points to the first address of the space requested by malloc printf("%d\n", *ip); free(ip);//The same space cannot be a quadratic free space return 0; }//If the ip is not assigned NULL after free(ip), the ip will still point to the first address of the space opened up by malloc, and is may point to the same space as ip when opening up the space. As a result, ip and is can control this space at the same time, resulting in the danger of program hiding
-
malloc development space has header information (the size is 28 bytes), in which there is a mark for recording the size of development space. Therefore, when free is used, free can know how much space should be released, and the actual development space is larger than the real application space
-
Memory leak: when applying with malloc, the address of malloc space is lost, and if it is not released again, the pointer points to other addresses; Only malloc is not released, resulting in the use up of heap space
int main() { int* ip = (int*)malloc(sizeof(int)*5); if (NULL == ip) exit(1); int* ip = (int*)malloc(sizeof(int) * 10); } //Finally, only 40 bytes opened for the second time can be released, but the space opened for the first time cannot be released. Because its address is not recorded, it cannot be released and the address is lost
-
int *is=(int *)calloc(n,sizeof(int));
Assign a value to 0 in the open space
void *my_calloc(int num, int size) { void* vp = (void*)malloc(num * size); if (vp != NULL) { memset(vp, num, size);//memset(void *vp,int value,size num) } return vp; }
-
The difference between heap area and stack area:
difference Stack heap management style Automatically managed by the system Controlled by the programmer, it is easy to use, but easy to leak memory Growth direction Stack expansion to low address (bottom-up) The heap expands to high address, which is a discontinuous memory area Space size 1M or 10M Limited by virtual memory available in the computer Storage content After a function call, the local variable is out of the stack first, the instruction address is out of the stack, and finally the stack is balanced, and the execution continues downward from this point Heap is used to store data whose lifetime is independent of function, which is specifically managed by programmers Distribution mode The stack can be allocated statically or dynamically It can only be released dynamically and manually Distribution efficiency High; By the special register, the stack has special instructions Low; Provided by library functions, the mechanism is complex Fragmentation problem There is no fragmentation of the stack Heap space is released and allocated in a trivial way, resulting in discontinuous heap memory space, resulting in a large amount of fragmentation System response after allocation As long as the requested memory is less than the remaining memory of the stack, the system will provide memory for the program, otherwise an error will be reported
20, Documents
-
stdin //Standard input stream stdout //Standard output stream stderr //Standard error stream (display errors on screen, no buffer)
Note:
-
#include<assert.h> assert(sp!=NULL&&se!=NULL); //The following is the wrong way of writing assert(sp!=NULL)&&assert(se!=NULL); if(assert(sp!=NULL));
e+1
listnode* p = pl->head;
int i = 1;
while (pos > i)
{
p = p->next;
i++;
}
return p;
}
```c bool Insert_Node(linklist* pl, int pos, Elemtype val)//Insert node { assert(pl != NULL); listnode* p_per = Findpos_per(pl, pos); if (p_per == NULL) return NULL; listnode* p_insert = buynode(); p_insert->data = val; p_insert->next = p_per->next; p_per->next = p_insert; pl->cursize += 1; return true; }
[external chain picture transferring... (img-H63veAt8-1636506856289)]
bool Erase(linklist* pl, listnode* p_per) { if (p_per == NULL || p_per->next == NULL) return NULL; listnode* p_record = p_per->next; p_per->next = p_per->next->next; free(p_record); p_record = NULL; pl->cursize -= 1; return true; } void Erase_Node(linklist* pl, int pos)//Delete node { assert(pl != NULL); listnode* p_per = Findpos_per(pl, pos); Erase(pl, p_per); }
[external chain picture transferring... (img-cEiBpIl4-1636506856291)]
void Invert_list(linklist* pl)//Reverse of linked list (head insertion method) { assert(pl != NULL); if (pl->cursize < 2) return; listnode* p = pl->head->next; listnode* s = NULL; pl->head->next = NULL; while (p != NULL) { s = p; p = p->next; s->next = pl->head->next; pl->head->next = s; } }
20, Documents
-
stdin //Standard input stream stdout //Standard output stream stderr //Standard error stream (display errors on screen, no buffer)
/* stdin Standard input stream stdout Standard output stream stderr Standard error stream (display errors on screen, no buffer) scanf("%d",&a) stdin sscanf(buff ,"%d",&a) fscanf(fp,"%d",&a) Serialization and deserialization??? */ int main() { //char ch; char ch[10]; FILE* fp = NULL; errno_t res = fopen_s(&fp, "2021-7-16.cpp", "r"); if (fp == NULL) { printf("fopen file error %d\n", res); return 1; } while (!feof(fp))//Not to the end { //ch = fgetc(fp); fgets(ch, 10, fp); printf("%s", ch); Sleep(200); } fclose(fp); fp = NULL; return 0; } int main() { char buffa[128]; char buffb[128]; scanf_s("%s", buffa,128);//Space as input Terminator fgets(buffb, 128, stdin);//Enter as input Terminator return 0; } int main() { char ch = '\0'; ch = getchar();//stdin ch = fgetc(stdin); } int main() { int ar[10]; FILE* fp = NULL; errno_t res = fopen_s(&fp, "qch.txt", "r"); if (fp == NULL) { printf("fopen file error %d\n", res); return 1; } for (int i = 0; i < 10; i++) { fread(ar, sizeof(int), 10, fp); }//The data is now in the buffer fclose(fp);//Write data to file fp = NULL; return 0; } int main() { //Binary write int ar[] = { 10,20,30,40,50,60,70,80,90,100 }; int size = sizeof(ar) / sizeof(ar[0]); FILE* fp = NULL; errno_t res = fopen_s(&fp, "qch.txt", "wb"); if (fp == NULL) { printf("fopen file error %d\n", res); return 1; } fwrite(ar, sizeof(int), size, fp); //The data is now in the buffer fclose(fp);//Write data to file fp = NULL; return 0; } int main()//read { int ar[10] ; FILE* fp = NULL; errno_t res = fopen_s(&fp, "qch.txt", "r"); if (fp == NULL) { printf("fopen file error %d\n", res); return 1; } for (int i = 0; i < 10; i++) { //fprintf(fp, "%d ", ar[i]); //fscanf(stdin,"%d", &ar[i]); fscanf_s(fp, "%d", &ar[i]); }//The data is now in the buffer fclose(fp);//Write data to file fp = NULL; return 0; } int main()//write { int ar[] = { 10,20,30,40,50,60,70,80,90,100 }; int size = sizeof(ar) / sizeof(ar[0]); FILE* fp = NULL; errno_t res= fopen_s(&fp,"qch.txt", "w"); if (fp == NULL) { printf("fopen file error %d\n", res); return 1; } for (int i = 0; i < size; i++) { //printf("%d", ar[i]); fprintf(fp, "%d ", ar[i]); }//The data is now in the buffer fclose(fp);//Write data to file fp = NULL; return 0; } int main() { int a = 10, b = 20; char buff[30]; int len = sprintf_s(buff, 30, "a=%d b=%d\n", a, b);//The formatted string is stored in the buff len = printf("a = % d b = % d\n", a, b);//The formatted string is output to the screen len = fprintf(stdout, "a= % d b = % d\n", a, b);//Display on standard output device, same function as printf /*float fa = 20.5, fb = 36.3; len = sprintf_s(buff, 30, "fa=%f fb=%f\n", fa, fb);*/ return 0; } int main() { //File operation (1. Open the file and leave it blank 2. Read and write the file 3. Close the file) int printf(const char* str, ...);//... is a variable parameter int sprintf(char* buff, const char* ptr); int fprintf(FILE * fp, const char* ptr); }