8.指针-进阶

1.指针语法解剖

  • 任意的指针,不管有多复杂,其定义都由两部分组成。
    • 第1部分:指针所指向的数据类型,可以是任意的类型
    • 第2部分:指针的名字

  • 示例:
char   (*p1);            // 第2部分:*p1; 第1部分:char; 
char  *(*p2);            // 第2部分:*p2; 第1部分:char *; 
char **(*p3);            // 第2部分:*p3; 第1部分:char **; 
char   (*p4)[3];         // 第2部分:*p4; 第1部分:char [3]; 
char   (*p5)(int, char); // 第2部分:*p5; 第1部分:char (int, float); 

  • 注解:
  1. 上述示例中,p1、p2、p3、p4、p5本质上并无区别,它们均是指针
  2. 上述示例中,p1、p2、p3、p4、p5唯一的不同,是它们所指向的数据类型不同
  3. 第1部分的声明语句,如果由多个单词组成,C语言规定需要将其拆散写到第2部分的两边

2.特殊指针

2.1char型指针

char型指针实质上跟别的类型的指针并无本质区别,但由于C语言中的字符串以字符数组的方式存储,而数组在大多数场合又会表现为指针,因此字符串在绝大多数场合就表现为char型指针。

  • 定义:
char *p = "abcd";

2.2多级指针

  • 如果一个指针变量 p1 存储的地址,是另一个普通变量 a 的地址,那么称 p1 为一级指针
  • 如果一个指针变量 p2 存储的地址,是指针变量 p1 的地址,那么称 p2 为二级指针
  • 如果一个指针变量 p3 存储的地址,是指针变量 p2 的地址,那么称 p3 为三级指针
  • 以此类推,p2、p3等指针被称为多级指针
  • 示例:
int a = 100;
int   *p1 = &a;  // 一级指针,指向普通变量
int  **p2 = &p1; // 二级指针,指向一级指针
int ***p3 = &p2; // 三级指针,指向二级指针

2.3void型指针

  • 概念:无法明确指针所指向的数据类型时,可以将指针定义为 void 型指针
  • 要点:

             a.void型指针无法直接索引目标,必须将其转换为一种具体类型的指针方可索引目标

             b.void 型指针无法进行加减法运算

  • void关键字的三个作用:

             a.修饰指针,表示指针指向一个类型未知的数据

             b.修饰函数参数列表,表示函数不接收任何参数。(预习)int main(void)

             c.修饰函数返回类型,表示函数不返回任何数据。(预习)void func(int)

  • 示例:
// 指针 p 指向一块 4 字节的内存,且这4字节数据类型未确定
void *p = malloc(4);

// 1,将这 4 字节内存用来存储 int 型数据
*(int *)p = 100;
printf("%d\n", *(int *)p);

// 2,将这 4 字节内存用来存储 float 型数据
*(float *)p = 3.14;
printf("%f\n", *(float *)p);

2.4const型指针

  • const型指针有两种形式:①常指针 ②常目标指针
  1. 常指针:const修饰指针本身,表示指针变量本身无法修改。

  1. 常目标指针:const修饰指针的目标,表示无法通过该指针修改其目标。

  • 常指针在实际应用中不常见。
  • 常目标指针在实际应用中广泛可见,用来限制指针的读写权限
  • 示例:
int a = 100;
int b = 200;

// 第1中形式,const修饰p1本身,导致p1本身无法修改
int * const p1 = &a; 

// 第2中形式,const修饰p2的目标,导致无法通过p2修改a
int const *p2 = &a;
const int *p2 = &a;

2.5函数指针(需预习:函数)

  • 概念:指向函数的指针,称为函数指针。
  • 特点:函数指针跟普通指针本质上并无区别,只是在取址和索引时,取址符和星号均可省略
  • 示例:
void   f (int); // 函数 f 的类型是: void (int)
void (*p)(int); // 指针 p 专门用于指向类型为 void (int) 的函数

p = &f; // p 指向 f(取址符&可以省略)
p =  f; // p 指向 f

// 以下三个式子是等价的:
  f (666); // 直接调用函数 f
(*p)(666); // 通过索引指针 p 的目标,间接调用函数 f
 p (666); // 函数指针在索引其目标时,星号可以省略

  • 要点:

1.函数指针是一类专门用来指向某种类型函数的指针。

2.函数的类型不同,所需要的函数指针也不同。

3.函数的类型,与普通变量的类型判定一致,即去除声明语句中的标识符之后所剩的语句。

二分查找是一种高效的查找算法,适用于在一个有序的数组中查找特定元素。它的基本思想是通过将查找范围不断缩小一半来快速定位目标元素。以下是二分查找的基本步骤: 1. **初始化指针**:设置两个指针,`left` 指向数组的起始位置,`right` 指向数组的末尾位置。 2. **中间元素比较**:计算中间位置 `mid = (left + right) / 2`,并将该位置的元素与目标元素进行比较。 - 如果中间元素等于目标元素,查找成功,返回 `mid`。 - 如果中间元素小于目标元素,将 `left` 指针移动到 `mid + 1`。 - 如果中间元素大于目标元素,将 `right` 指针移动到 `mid - 1`。 3. **重复查找**:重复上述步骤,直到 `left` 指针大于 `right` 指针,此时查找失败,返回 -1。 以下是一个简单的二分查找实现示例: ```python def binary_search(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return -1 # 示例数组 arr = [1, 3, 5, 7, 9, 11, 13] # 目标元素 target = 7 # 调用二分查找函数 index = binary_search(arr, target) if index != -1: print(f"元素 {target} 在数组中的索引为 {index}") else: print("元素未找到") ``` 在这个示例中,数组 `arr` 是有序的,目标是查找元素 `7`。通过二分查找算法,最终返回元素 `7` 的索引 `3`。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄月初二丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值