当前位置:网站首页>Hello C (IV) -- pointer and function
Hello C (IV) -- pointer and function
2022-06-24 23:42:00 【Tianshan old demon】
Pointers make a huge contribution to the function , A pointer can pass data to a function , And it allows the function to modify the data . The function of pointer to function mainly has two aspects : Passing pointers to functions and declaring function pointers .
One 、 Stack and heap of programs
The stack and heap of programs are C Runtime elements for language program running .
1、 Program stack
A program stack is an area of memory that supports function execution , It usually shares a memory area with the heap , Usually the program stack occupies the lower part of the memory area , The upper part of the heap memory area . The program stack stores stack frames , Stack frame stores function parameters and local variables . When you call a function , The stack frame of the function is pushed onto the stack , A stack frame grows up the stack , When the function terminates , The stack frame of the function pops up from the program stack , Memory used by stack frames will not be cleaned up , But it may be covered by the stack frame of another function on the program stack . Dynamically allocated memory comes from the heap , Heap down growth , With the allocation and release of memory , The heap will be full of debris . Although the heap grows downward , But it's just a general direction , The actual memory may be allocated anywhere on the heap .
2、 Stack frame
Composition of stack frame :
A、 The return address
The internal address of the program to be returned after the function is completed
B、 Local data storage
Memory allocated for local variables
C、 Parameter storage
Memory allocated for function parameters
D、 Stack pointer and base pointer
The pointer used by the runtime system to manage the stack
The stack pointer usually points to the top of the stack , Base pointer ( Frame pointer ) Usually exists and points to the address inside the stack frame
Two 、 The pointer and the data are passed through
1、 Passing data with a pointer
In the function, the pointer variable is used as a parameter to pass data, and the data can be modified in the function , If you do not need to modify the data , The pointer variable is limited to const type . Typical function applications are as follows :
char *strcpy(char *dest, const char *src);If a function passes data by value , The data cannot be modified in the function .
2、 Return pointer
The return pointer needs to return a pointer of a data type .
There is a problem with returning pointers from functions :
A、 Returns an uninitialized pointer
B、 Returns a pointer to an invalid address .
C、 Returns a pointer to a local variable
D、 Returns a pointer but does not free memory
Return dynamically allocated memory from function , The memory must be released after it is used up , Otherwise, memory leakage will occur .
A function that returns a pointer to local data or a local variable is wrong , When the function returns , The stack frame of the local data will be ejected from the program stack , The data stored in the stack frame is easily overwritten by the stack frame of subsequent function calls . By declaring a local variable as static type , Local data can be 、 The scope of a variable is limited within a function , But the allocation is out of the stack (data Data segment ), Local data can be avoided 、 Variables are overwritten by stack frames of other functions .
3、 The pointer passing the pointer
When passing a pointer to a function , What is passed is the value of the pointer variable , If you need to modify the original pointer instead of a copy of the pointer variable , You need to pass the pointer to the pointer .
4、 Evaluation order of function parameters
The evaluation order of function parameters depends on the implementation of the compiler .
GCC compiler
#include <stdio.h>
void fun(int i, int k)
{
printf("%d %d\n", i, k);
}
int main(int argc, char *argv[])
{
int k = 1;
int i = 1;
int j = 1;
int l = 1;
j = j++ + j++;//j = 4
l = ++l + ++l;//l = 6
fun(++k,++k);//3,3
fun(i++,i++);//2,1
return 0;
}Stack order of function parameters
When a function call occurs , Parameters are passed to the called function , The return value is returned to the function caller .
Function calling conventions describe how function parameters are passed to the stack and how the stack is maintained .
The calling convention is used for library calling and library development .
Stack from right to left :__stdcall, __cdecl, __thiscall
Stack from left to right :__pascal, __fastcall
When C Language calls other languages such as pascal Language library functions need to display the declaration calling convention .
5、 Functions with variable parameters
C Functions with variable parameters can be defined in language , The implementation of variable parameter functions depends on stdarg.h The header file .
va_list: Parameter set
va_arg: Take the specific parameter value
va_start: Identify the start of the parameter
va_end: Identifies the end of the parameter
Variable parameters must be accessed sequentially from beginning to end
At least one definite named parameter must exist in the parameter list
Variable argument function cannot determine the number of arguments that actually exist
Variable argument function cannot determine the actual type of argument ,va_arg If the wrong parameter type is specified, the structure will be indeterminate .
#include <stdio.h>
#include <stdarg.h>
float average(int n, ...)
{
va_list args;
int i = 0;
float sum = 0;
va_start(args, n);
for(i=0; i<n; i++)
{
sum += va_arg(args, int);
}
va_end(args);
return sum / n;
}
int main()
{
printf("%f\n", average(5, 1, 2, 3, 4, 5));
printf("%f\n", average(4, 1, 2, 3, 4));
return 0;
}3、 ... and 、 A function pointer
A function pointer is a pointer variable that holds the address of a function , Pointer variables to function addresses .
1、 Function type
C Functions in a language have their own types , The type of the function is determined by the return type 、 The type and number of parameters determine .
adopt typedef Function types can be renamed .
typedef type func(parameter list);Code instance :
#include <stdio.h>
typedef int func(int a);
int test(int a)
{
printf("test\n");
}
int main(int argc, char *argv[])
{
func *f;
f = test;
(*f)(1);
return 0;
}2、 Declaration of function pointer
Use function type declarations :
typedef int func(int a);
fun *f;The general format of function pointer declaration is :
data type (* Pointer variable name )();
void * fun(void);// return void* Function of type pointer
void (*pFun)(void);// A function pointer
void *(*pFun)(void *, void *);// A function pointer
typedef void(*Fun)(void);// Define a function pointer type Fun
Fun pfun = fun;// Will function fun The address of is assigned to the function pointer pfun
Fun pfun = &fun;// Will function fun The address of is assigned to the function pointer pfun
void *(*pf[5])(void);// Function pointer array 3、 The use of function pointers
The general flow of calling function pointers :
A、 Define function pointer variables
B、 The entry address of the called function ( Function name ) Give the function a pointer variable
C、 Call functions in the form of function pointer variables
D、 The general form of calling a function in the form of a function pointer variable is :(* Pointer variable name ) ( Argument list )
Function calls and function pointer variables are called as follows :
fun();// Function call
(*fun)();// Call a function as a function pointer variable
(**fun)();// Call a function as a function pointer variable
pfun();// Call a function as a function pointer
(*pfun)();// Call a function as a function pointer
(**pfun)();// Call a function as a function pointer Function pointer variables cannot perform arithmetic operations , The offset of the function pointer is meaningless . Function call (* Pointer variable name ) There must be brackets around , Among them * It should not be understood as an evaluation operation ,* It's just a symbol .
Function pointer is the key technology to realize callback function , The jump of fixed address can be realized in the program .
4、 Pass function pointer
Pass the function pointer variable as the parameter of the function , Make the program code more flexible .
int add(int num1, int num2)
{
return num1 + num2;
}
int sub(int num1, int num2)
{
return num1 - num2;
}
typedef int (*pFun)(int, int);
int compute(pFun operation, int num1, int num2)
{
return operation(num1, num2);
}
compute(add, 5, 6);
compute(sub, 10,2);add、sub The address of the function is passed to compute Function as parameter ,compute Use add、sub The address of the function calls the corresponding operation .
5、 Return function pointer
To return a function pointer, you need to declare the return type of the function as a function pointer .
int add(int num1, int num2)
{
return num1 + num2;
}
int sub(int num1, int num2)
{
return num1 - num2;
}
typedef int (*pFun)(int, int);
pFun select(char opcode)
{
switch(opcode)
{
case ‘+’:
return add;
case ‘-’:
return sub;
}
}
int evaluate(char opcode, int num1, num2)
{
pFun operation = select(opcode);
return operation(num1, num2);
}
evaluate(‘+’, 5, 6);
evaluate(‘-’, 10, 6);By entering one character and two operands, the corresponding calculation can be carried out
6、 The function pointer array uses
The function pointer array can select the function to execute based on certain conditions , The function pointer array is declared as follows :
First statement :
typedef int (*operation)(int, int);
operation operations[128] = {NULL};Second statement :
int (*operations[128]) (int, int) = {NULL};After the function pointer array is declared, a certain type of operation function can be assigned to the array .
operations[‘+’] = add;
operations[‘-’] = sub;
int evaluate_array(char opcode, int num1, num2)
{
pFun operation = operations[opcode];
return operation(num1, num2);
}
evaluate_array(‘+’, 6 ,9);7、 Function pointer conversion
Convert pointer variables to other types of pointer variables . There is no guarantee that function pointers and data pointers will work properly after being converted to each other .
Four 、 Functions and macros
Macros are expanded directly by the preprocessor , The compiler does not know the existence of macros , Functions are entities compiled directly by the compiler , The calling behavior is determined by the compiler . Using macros multiple times can lead to a larger executable size , The function is executed by jumping , Only one function body exists in memory . Macros are more efficient , No call overhead ; Activity records are recorded when the function is called , There is a call overhead .
Macros are more efficient than functions , But macros are text substitutions , Parameter type cannot be checked , Therefore, functions that can be completed with functions must not use macros , And recursive definitions cannot be used in macro definitions .
The sample code :
#include <stdio.h>
#include <malloc.h>
#define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
#define FREE(p) (free(p), p=NULL)
#define LOG_INT(i) printf("%s = %d\n", #i, i)
#define LOG_CHAR(c) printf("%s = %c\n", #c, c)
#define LOG_FLOAT(f) printf("%s = %f\n", #f, f)
#define LOG_POINTER(p) printf("%s = %p\n", #p, p)
#define LOG_STRING(s) printf("%s = %s\n", #s, s)
#define FOREACH(i, n) while(1) { int i = 0, l = n; for(i=0; i < l; i++)
#define BEGIN {
#define END } break; }
int main()
{
int* pi = MALLOC(int, 5);
char* str = "D.T.Software";
LOG_STRING(str);
LOG_POINTER(pi);
FOREACH(k, 5)
BEGIN
pi[k] = k + 1;
END
FOREACH(n, 5)
BEGIN
int value = pi[n];
LOG_INT(value);
END
FREE(pi);
LOG_POINTER(pi);
return 0;
}5、 ... and 、 Recursive function
Recursion is a kind of autonomous thought in mathematics . Recursion needs to have boundaries , When the boundary conditions are not satisfied , Recursion continues ; When the boundary conditions are satisfied , Recursive termination .
A recursive function is a function that calls itself within a function body , It is the application of recursive mathematics in programming . Recursive functions must have recursive exits , A function without a recursive exit will result in infinite recursion , Cause the program stack to overflow and crash .
A general representation of a recursive model :

