news 2026/6/10 14:49:16

深究指针_2

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深究指针_2

文章目录

  • 深究指针_2
    • void *类型
    • 内存管理
      • 内存布局
      • malloc
      • calloc()
      • 调整函数realloc()
    • 数组与指针
    • 指针和字符串操作

深究指针_2

void *类型

**(void *)**是任意类型指针,更准确地说,是“通用指针”或者是“无类型指针”。与函数定义void相似,多用在动态内存分配等地方,重点在于其通用性

  • void *就是一个指向未知类型数据的内存地址的指针
  • 它只包含一个地址值,但不包含关于这个地址上存储的数据类型的信息。

特性

  • 可以指向任何类型的数据

  • inta=10;floatb=3.14;charc='X';intarr[5]={1,2,3,4,5};void*vp;// 声明一个void指针vp=&a;// 可以指向intvp=&b;// 可以指向floatvp=&c;// 可以指向charvp=arr;// 可以指向数组
  • 不能直接解引用,不能进行指针算术运算,使用前要进行类型转换

  • inta=10;void*p;int*a_ptr=(int*)p;

内存管理

内存布局

在此之前我们先了解C程序内存布局。

栈(stack)局部变量,函数参数(自动管理)
······
堆(Heap)动态内存分配(手动管理)
BSS段没有初始化的全局/静态变量
数据段(data)已经初始化的全局/静态变量
代码段(text)程序代码

malloc

#include<stdio.h>#include<srdlib.h>intmain(){intn,sum,i,*p;printf("Enter n:");scanf("%d",&n);if((p=(int*)malloc(n*sizeof(int)))==NULL){printf("Fail to allocate memory.\n");exit(1);// 终止程序执行}//强制转换为整形指针,并且判断是否分配成功//p已经指向基地址printf("Enter %d integers:",n);for(i=0;i<n;i++){scanf("%d",p+i);//本身就是地址,也可以是p[i]//p已经是数组名}for(i=0;i<n;i++){sum+=*(p+i);}free(p);//用完后一定要释放return0;}

总结

确定需要多少内存空间

利用内存动态分配函数<srdlib.h>

用指针指向此空间,指向基地址即可,只可以通过指针访问

内存使用完毕释放

void*malloc(unsighnedchar)

在动态存储去,无符号整型,大小为字节数

申请成功,则返回一个指向分配内存空间的起始地址的指针

类型为 void *(上述通用指针),不成功返回NULL

int*p;if((p=(int*)malloc(n*sizeof(int)))==NULL){printf("Not able to allocate memory.\n");exit(1);}

calloc()

自动对整个区域进行初始化,而malloc()不执行操作

void*calloc(unsignedn;unsignedsize)

在动态存储区连续分配n个存储块,每个存储块长度为size,并且分配后全部初始化为0;

空间释放函数

voidfree(void*ptr);//指向释放空间首地址指针free(p);

调整函数realloc()

void*realloc(void*ptr,unsignedsize)

更改以前的存储分配

ptr必须是以前通过动态内存分配得到的指针

参数size是现在需要的空间大小

如果调整失败,返回NULL,ptr指向存储块的内容不变

如果调整成功,返回指向大小为size的存储块的起始地址的指针,并保证该块的内容与原块一致。

  • 如果size小于原块,内容为前size范围内的数据
  • 如果size大于原块,则原有数据存在新快的前一部分

如果分配成功,原存储快内容就可能改变了,因此不能再通过ptr去使用

数组与指针

数组名作为函数的参数,在函数调用时,将实参数组首元素的地址传给形参(指针变量),因此,形参也指向实参数组的首元素,如果改变形参所指向的单元的值,就改变实参数组元素的值。

源于数组名是指针常量,指针作为函数的参数。

指针和字符串操作

我们先来分析一个实例

#include<stdio.h>intmain(){char*str[]={"Hello","World","C"};char**pp=str;printf("%c\n",**pp);// 输出 'H'printf("%s\n",*(pp+1));// 输出 "World"printf("%c\n",*(*pp+1));// 输出 'e'printf("%c\n",*((*pp+1)+2);//输出'r'return0;}

