高级指针部分编写完毕。

This commit is contained in:
Lion Chan 2018-07-05 00:16:35 +08:00
parent 2f79771c00
commit 03a7c0a9d1
1 changed files with 90 additions and 7 deletions

View File

@ -178,6 +178,27 @@ void* p1 = p0;
## 2.8.6 指针与函数
函数、或者说程序本身在运行时也是要占用内存空间的。因此,可以使用指针,像指向某个变量那样指向这个函数:
```cpp
typedef void (*P_FUN_TYPE)(int a);
void fun(int a)
{
printf("%d", a);
}
void main(void)
{
int a = 0x10;
P_FUN_TYPE pfun = fun;
pfun(a); // 与直接调用 fun(a) 是一样的.
}
```
这样可以指向函数的指针称为函数指针。在一般的程序中,函数指针并不常见。但,如果你编写的程序具有某种框架,例如 linux 内核中的驱动框架,就会大量使用函数指针了。
## 2.8.7 多级指针
前面提及指针的实质是变量,因此也有一个内存空间用于保存指针的值,同样也有一个内存地址与之对应。这就是说,我们可以通过一个指向指针的指针去访问另一个指针,这被称为二级指针或多级指针。
@ -187,21 +208,83 @@ int a=10;
int* pa = &a;
int** ppa = &pa;
printf("%d", **ppa);
printf("%d\n", **ppa);
```
## 2.8.8 指针参数
以上所说的全部类型指针都可以作为函数的参数来进行传递。
```cpp
void fun(int* arry, int size)
{
int i;
for(i=0; i<size; i++)
printf("%d\n", arry[i]);
}
void main(void)
{
int codeList[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
fun(codeList, sizeof(codeList)/sizeof(*codeList));
}
```
对于参数的传递有值传递和引用传递两种。C 语言本质上只支持值传递。但通过指针,可以达到传递引用的效果——这是因为指针本身就是对其他变量的引用。
## 2.8.9 指针与内存泄漏
数组访问的溢出
没有释放的内存
野指针
使用指针时,有些事情是需要特别注意的。
当使用指针来访问数组时,有可能访问的范围超过了数组自身的实际长度,这是非常危险的,并且在任何情况下都应该避免:
```cpp
int arry[6];
int* p = arry;
p += 10;
p = 0x55; // 数组方位越界.
```
如果指针没有被初始化,则将其赋值为 NULL即空指针。另外在使用完指针后也应该将其赋值为 NULL。这样在程序中通过对指针值得判断可以知道这个指针是否有效。无效得指针非常可怕我们将其称为野指针。
```cpp
typedef void (*P_FUN_TYPE)(int a);
void fun(int a)
{
printf("%d", a);
}
void main(void)
{
int a = 0x10;
P_FUN_TYPE pfun; // pfun 没有被初始化过, 被称作野指针.
pfun(a); // 调用 pfun(a) 之后程序不知道跑到了哪里去,程序跑飞了.
}
```
很多时候,我们使用 malloc() 等函数为指针分配一个空间,但是在使用后我们忘记了释放,然后下次又接着申请了。这使得内存越用越少,很多内存脱离了程序应有得掌控范围,造成内存泄漏。
```cpp
int* p = NULL;
int i;
for(i=0; i<1024; i++)
p = malloc(1024);
p = NULL;
// 很快 1M 内存就消失了,并且这块内存无法再被回收。
```
内存泄露他同样是极旗危险得,它不仅造成程序和系统不稳定,也会危害系统安全,泄漏用户隐私数据等。
## 练习
1、Program 2-8-4-1 中同样有编译警告,你该如何去除这些警告?
函数指针
指针数组
数组名
2、如果有多个不同得设备他们的读写方法不同但是调用接口的形式是一致的我们的主程序要读写所有的设备该怎样实现最高效能否将这些设备组织在一个数组中