1、 Recursive implementation of the string length function
int strlen_r(const char* s)
{
if( *s )
{
return 1 + strlen_r(s+1);
}
else
{
return 0;
}
}2、 Fibonacci sequence solution
The Fibonacci sequence is expressed as follows :1,1,2,3,5,8,13,21,...

int fac(int n)
{
if( n == 1 )
{
return 1;
}
else if( n == 2 )
{
return 1;
}
else
{
return fac(n-1) + fac(n-2);
}
return -1;
}3、 Recursively implement the Hanover tower
The hanotta problem
With the help of B Column by A The column moved to C column
You can only move one block at a time
Small blocks can only be placed on top of large blocks

resolvent :
take n-1 A block of wood C Column by A The column moves to B column
Move the bottom wooden block directly to C column
take B On the column n-1 Songmu block with the help of A Column by B The column moves to C column
#include <stdio.h>
void han_move(int n, char a, char b, char c)
{
if( n == 1 )
{
printf("%c --> %c\n", a, c);
}
else
{
han_move(n-1, a, c, b);
han_move(1, a, b, c);
han_move(n-1, b, a, c);
}
}
int main()
{
han_move(3, 'A', 'B', 'C');
return 0;
}6、 ... and 、 Function design principles
General principles of function design :
A、 Function is a function independent module
B、 The function name should reflect the function of the function to a certain extent
C、 The function parameter name should reflect the meaning of the parameter
D、 Try to avoid using global variables in functions
E、 When function parameters should not be modified in function memory , Parameters should use const Statement
F、 If the parameter is a pointer , And only used as input parameters , Parameters should use const Statement
G、 The return value of a function cannot be omitted , No return value should declare the bit void
H、 Check the validity of the parameters , It is important to check the validity of pointer parameters
I、 Do not return a pointer to stack memory , The function in the stack will be released automatically when it ends
J、 The size of the function should be small , Try to control 80 inline
K、 Functions avoid having too many arguments , Control in 4 Within the number of adopted
边栏推荐
- Tremblement de terre réel ~ projet associé unicloud
- 选择类排序法
- Nominal resistance table of patch resistors with 5% and 1% accuracy
- 7-5 maximal submatrix sum problem
- Go shopping
- Hydropower project construction scheme based on 3D GIS Development
- Harmonyos accessing database instances (3) -- use ORM bee to test how good harmonyos is
- 如何化解35岁危机?华为云数据库首席架构师20年技术经验分享
- Andersen Global借助巴勒斯坦成员公司加强中东平台
- [JS] - [array application] - learning notes
猜你喜欢

