当前位置: 首页 > news >正文

10-指针进阶——char型,多级指针,void指针,const指针

10-指针进阶——char型,多级指针,void指针,const指针

文章目录

  • 10-指针进阶——char型,多级指针,void指针,const指针
    • 一、char 型指针
      • 1.1 示例
    • 二、多级指针
      • 2.1 示例
    • 三、 指针的万能拆解方法
      • 3.1 示例
    • 四、void 型指针
      • 4.1 示例
      • 4.2 void 关键字的作用
        • 4.2.1 示例
    • 五、const 指针
      • 5.1 常指针
      • 5.2 常目标指针

一、char 型指针

概念:字符指针(char*)是一种特殊类型的指针,用来指向一个字符或字符数组,通常用于字符串处理。

1.1 示例

#include <stdio.h>int main() {char *msg = "Hello Even";printf("%s\n", msg); // 输出字符串 "Hello Even"return 0;
}

在上述代码中,msg是一个字符指针,指向字符串常量 "Hello Even" 的首字符 'H'

二、多级指针

概念:多级指针是指针的指针。一个指针指向另一个指针时,就是多级指针。

  • 一级指针:指向一个普通变量的地址。
  • 二级指针:指向一个指针变量的地址。
  • 三级指针:指向一个二级指针变量的地址。

2.1 示例

#include <stdio.h>int main() {int a = 100;int *p1 = &a;    // 一级指针int **p2 = &p1;  // 二级指针int ***p3 = &p2; // 三级指针printf("a = %d\n", a);        // 输出 100printf("*p1 = %d\n", *p1);    // 输出 100printf("**p2 = %d\n", **p2);  // 输出 100printf("***p3 = %d\n", ***p3);// 输出 100return 0;
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这段代码中,p1 是一个一级指针,指向变量 ap2 是一个二级指针,指向 p1p3 是一个三级指针,指向 p2

三、 指针的万能拆解方法

每个指针都可以分为两部分:

  1. 第一部分:说明它是一个指针(*p)。
  2. 第二部分:说明它所指向的内容的类型(*p 以外的东西)。

3.1 示例

#include <stdio.h>int main() {char *p1;               // 第一部分: *p1,第二部分: char, 说明 p1 指向 char 类型char **p2;              // 第一部分: *p2,第二部分: char *, 说明 p2 指向 char* 类型int **p3;               // 第一部分: *p3,第二部分: int *, 说明 p3 指向 int* 类型char (*p4)[3];          // 第一部分: *p4,第二部分: char[3], 说明 p4 指向一个拥有3个元素的 char 数组char (*p5)(int, float); // 第一部分: *p5, 第二部分: char(int, float), 说明 p5 指向一个返回 char 并需要 int 和 float 参数的函数void *(*p6)(void *);    // 第一部分: *p6, 第二部分: void *(void *), 说明 p6 指向一个返回 void* 并需要 void* 参数的函数return 0;
}

在这个例子中:

  • p1 是一个指向 char 类型的指针。
  • p2 是一个指向 char* 类型的指针,即指向 char 指针的指针。
  • p3 是一个指向 int* 类型的指针,即指向 int 指针的指针。
  • p4 是一个指向拥有 3 个 char 元素的数组的指针。
  • p5 是一个指向一个返回 char 类型并需要 intfloat 参数的函数的指针。
  • p6 是一个指向一个返回 void* 并需要 void* 参数的函数的指针。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总结

  • char 型指针:用于指向字符或字符串数组,常用于字符串处理。
  • 多级指针:指针的指针,可以是一级、二级、三级等多级指针,用于更复杂的内存操作。
  • 指针的万能拆解方法:可以将任何指针分解为两部分,一部分表示它是一个指针,另一部分表示它所指向的内容的类型。

指针的大小是固定的(在64位系统中为8字节),但它们所指向的数据类型各不相同

四、void 型指针

概念void 型指针表示该指针的类型暂时不确定,即它可以指向任何类型的数据

要点

  1. 无法直接索引目标void 型指针必须先进行强制类型转换,然后才能索引目标。
  2. 无法直接进行加减运算void 型指针不允许直接进行加减运算,因为编译器不知道如何移动指针。

4.1 示例

#include <stdio.h>
#include <stdlib.h>int main() {void *p = malloc(4); // 使用 malloc 申请 4 个字节的内存,并让 p 指向该内存的入口地址*(int *)p = 250; // 强制类型转换为 int 型指针,然后解引用printf("*p as int: %d\n", *(int *)p); // 输出 250*(float *)p = 3.14; // 强制类型转换为 float 型指针,然后解引用printf("*p as float: %f\n", *(float *)p); // 输出 3.140000free(p); // 释放内存return 0;
}

