catalogue
Knowledge point 1 [overview of storage] (understand)
Knowledge point 2 [general local, general global, static local, static global] (important)
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)
Knowledge point 4 [gcc compilation process] (understand)
Knowledge point 5 [include header file contains] (understand)
1. Why should header files be included to improve development efficiency
Knowledge point 6 [macro #define] (understand)
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)
2. #ifndef test does not exist
3. #if xxx conditional compilation
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
Use the static library: libtestlib a. Header file mylib H to users
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