C_ Pretreatment (intensive lecture)

Posted by timmytock on Sat, 22 Jan 2022 10:54:15 +0100

catalogue

Knowledge point 1 [overview of storage] (understand)

Knowledge point 2 [general local, general global, static local, static global] (important)

1. Ordinary local variable

2. General global variable

3. Static local variable

4. Static global variable

Knowledge point 3 [global function, static function] (important)

1. Global function (the default function is global function)

2. Static function (add static when defining the function)

Comprehensive case:

Knowledge point 4 [gcc compilation process] (understand)

One step:

Knowledge point 5 [include header file contains] (understand)

1. Why should header files be included to improve development efficiency

2. include usage form

Knowledge point 6 [macro #define] (understand)

Macro benefits:

2. Macro with parameters (difficulty)

3. Scope of macro: the whole source file

4. Defects of macro (macro function) with parameters

1. Macros cannot guarantee the integrity of parameters

5. Advantages of macro with parameters (macro function)

Function calling process: the overhead of entering and leaving the stack is required

Differences between macro with parameters and function with parameters:

6. Try to put macros in header files

Knowledge point 7 [conditional compilation] (understand)

1. #ifdef test exists

2. #ifndef test does not exist

3. #if xxx conditional compilation

Knowledge point 8 [conditional compilation to prevent repeated inclusion of header files] (understand)

Introduction of knowledge points:

Solution 1: windows mode: #pragma once

#pragma once contains only once

Solution 2: Linux mode: #ifndef

Knowledge point 9 [production of static database and dynamic database] (understand)

1. Introduction of knowledge points

preparation:

2. Make static library

Use the static library: libtestlib a. Header file mylib H to users

3. Make dynamic library

Knowledge point 1 [overview of storage] (understand)

In a 32-bit system, the addressing range of each process is 4G, 0x00 ~ 0xff

In a 64 bit system, the addressing range of each process is 128G, 0x00 00 00 00 00 00 ~ 0xff ff ff ff

Knowledge point 2 [general local, general global, static local, static global] (important)

1. Ordinary local variable

Definition form: ordinary variables defined in {} compound statements are ordinary local variables.

void test01()
{
    int num;//Ordinary local variable
}

Scope: the nearest {} compound statement

void test01()
{
    {
        int num1 = 10;//Ordinary local variable
        printf("num1 = %d\n", num1);//Can identify
    }
    printf("num1 = %d\n", num1);//Unrecognized num1
}

Life cycle: at the end of the nearest {} compound statement, the system will release ordinary local variables.

Storage area: stack area

matters needing attention:

1. Ordinary local variables are not initialized, and the content is uncertain

2. In special cases, local variables can use the principle of proximity

3. The compound statement {} ends and the normal local variable is released

2. General global variable

Definition form: variables defined outside the {} compound statement are ordinary global variables.

int num2;//global variable
void test02()
{
}

Scope: all source files are recognized

Lifecycle: entire process

Storage area: Global Area

matters needing attention:

1. The global variable is not initialized, and the content is 0

2. It will not be released until the end of the whole process

3. The use of other source files must be declared with extern first

4. Local variables are preferred when global variables and local variables have the same name

00_fun.c

int num3 = 100;

00_test.c

extern int num3;//statement
int num2;//global variable
void test02(){
     printf("num2 = %d\n", num2);//0
     printf("num3 = %d\n", num3);//100  
}

3. Static local variable

Definition form: ordinary variables defined and decorated with static in {} compound statements are static local variables.

void test04(){
    //Static local variable
    static int num5 = 200;
}

Scope: between compound statements {} statements

void test04(){
    //Static local variable
    {
        static int num5 = 200;
    }
    printf("num5 = %d\n", num5);//Unrecognized
}

Lifecycle: entire process

Access area: Global Area

matters needing attention:

1. Static local variables are not initialized, and the content is 0

2. The scope of action can only be between {}

3. The whole process of life cycle

4. Only the first definition and initialization of static local variables are valid

4. Static global variable

Definition form: variables defined outside {} compound statements and decorated with static are static global variables.

//static global
static int data1 = 100;
void test06()
{

}

Scope: valid only in the current source file

Life cycle: the whole process

Access area: Global Area

matters needing attention:

1. Static global variables cannot be used directly in other source files, and adding extern is not easy

Knowledge point 3 [global function, static function] (important)

1. Global function (the default function is global function)

Can be identified in all source files.

2. Static function (add static when defining the function)

Can only be used in the current source file

02_fun.c

#include <stdio.h>
//The global function , only needs an extern declaration , and can be used externally
void my_printf01(void)
{
    printf("Global function I'm at 02_fun.c in\n");
    return;
}

//Static functions {can only be used in the current source file
static void my_printf02(void)
{
    printf("Static function I'm at 02_fun.c in\n");
    return;
}

02_test.c

#include <stdio.h>
extern void my_printf01(void);
extern void my_printf02(void);

int main(int argc, char const *argv[])
{
    my_printf01();
    my_printf02();//Unrecognized
    
    return 0;
}

Comprehensive case:

Knowledge point 4 [gcc compilation process] (understand)

Preprocessing, compilation, assembly, linking

Preprocessing: header file inclusion, macro replacement, conditional compilation, deletion of comments (no syntax check)

gcc -E hello.c -o hello.i 1,Pretreatment

Compile: compile the preprocessed file into an assembly file (syntax check)

gcc -S hello.i –o hello.s 2,compile

Assembly: generate assembly files into binary files

gcc -c hello.s -o hello.o 3,assembly

Connect: connect all o file + library function + startup code are packaged as an executable file

gcc hello.o -o hello_elf 4,link

One step:

gcc 03_test.c -o 03_test   Generated is 03_test
gcc 03_test.c    generate a.out

Knowledge point 5 [include header file contains] (understand)

1. Why should header files be included to improve development efficiency

2. include usage form

#Include < > / / include the header file in angle brackets. Find the header file in the path specified by the system 
#Include "" / / include the header file in double quotation marks. First find the header file in the current directory, and then find it in the path specified by the system

Recommendations:

The header file of the system uses #include < >

Custom header files use #include ""

Knowledge point 6 [macro #define] (understand)

Macro names are recommended to distinguish between uppercase and normal variables.

Macro benefits:

The preprocessing phase completes macro replacement

#include <stdio.h>

#define N 1000
#define STR "hello world"
#define PI 3.14f

void test01(){
    printf("N = %d\n", N);
    printf("STR = %s\n", STR);
    printf("PI = %f\n", PI);

    int arr1[N];
    int arr2[N];
    int arr3[N];
    int arr4[N];   
    int arr5[N];
}

int main(int argc, char const *argv[])
{
    test01();
    return 0;
}

2. Macro with parameters (difficulty)

Parameters in macros with parameters have no type (remember)

#define MY_MUL(a,b)   a*b
#define MY_MUL(a, b) a*b
void test01()
{
   printf("%d\n", MY_MUL(10, 20));// 10*20
   printf("%d\n", MY_MUL(100, 200));// 100*200
   printf("%d\n", MY_MUL(300, 400));// 300*400
}

Macros with parameters are also called "macro functions": macros only call like functions, not functions in essence

3. Scope of macro: the whole source file

Macros have no concept of scope.

End macro scope: #undef macro name

4. Defects of macro (macro function) with parameters

1. Macros cannot guarantee the integrity of parameters

#define MY_MUL(a, b) a*b
void test01()
{
   printf("%d\n", MY_MUL(10+10, 20+20));//10+10*20+20==230
}

Solution: add () to the parameters in the expression

#define MY_MUL01(a, b) a*b
#define MY_MUL02(a, b) ((a)*(b))
void test01()
{
   printf("%d\n", MY_MUL01(10+10, 20+20));//10+10*20+20==230
   printf("%d\n", MY_MUL02(10+10, 20+20));//((10+10)*(20+20))==800
}

Adding () in special cases can not guarantee the integrity of parameters

#define GET_MAX_DATA(a, b) ((a)>(b)?(a):(b))
void test02()
{
    int a = 3;
    int b = 5;
    //((a)>(++b)? (a) : (+ + b)) cannot guarantee the integrity of parameters
    printf("The maximum value is:%d\n", GET_MAX_DATA(a,++b));//7
}

5. Advantages of macro with parameters (macro function)

Function calling process: the overhead of entering and leaving the stack is required

Macro function: only replace the position of the macro in the preprocessing stage, without the overhead of entering and leaving the stack

Differences between macro with parameters and function with parameters:

The macro with parameters will be expanded as many times as it is called. There is no function call process when executing the code, and there is no need to press the stack. Therefore, macro with parameters wastes space and saves time.

For functions with parameters, there is only one copy of the code in memory. There is a code segment. When calling, you need to press the stack to get instructions from the code segment. Therefore, the function with parameters wastes time and saves space.

Functions with parameters are typed. Formal parameters of macros with parameters do not have type names.

6. Try to put macros in header files

#define SET_BITS(data, n)   ((data)|=(0x01<<(n)))
#define CLEAR_BITS(data, n)  ((data)  &= ~(0x01<<(n)))

Knowledge point 7 [conditional compilation] (understand)

Introduction of knowledge points:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char buf[128]="helloWORLD";

    //Function 1: change lowercase to uppercase
    if(OK)
    {
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='a' && buf[i] <='z')
                buf[i] -= 32;
            i++;
        }
    }
    else//Function 2: change uppercase to lowercase
    {
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='A' && buf[i] <='Z')
                buf[i] += 32;
            i++;
        }
    }
    printf("%s\n", buf);
    return 0;
}

