NDK02_C:指针、指针运算、多级指针与函数指针

NDK开发汇总

一 学习指针的目标

  • 从专业角度了解指针的作用
  • 会使用指针进行基本运算
  • 会使用指针作为函数的参数
  • 会使用指针数组和数组指针
  • 会使用二级指针
  • 会使用函数指针

二 指针

指针变量存储的是 变量类型对应的变量的地址。

  • 声明指针或者不再使用后都要将其置为0 (NULL)

  • 野指针 未初始化的指针

  • 悬空指针 指针最初指向的内存已经被释放了的一种指针

  • & 取地址操作符,运用在内存中的对象上面,即变量与数组元素

  • 间接寻址或引用运算符 *

  • &和*都是单目运算符

  • %#x 16进制输出

  • int * p p存储的是int型的变量的地址

double f = 23.99f;
double *fp;
fp = &f;
printf("f的内存:%d\n", sizeof(f));//8
printf("size of(*fp) %d\n", sizeof(*fp));//8
printf("size of(fp) %d\n", sizeof(fp));//4 fp是一个变量,指向double类型的数据的变量;fp是存储的 地址,地址是占用4个字节的。32位 4*8

定义

int *a; 正规
int* a;
int * a;
//因为 其他写法看起来有歧义
int* a,b;

使用:

//声明一个整型变量
int i = 10;
//将i的地址使用取地址符给p指针
int *p = &i;
//输出 0xffff 16进制地址
printf("%#x\n", &i);
printf("%#x\n", &p);

指针多少个字节?指向地址,存放的是地址
地址在 32位中指针占用4字节 64为8

解引用

解析并返回内存地址中保存的值

int i = 10;
int *p = &i;
//解引用  
//p指向一个内存地址,使用*解出这个地址的值 即为 10
int pv = *p;
//修改地址的值,则i值也变成100
//为解引用的结果赋值也就是为指针所指的内存赋值
*p = 100;

三 指针运算:

  • *p 代表是它所指的地址上面的值的运算
  • p++ 是p 指针变量++,结果就是:p指向它的下一个地址
//对指针 进行算数运算
//数组是一块连续内存 分别保存 11-55
//*p1 指向第一个数据 11,移动指针就指向第二个了
int i1[] = {11,22,33,44,55};
int *p1 = i1;
for (size_t i = 0; i < 5; i++)
{
    //自增++ 运算符比 解引用* 高,但++在后为先用后加
    //如果++在前则输出 22-55+xx
	printf("%d\n", *p1++);
    //p1[0] == *(p1+1) == s[1]

}

指针指向地址,指针运算实际上就是移动指针指向的地址位置,移动的位数取决于指针类型(int就是32位)

四 数组与指针

通过数组下标所能完成的任何操作都可以通过指针来实现。而用指针编写的程序比用数组下标编写的程序执行速度快,但是,指针写的程序会比较难理解一点。

在c语言中,指针和数组名都表示地址

1、数组是一块内存连续的数据。

2、指针是一个指向内存空间的变量

int i1[] = {11,22,33,44,55};
//直接输出数组名会得到数组首元素的地址
printf("%#x\n",i1);
//解引用
printf("%d\n",*i1);
//将数组名赋值给一个指针,这时候指针指向数组首元素地址
int *p1 = i1;

五 指针数组和数组指针

指针数组

  • 是一个数组,数组里存储的是指针类型的变量, 如: int *p1[4];
//二维数组类型是 int (*p)[x]
int array[2][3] = { {11,22,33},{44,55,66} };
//也可以 int array[2][3] = {  11,22,33 ,44,55,66 };
//array1 就是一个 int[3] 类型的指针
int (*array1)[3] = array;
//怎么取 55 ?
//通过下标
array[1][1] == array1[1][1]
//通过解引用
int i = *(*(array1 + 1) + 1);
//拆分
//1、 指针偏移 因为array1的类型是3个int的数组 所以 +1 移动了12位
array1 + 1 
//2、获得{44,55,66}数组  (*(array1 + 1))[1] = 55
(*(array1 + 1) 
//3、对数组执行 +/- 相当于隐式的转为指针
//获得 55 的地址 再解地址
*(array1 + 1) + 1

数组指针

  • 是一个指针,这个指针指向的是一个数组的首地址,如:int (*p2)[4]
int *array2[2];
array2[0] = &i;
array2[1] = &j;

六 多级指针

  • 指向指针的指针

二级指针存的内容是一个一级指针的地址
// p 是一个指针变量,这个变量本身就是一个地址的别名
// *p 运算,得到的就是a 的值
// *p2 运算,得到的就是p的值
//**p2 运算,得到的就是 p的值的 *运算得到的值 a;

一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。

int a = 10;
int *i = &a;
int **j = &i;
// *j 解出 i   
printf("%d\n", **j);

七 函数指针

函数指针是指向函数的指针变量

void println(char *buffer) {
	printf("%s\n", buffer);
}
//接受一个函数作为参数
void say(void(*p)(char*), char *buffer) {
	p(buffer);
}
void(*p)(char*) = println;
p("hello");
//传递参数
say(println, "hello");

//typedef 创建别名 由编译器执行解释
//typedef unsigned char u_char;
typedef void(*Fun)(char *);
Fun fun = println;
fun("hello");
say(fun, "hello");

//类似java的回调函数
typedef void(*Callback)(int);

void test(Callback callback) {
	callback("成功");
	callback("失败");
}
void callback(char *msg) {
	printf("%s\n", msg);
}

test(callback);
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值