Chapter3.h
#ifndef __CHAPTER_3_
#define __CHAPTER_3_
/*《深入理解C指针》学习笔记 -- 第三章*/
/*它们都保存在栈中的什么位置?*/
void __location_stack_test(int*, int);
/*指向常量的指针*/
void __constant_pointer_test(const int*, int*);
/*指向指针的指针*/
void __pointer_to_pointer(int**);
/*函数指针的使用方法*/
typedef int (*fptr_op)(int, int);
int add(int, int);
int sub(int, int);
int function_pointer_test(fptr_op, int, int);
#endif
Chapter3.cpp
#include "Chapter3.h"
#include <stdio.h>
#include <malloc.h>
/*它们都保存在栈中的什么位置?*/
void __location_stack_test(int* p_test, int test)
{
int test1;
printf("test's address is : %x\n", &test);
printf("p_test's address is : %x\n", &p_test);
printf("test1's address is : %x\n", &test1);
/*
输出结果是:
test's address is : 29f708
p_test's address is : 29f704
test1's address is : 29f6f4
可以看到,在栈中,函数参数的存储顺序是倒过来的,从最后一个参数存起
(栈的地址是从高到低),最后,存储的才是函数中的局部变量
我们从地址中可以看出,函数参数的地址和局部变量之间存在空隙,这里在栈中
存储的是函数调用的返回地址
*/
}
/*指向常量的指针*/
/*
p_test : 需要指向一个整型量,可以是常量,也可以不是,但是,我们不能在函数内利用解引用修改它
test : 必须指向一个非常量,因为,我们可以在函数内利用解引用修改它
*/
void __constant_pointer_test(const int* p_test, int* test)
{
/*
通常,我们写程序的时候需要保证程序不出现“意外”,不过,通常我们知道这个函数的原型
就不会随便传一个值给这个函数,这个也是我一般的做法,直到我面试的时候,面试官提醒我,
是不是添加一个 const 更好呢?我才明白,这样做是更加严谨的做法
*/
//*p_test = 10; 这里会出现问题,因为指针指向的是常量,不允许赋值操作
*test = 10;
}
/*指向指针的指针*/
void __pointer_to_pointer(int** test)
{
/*如果我们修改的是指针,这里是给指针分配内存,那么,我们必须要传递指针的指针*/
*test = (int*)malloc(sizeof(int));
/*
什么时候应该传递指针,什么时候应该传递指针的指针?
我的理解是:你想要修改什么,就传递它的地址过去
*/
}
/*函数指针的使用方法*/
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
/*
op : 函数指针类型的参数
*/
int function_pointer_test(fptr_op op, int a, int b)
{
return op(a, b);
}