1. #ifdef test exists

Source code:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char buf[128]="helloWORLD";

    //Function 1: change lowercase to uppercase
    #ifdef OK
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='a' && buf[i] <='z')
                buf[i] -= 32;
            i++;
        }
    #else / / function 2: change uppercase to lowercase
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='A' && buf[i] <='Z')
                buf[i] += 32;
            i++;
        }
    #endif
    printf("%s\n", buf);
    return 0;
}

2. #ifndef test does not exist

Source code:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char buf[128]="helloWORLD";

    //Function 1: change lowercase to uppercase
    #ifndef OK
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='a' && buf[i] <='z')
                buf[i] -= 32;
            i++;
        }
    #else / / function 2: change uppercase to lowercase
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='A' && buf[i] <='Z')
                buf[i] += 32;
            i++;
        }
    #endif
    printf("%s\n", buf);
    return 0;
}

3. #if xxx conditional compilation

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char buf[128]="helloWORLD";

    //Function 1: change lowercase to uppercase
    #if OK
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='a' && buf[i] <='z')
                buf[i] -= 32;
            i++;
        }
    #else / / function 2: change uppercase to lowercase
        int i=0;
        while(buf[i] != '\0')
        {
            if(buf[i]>='A' && buf[i] <='Z')
                buf[i] += 32;
            i++;
        }
    #endif
    printf("%s\n", buf);
    return 0;
}