我们来逐行分析这段代码

char*str[]={"Hello","World","C"};

这一行定义了一个指针数组

  • str是一个数组,包含了三个char*类型元素,分别指向定义的三个元素,str[i]指向第i个字符串。
  • 内存布局:
    • str[0]→ 指向字符串 “Hello”
    • str[1]→ 指向字符串 “World”
    • str[2]→ 指向字符串 “C”
    • *str[0] = “Hello”
char**pp=str;
  • pp是一个指向指针的二级指针
  • str作为数组名,退化为指向数组第一个元素的指针,也就是&str[0]
  • pp = &str[0]
  • *pp = str[0] = ‘Hello’ 这是指向第一个字符的指针
  • **pp = *(*pp) = *str[0] = ‘H’
printf("%s\n",*(pp+1));
  • pp+1 = &str[1] 移动一个指针大小的距离

  • *(pp+1) = str[1] = “World”

printf("%c\n",*(*pp+1));
  • *pp = str[0](数组名)是指向字符串"Hello"的指针,存储第一个字母的地址,*pp+1指向第二个字母的指针,即’e‘存储的位置。
  • *(*pp+1) = ‘e’

事实上,以上仅仅作为理解,写代码过于弯绕繁琐,通常指针数组可以直接: str[i]等效于(pp + i),str[i][j] 等效于 *(*(pp + i)+ j)*

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 19:42:34

Redash数据可视化终极指南:从原始数据到专业报表

Redash数据可视化终极指南&#xff1a;从原始数据到专业报表 【免费下载链接】redash getredash/redash: 一个基于 Python 的高性能数据可视化平台&#xff0c;提供了多种数据可视化和分析工具&#xff0c;适合用于实现数据可视化和分析。 项目地址: https://gitcode.com/Git…

作者头像 李华
网站建设 2026/6/10 14:10:10

关于 QGraphicsItemGroup 内部项目发生变化后group重新定位的问题

在项目中为了便于对组合后的图元进行管理&#xff0c;一般会继承 QGraphicsItemGroup 实现自己的 group 类&#xff0c;这样可以方便的借用 QGraphicsItemGroup 对内部图元进行管理&#xff0c;但同时也受到了 QGraphicsItemGroup 实现的约束。例如&#xff1a;QGraphicsItemGr…

作者头像 李华
网站建设 2026/6/10 0:14:35

FFmpeg开发笔记(八十九)基于FFmpeg的直播视频录制工具StreamCap

着推拉流技术的发展&#xff0c;现在网络直播应用很普及了&#xff0c;打开许多App都能看到各式各样的直播节目&#xff0c;包括抖音、快手、虎牙、斗鱼、B站、小红书、YY、映客等等。有关视频推拉流的FFmpeg实现参见《FFmpeg开发实战&#xff1a;从零基础到短视频上线》一书的…

作者头像 李华
网站建设 2026/6/10 14:09:30

现代UI组件库与设计工具的无缝集成实战指南

现代UI组件库与设计工具的无缝集成实战指南 【免费下载链接】ant-design An enterprise-class UI design language and React UI library 项目地址: https://gitcode.com/gh_mirrors/ant/ant-design 在当今快速迭代的产品开发环境中&#xff0c;设计与开发团队之间的协作…

作者头像 李华
网站建设 2026/6/6 21:17:19

SpringAI基于内存存储向量

一、环境信息 1、参看如下&#xff1a; SpringAI入门学习 二、测试使用 1、创建SimpleVectorStore public interface VectorStore extends DocumentWriter {default String getName() {return this.getClass().getSimpleName();}void add(List<Document> documents)…

作者头像 李华
网站建设 2026/6/10 14:42:17

Matlab/Simulink 三相四桥臂逆变器仿真模型探索

matlab/simulink三相四桥臂逆变器仿真模型 采用电压外环&#xff0c;电流内环控制策略&#xff0c;交流侧可以接不平衡负载&#xff0c;在负载不平衡的情况下依然保持输出电压对称。 直流侧电压为750V&#xff0c;可以自己定义&#xff0c;交流侧为380/220v&#xff0c;平衡负载…

作者头像 李华