目录
一、指针函数
返回值为指针的函数
C 语言中,栈上的局部变量会在函数执行结束后被销毁,因此不能直接返回其地址。若需返回局部变量相关的数据,可通过以下三种方式调整:
- 给局部变量添加 static 关键字;
- 使用全局变量;
- 通过 malloc 函数将内存空间开辟到堆上。
1.有效性
C 语言中函数返回指针时,不同变量存储区域对指针有效性的影响:

- 返回栈上局部数组的地址(无效)
- 函数 char* Fun() 中定义了局部数组 char a[50] = "hello",该数组存储在栈上。
- 函数执行结束后,栈空间被释放,数组 a 的内存被回收。
- main 函数中接收的指针 p = 0x5000 指向的是已失效的栈内存,后续访问该地址属于 “野指针” 操作。
- 返回静态数组的地址(有效)
- 函数 char* Fun() 中定义了静态数组 static char a[50] = "hello",静态变量存储在静态数据区(.data 段)。
- 静态数据区的变量生命周期与程序一致,函数执行结束后不会被销毁。
- main 函数中接收的指针 p = 0x300 始终有效,可安全访问数组内容。
- 返回字符串常量的地址(有效)
- 函数 char* Fun2() 中定义了字符串常量 char* p = "hello",字符串常量存储在只读数据区(.rodata 段)。
- 只读数据区的内容在程序运行期间不会被修改且一直存在。
- main 函数中接收的指针 str = 0x100 可长期有效访问该字符串(但注意字符串常量不可修改)。
2.参数传递
指针函数返回的地址,可以作为下一个函数的参数进行传递。
int main()
{
char src[100] = {0};
char dst[100] = {0};
strcpy(dst,strcpy(src,"hello")); //内部的strcpy调用完后,会返回src指针。
printf("src :%s ,dst:%s\n",src,dst);
}
二、函数指针
指向了一个函数的指针
1.应用
降低耦合度,增加灵活性。
在代码开放阶段,函数需要执行的功能不确定。需要等到程序运行起来后,才能确定具体功能。 这里的 add,sub 会在程序运行起来后,根据不同情况会被调用。add,sub 被称为回调函数。
int add(int a, int b) // int (int,int) 0x3000 这个函数的类型,就是去掉函数名
{
return a+b;
}
int sub(int a, int b) // 0x5000
{
return a-b;
}
int main() // 函数名,本质是就是一个指针,指向的内容是一段操作,不是数据而已。
{
int (*op)(int,int) = NULL; // int(*)(int,int) 定义了一个函数指针
int a = 10;
int b = 20;
int num = 0;
printf("1:+ 2:-\n");
printf("input num:");
scanf("%d",&num);
switch(num)
{
case 1:
op = add; // op = 0x3000 函数指针的赋值
break;
case 2:
op = sub; // op = 0x5000
break;
default:
op = add;
}
int ret = op(a, b); // 函数指针的调用
printf("op result is %d\n", ret);
return 0;
}
2.typedef
定义类型别名
typedef unsigned int u32; // u32 是一个类型名 等价 unsigned int
typedef int s32;
typedef int (*PFUN)(int,int); // PFUN 是一个类型名,int(*)(int,int)
PFUN op1 = NULL; // 等价于 int(*op1)(int,int) = NULL;
op1 = lessthan;
3.二级指针
指向指针变量的指针
二级指针变量中存储的是一个地址,在解引用后,存储的还是一个地址
应用:在被调函数中,需要修改指针的指向。
#include <stdio.h>
void fun(char **arg_p) 二级指针
{
*arg_p = "ok"; // 这个使用间接引用,直接操作main函数中的一级指针变量本身
}
int main()
{
char *p = "hello"; // int *
fun(&p); // &p int **p; &p是二级指针
printf("p is %s\n",p);
}
//char *p ="ok";
//char **q = &p;
4.const指针
被 const 修改的变量,称为只读变量
规则:const 靠近谁,谁就不能被修改。
- 若 const 在 * 左边,修饰数据,数据不能改,指针可以改指向;
- 若在 * 右边,修饰指针本身,指针不能改指向,数据可以改。
- 若左右都有,数据和指针指向都不能改
| 声明形式 | 修饰对象 | 能否改数据? | 能否改指针指向? | 是否需初始化? |
|---|---|---|---|---|
| const char *p; | 指向的数据 | ❌ | ✅ | ❌ |
| char const *p; | 指向的数据 | ❌ | ✅ | ❌ |
| char *const p; | 指针变量本身 | ✅ | ❌ | ✅ |
| const char *const p; | 数据 + 指针本身 | ❌ | ❌ | ✅ |
| char const *const p; | 数据 + 指针本身 | ❌ | ❌ | ✅ |

1482

被折叠的 条评论
为什么被折叠?