在上面的代码中,p 是一个 void 型指针,通过强制类型转换为 int 型指针或 float 型指针来访问数据。

注意
以上写法 void * p , 在实际开发中不应该出现。以上代码只是为了说明语法问题。

4.2 void 关键字的作用

  1. 修饰指针:表示该指针指向了一个未知类型的数据。
  2. 修饰函数的参数列表:表示该函数不需要参数。
  3. 修饰函数的返回值:表示该函数没有返回值。
4.2.1 示例
void functionWithNoReturnValue(void) {// 函数没有返回值,也不需要参数
}int main() {functionWithNoReturnValue();return 0;
}

五、const 指针

概念const 修饰指针有两种效果:

  1. 常指针:修饰的是指针本身,表示该指针变量无法修改
  2. 常目标指针:修饰的是指针所指向的目标,表示无法通过该指针来改变目标的数据

5.1 常指针

#include <stdio.h>int main() {char arr[] = "Hello";char msg[] = "Even";char * const p = arr;// p = msg; // 编译错误:p 被 const 修饰,表示 p 是一个常量,无法修改它的内容(所指向的地址)*(p + 1) = 'E'; // p 所指向的内容是可以通过 p 来修改的printf("%s\n", p); // 输出 "HEllo"return 0;
}

5.2 常目标指针

#include <stdio.h>int main() {char arr[] = "Hello";char msg[] = "Even";const char *p1 = arr;//常目标指针p1 = msg; // p1 的指向是可以被修改的// *(p1 + 1) = 'V'; // 编译错误:常目标指针不允许通过该指针来修改它所指向的内容*(msg + 1) = 'V'; // 直接修改内容是可以的printf("%s\n", p1); // 输出 "Even"return 0;
}

总结:

  • void 型指针:通用指针,可以指向任意类型的数据,但需要强制类型转换后才能操作。
  • const 修饰指针
    • 常指针:指针本身不能修改(指向的地址不能变),但所指向的内容可以修改。
    • 常目标指针:所指向的内容不能通过该指针修改,但指针本身可以指向其他地址。

在实际开发中,const 修饰符经常用于限制指针的权限,特别是常目标指针,用来确保数据的只读性,防止误修改。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相关文章:

  • 【iOS】UI——关于UIAlertController类(警告对话框)
  • 数据总线、位扩展、字长
  • 【三十三】springboot+序列化实现返回值脱敏和返回值字符串时间格式化问题
  • 【python报错】list indices must be integers or slices, not tuple
  • 数学+思维,CF1056B - Divide Candies
  • 网络安全快速入门(十五)(下)手动创建用户及su,sudo命令
  • 简单使用phpqrcode 生成二维码图片
  • 代码随想录算法训练营第36期DAY50
  • Docker 进入指定容器内部(以Mysql为例)
  • 详解linux设备下的/dev/null
  • 微信小程序怎么进行页面传参
  • 大学数字媒体艺术设计网页设计试题及答案,分享几个实用搜题和学习工具 #媒体#职场发展
  • 12寸晶圆厂建设概述
  • Javascript全解(基础篇)
  • C语言详解(动态内存管理)2
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【知识碎片】第三方登录弹窗效果
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • fetch 从初识到应用
  • jQuery(一)
  • Laravel 菜鸟晋级之路
  • Python 反序列化安全问题(二)
  • Spark学习笔记之相关记录
  • use Google search engine
  • 警报:线上事故之CountDownLatch的威力
  • 老板让我十分钟上手nx-admin
  • 七牛云假注销小指南
  • 前端自动化解决方案
  • 浅谈web中前端模板引擎的使用
  • 什么软件可以剪辑音乐?
  • 实现简单的正则表达式引擎
  • 原生js练习题---第五课
  • 2017年360最后一道编程题
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • # SpringBoot 如何让指定的Bean先加载
  • ${ }的特别功能
  • (2)Java 简介
  • (2015)JS ES6 必知的十个 特性
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (SpringBoot)第七章:SpringBoot日志文件
  • (ZT)薛涌:谈贫说富
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (四)软件性能测试
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • ***测试-HTTP方法
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .Net Remoting常用部署结构
  • .Net 基于.Net8开发的一个Asp.Net Core Webapi小型易用框架
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET/C# 使窗口永不获得焦点
  • .NET命令行(CLI)常用命令