C language learning notes

Keywords: C

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 characterfunctionASCII
\nNewline character10
\rCarriage return13
\tHorizontal tab9
\0001 ~ 3 are characters represented by octal
char ch='\''//Single quotation mark
char ch = '0' (character 0)ASCII 48
char ch=00(false)
char ch = '\ 0' (empty character)0(false)
char ch='a'97
int *p=NULL0(false)
  • The string ends with '\ 0'
characterASCII
'(space)32
'0'48
A65
a97
enterCR
Line feedLF

4, Scope and lifetime

Code area
Data area
Heap area
Stack area

1. Scope

  1. 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.

  2. When a global variable scope is defined, it is visible to the statements below it

  3. 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)

  1. 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)

  2. 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.

  3. Global variables are stored in the data area and local variables are stored in the stack area.

  4. Global variables are stored in the data area before the main function is executed and released after the program is completed

  5. 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

  1. Operate on operands accordingly
  2. Classification: unary operator, binocular operator, and binocular operator
  3. The ternary operator solves simple if statements ((a > b)? A: b)

1. Front and rear++

  1. ++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
    
  2. 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

  1. Data type keyword:

    Char int short float double signed unsigned struct union enum typedef sizeof auto static register extern const volatile

  2. 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

  1. static keyword can extend the production cycle of variables and store them in the data area

  2. 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

  1. 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

  1. There are many kinds of true (non-0) in c language, but only 0 is false
  2. The bool type has only two values, true and false
  3. bool type one byte 0000 000 0 the last bit is used to indicate true or false
  4. 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

  1. A switch statement is a multi branch statement

    switch(Integer variable expression)
    {
        case constant:Statement block
            break;
        default:
            break;
    }
    
  2. 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

  1. For (expression 1; expression 2; expression 3)

    {loop statement}

  2. 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

  1. Empty statements consist only of semicolons and do nothing

    int a=10; ;
    
  2. 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

  1. 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);
      }
      
  2. 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)
  3. 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);
    }
    
  4. 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

  1. 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
    
  2. Arrays are stored continuously in memory

  3. 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]);
    
  4. 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

  1. Pointer variable is a variable used to access the storage address (storage address); A pointer is the address of memory

  2. No matter what type of pointer, the size is 4 bytes (under 32-bit platform).

  3. Pointers are divided into wild pointers (declared but uninitialized) and null pointers (initialized to null)

  4. *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
    
  5. 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)
    
  6. A pointer has two values, one is its own value (stored address) and the other is the value it points to (dereference)

  7. 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;
}
  1. 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

  1. 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.

  2. Add one to a type pointer to increase the bytes occupied by the type

  3. 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.
    

  4. 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

  1. void cannot define variables, but can define pointer variables

  2. 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;
    }
    
  3. 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.

  1. 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

    sint**(type)
    *sint*
    **sint
  2. 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

  3. 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];
    
  4. 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
    
  5. 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

  6. When defining a two-dimensional array, the high order can be defaulted (arr[][4])

  7.     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;
    
  8. 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

  1. User designed data types

    struct Structure name
    {
        Member list (can be basic data type, pointer, array, other structure types)
    }
    
  2. 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.

  3. int a;//Built in types can create variables
    struct student s1;//Structure types can also create variables
    
  4. 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

  5. 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
    }
    
  6. 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}};
    }
    
  7. 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
    }
    
  8. 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);

```
  1. 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

  1. 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)

  2. Consortium (Consortium)

    In a consortium, all members share a space whose size is the longest length variable among the members.

  3. 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

  1. String must end with '\ 0'

  2. 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

  1. Divide and conquer strategy: divide a large-scale problem into the same small-scale problem

  2. Recursion: function calls themselves

  3. 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

  4. When performing regression, you need to use return to store the value in the temporary space

15, Bit operation

  1. 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
    }
    
  2. 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:

    differenceStackheap
    management styleAutomatically managed by the systemControlled by the programmer, it is easy to use, but easy to leak memory
    Growth directionStack expansion to low address (bottom-up)The heap expands to high address, which is a discontinuous memory area
    Space size1M or 10MLimited by virtual memory available in the computer
    Storage contentAfter 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 pointHeap is used to store data whose lifetime is independent of function, which is specifically managed by programmers
    Distribution modeThe stack can be allocated statically or dynamicallyIt can only be released dynamically and manually
    Distribution efficiencyHigh; By the special register, the stack has special instructionsLow; Provided by library functions, the mechanism is complex
    Fragmentation problemThere is no fragmentation of the stackHeap 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 allocationAs 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

  1. stdin //Standard input stream
    stdout //Standard output stream
    stderr //Standard error stream (display errors on screen, no buffer)
    

Note:

  1. #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

  1. 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);
}

Posted by michelledebeer on Wed, 10 Nov 2021 15:06:56 -0800