Knowledge point 8 [conditional compilation to prevent repeated inclusion of header files] (understand)

Introduction of knowledge points:

06_a.h

#include "06_b.h"
int num_a = 2000;

06_b.h

int num_b=1000;

06_fun.c

#include <stdio.h>
#include "06_a.h"
#include "06_b.h"

int main(int argc, char const *argv[])
{
    printf("num_a = %d\n", num_a);
    printf("num_b = %d\n", num_b);
    
    return 0;
}

Solution 1: windows mode: #pragma once

#pragma once contains only once

Solution 2: Linux mode: #ifndef

06_a.h

#ifndef __06_A_H__
#define __06_A_H__

#include "06_b.h"
int num_a = 2000;

#endif 

06_b.h

#ifndef __06_B_H__
#define __06_B_H__
int num_b=1000;
#endif

Knowledge point 9 [production of static database and dynamic database] (understand)

1. Introduction of knowledge points

07_test.c

#include <stdio.h>
int main(int argc, char const *argv[])
{
    printf("hello world\n");
    return 0;
}

preparation:

main.c

#include <stdio.h>
#include "mylib.h"
int main(int argc, char const *argv[])
{
    printf("%d\n", my_add(10,20));
    printf("%d\n", my_sub(10,20));
    printf("%d\n", my_mul(10,20));
    printf("%d\n", my_div(10,20));
    
    return 0;
}

mylib.c

int my_add(int a, int b)
{
    return a+b;
}

int my_sub(int a, int b)
{
    return a-b;
}
int my_mul(int a, int b)
{
    return a*b;
}
int my_div(int a, int b)
{
    return a/b;
}

 mylib.h

#ifndef __MYLIB_H__
#define __MYLIB_H__

extern int my_add(int a, int b);
extern int my_sub(int a, int b);
extern int my_mul(int a, int b);
extern int my_div(int a, int b);

#endif

2. Make static library

gcc -c mylib.c -o mylib.o
ar rc libtestlib.a mylib.o  
Note: static libraries must be named with lib Start with.a ending

Use the static library: libtestlib a. Header file mylib H to users

1. Put the static library and header files into the source file directory

2. Put the static library and header files into the specified directory

3. Put the static library and header files in the system directory

Put static library in / lib

Put header file in / usr/include

3. Make dynamic library

Make dynamic link library: GCC - shared mylib c -o libtestlib. So / / compile and create dynamic link libraries using gcc

1. The dynamic library and header files are placed in the source file directory

There is no problem in compiling and running. The reason for the error is that it is not linked to the dynamic library (running on the terminal)

export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH

2. The dynamic library and header files are placed in the specified directory

export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH

3. Put the dynamic library and header file into the system directory

Dynamic library in / lib

Put header file in / usr/include

If both static and dynamic libraries exist, the default dynamic compilation is required. If static compilation is required, add static