openGauss内核:简单查询的执行

Ethernet ARP Protocol

Adding, deleting, querying and modifying MySQL tables

SAP PA certificate for no birds, which can be tested by new peers

Morris遍历

Hyperledger Fabric 2. X dynamic update smart contract

Stm32f030f4 reading infrared remote control data

JS listens for page or element scroll events, scrolling to the bottom or top

Volcano成Spark默认batch调度器
![[JS] - [string - application] - learning notes](/img/dc/f35979b094f04c0ee13b3354c7741d.png)
[JS] - [string - application] - learning notes
随机推荐
Window system installation Nacos
7-7 数字三角形
372. chessboard coverage
HarmonyOS访问数据库实例(3)--用ORM Bee测下HarmonyOS到底有多牛
Monotone stack and its application
安装IBM CPLEX学术版 academic edition | conda 安装 CPLEX
Jetpack Compose 最新进展
Yyds dry goods counting uses xshell to implement agent function
STM32CubeIDE SWV功能使用方法
7-9 treasure hunt route
企业数据防泄露解决方案分享
R language uses the multinom function of NNET package to build an unordered multi classification logistic regression model, and uses the AIC function to compare the AIC values of the two models (simpl
Harmonyos accessing database instances (3) -- use ORM bee to test how good harmonyos is
Tiktok actual combat ~ sorting out the short video release process
Fibonacci
Hydropower project construction scheme based on 3D GIS Development
7-6 laying oil well pipeline
Common regular expressions
Morris traversal
去商场逛街