news 2026/8/9 6:10:44

【C语言6】指针

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C语言6】指针

文章目录

  • 6. 指针
    • 6.1 指针基础
      • 6.1.1 指针变量的定义
      • 6.1.2 指针变量的初始化和赋值
      • 6.1.3 指针运算符
    • 6.2 指针的算数运算
    • 6.3 指针作为函数参数
    • 6.4 指针和数组
      • 6.4.1 指针和一维整型数组
      • 6.4.2 指针和一维字符型数组
      • 6.4.3 数组指针
      • 6.4.4 指针和二维数组
      • 6.4.5 指针数组
    • 6.5 二级指针
    • 6.6 指针函数
    • 6.7 函数指针
    • 6.8 const修饰的指针
    • 6.9 void*指针

此处为C语言汇总版: 【C语言md编辑器版】从0基础开始到熟练掌握(完整篇,共9部分)

6. 指针

内存:程序运行时,可以访问到的内存存储空间;计算机为了方便对内存的管理,以字节为单位对内存进行了编号。
地址:计算机管理内存时,给内存的编号。
指针:指针即为地址,地址即为指针,指针指向了一个具体的空间。
指针变量:变量,保存地址的变脸,需要占用内存空间。

6.1 指针基础

6.1.1 指针变量的定义

指针变量保存的地址为指针指向数据的首地址。

基类型*变量名
  • 基类型:该指针指向空间存储数据的数据类型。(例如:int、char、float、构造数据类型…)
  • *:类型说明符,说明后面的变量是指针。
  • 变量名:遵循标识符的命名规则。(一般以p开头,没有强制要求)
  • sizeof(指针):在64位计算机系统下,占8字节。在32位计算机系统下,占4字节。

6.1.2 指针变量的初始化和赋值

  • 野指针:未初始化或赋值的一个指针,或指向一个已经释放内存空间的指针。
  • 避免野指针
    1. 对指针定义初始化为空指针NULL
    2. 在指针定义时直接赋值。
    #defineNULL(void*)0;//万能指针NULL

6.1.3 指针运算符

  • *指针运算符
    • 用来访问指针变量指向的内存空间的数据。
    • *指针变量——>指针降级为变量类型——>基类型的变量。
    int*p;p ——>int**p ——>int
    注意
    1. *指针运算符不可以用于普通变量,只能放在指针变量的前边。
    2. *指针变量,访问指针变量指向的数据,该表达式降级为变量类型——>基类型的变量。
    3. *指针变量,访问的字节数取决于定义该指针时的基类型。
类型访问大小
char *p1字节
int *p4字节
double *p8字节
  • &取地址运算符
    &变量
    1. &只能给一个变量取地址,不能给常量或表达式取地址。
    2. &给某个变量取地址时,获取的是这个变量首字节的地址。

6.2 指针的算数运算

+ - * / % ++ --

+ * / %对指针运算毫无意义
-:指针1-指针2:表示两个指针之间间隔的元素个数(地址值之间的字节差/sizeof(基类型))
++:指针+1:表示从当前地址向后偏移sizeof(基类型)字节。
--:指针-1:表示从当前地址向前偏移sizeof(基类型)字节。

char*p;p+1;//向后偏移一个字节。int*p;p+1;// 向后偏移一个字节。

6.3 指针作为函数参数

  1. 被调函数中,想要修改主调函数中定义的变量,必须传递该变量的地址;
  2. 被调函数中,想要使用主调函数中定义的变量,可以传递值,也可以传递地址。
  3. 被调函数想要返回多个结果时,可以传递主调函数定义的变量的地址,地址指向的空间可以保存被
    调函数得到的结果。

6.4 指针和数组

6.4.1 指针和一维整型数组

数组的数组名为数组的首元素地址
注意:数组名为地址常量,不可赋值,不可移动。

一维整型数组作为参数传递:

voidprint_array(inta[],intlen){}voidprint_array(int*pa,intlen){}

6.4.2 指针和一维字符型数组

charstr[32]={"hello"};str===>&str[0]====>char*-------->*str====>str[0]str+1===>&str[1]====>char*-------->*(str+1)===>str[1]...str+n===>&str[n]====>char*-------->*(str+n)===>str[n]str+1;指针向内存高地址偏移sizeof(char)字节数 str-1;指针向内存低地址偏移sizeof(char)字节数
char*mystrcpy(char*dst,constchar*src){char*rdst=dst;while(*src!='\0'){*dst=*src;dst++;src++;}*dst='\0';returnrdst;}

注意:const在这起到提高安全性的作用,保证源不会发生改变。

6.4.3 数组指针

  • 本质:是一个指针,指向数组整体的指针。
基类型(*指针名)[常量];//数组的指针。int(*指针名)[5];//定义了一个指向5个整型元素的数组的指针。inta[5]={1,2,3,4,5};a:首元素地址——>&a[0]——>int*&a:数组的指针——>int(*)[5];&a+1:数组指针+1——>偏移整个数组,大小为sizeof(a)字节。

注意:指针变量自己占8字节的空间大小。

总结:
int a[5] = {1, 2, 3, 4, 5};
a:首元素地址——>int *
除了两种情况:
1.sizeof(a/数组名)a不能当作int *类型,当作数组整体,代表整个数组。
2.&a;数组指针,该指针类型为:int (*)[5];指向一个数组。

6.4.4 指针和二维数组

二维数组的数组名是首元素地址,首元素是一维数组,所以二维数组名本质上是一个数组指针

inta[5]={1,2,3,4,5};a 首元素地址&a[0]int*a[n]——>*(a+n)inta[2][3]={1,2,3,4,5,6};a 首元素地址&a[0]int(*)[3]——>数组指针 a[m][n]——>*(a[m]+n)——>*(a+m)[n]——>*(*(a+m)+n)

二维数组的数组名作为参数传递:

voidprint_2d_array(inta[][列数],inthang){}voidprint_2d_array(int(*pa)[列数],inthang){}voidprint_2d_array(chara[][列数],inthang){}voidprint_2d_array(char(*pstr)[列数],inthang){}

6.4.5 指针数组

定义:用数组来保存若干个指针。

语法指针类型 *数组名[常量];

int*a[5];int*——>数组中保存的数据类型:该数组保存的元素是int*指针。[5]——>该数组中可以保存5int*指针。 定义了一个可以保存5整型指针的数组,整体占40个字节。

指针数组的初始化

char*p=NULL;char*p[5]={NULL};5个字符型指针都初始化成NULL;char*p="hello";char*p[5]={"hello","world","how","are","you"};p[0]——>是一个指针,保存字符串常量"hello"的首地址。char*p1="hello";char*p2="world";char*p[2]={p1,p2};

指针数组和二维字符数组的区别

charstr[3][100]={"hello","world","how"};//300字节char*pstr[3]={"hello","world","how"};//24字节
  1. 二维字符型数组中保存的是多个字符串本身;指针数组中保存的是多个字符串的地址。
  2. 要保存多个字符串用二维字符型数组,要操作多个字符串用指针数组。

6.5 二级指针

定义:本质上还是指针,是一个指针变量的指针。

int**指针名称;——>保存整型指针的指针char**指针名称;——>保存字符型指针的指针

C语言中主要有两个二级指针的使用场景:

  1. 想要在被调函数中修改主调函数中的指针变量,实参需要传递该指针变量的地址;形参用二级指针接收。
  2. 指针数组的数组名,是一个二级指针,实参传递指针数组的数组名时,形参用二级指针接收。
char*str[3]={"hello","world","!"};str[0];——>char*——>保存了字符串常量"hello"的首地址。 str ——>&str[0]——>char**二级指针
  • 值传递:无法在被调中修改主调中的变量,只能使用该变量

  • 指针传参:可以在被调中修改主调中定义的变量,也可以使用该变量。

  • 值传递:恰好传递的值是一个指针变量,无法在被调用修改主调中定义的指针变量,可以使用该指针变量。

  • 指针传参:可以在被调函数中可以修改主调函数中定义的指针变量,也可以使用该变量。

6.6 指针函数

定义:本质上还是一个函数,具有指针类型返回值的函数,我们便称其为指针函数。

指针函数返回的指针类型

  1. 局部变量的地址不能被返回(变量、数组);

    charstr[32]={"hello world"};

  2. 具有静态生命周期的变量的地址可以被返回。

    1. static修饰的静态变量地址。
    2. 全局变量的地址。
  3. 可以返回字符串常量的地址。

    char*str="hello world!";
  4. 可以返回通过参数传递给该函数的地址。

    strcpy(dst,src);
  5. 可以返回堆区申请且没有被释放的空间地址。

6.7 函数指针

定义:本质上还是一个指针,指向函数,我们便称其为函数指针。
函数:函数的函数名,为函数的入口地址。
函数的指针语法

  1. 定义函数指针:返回值类型 (*指针名称)(形参表)
    函数声明:intfun(intnum1,intnum2);函数指针:int(*pfun)(int,int);定义了一个函数指针变量,该指针变量在内存占8字节 该函数指针可以指向具有int类型返回值,两个int类型形参的函数。char*(*pfun)(char*);
    注意int *fun(int, int )为指针函数。
    int (*pfun)(int, int)为函数指针。
  2. 函数指针初始化
    int(*pfun)(int,int)=NULL;
  3. 函数指针赋值:
    intadd(intnum1,intnum2){}int(*pfun)(int,int)=NULL;pfun=add;
  4. 函数指针调用函数:
    函数名(实参表);函数指针名(实参表);
  5. 函数指针的应用
    • 回调函数
      1. 将函数作为某个函数的参数传递,传递的函数称为回调函数。
      2. 降低代码耦合度,减少重复代码。

6.8 const修饰的指针

const:read only ——>只读,必须初始化。

constintnum=10;该变量只允许被使用,不允许被改变。constint*p;——>intconst*p 等价。intconst*p;——>修饰*p,对指针p指向的内容修饰。即p指向的内容不可改变。 p=&num//ok*p=1000;//noint*constp;——>修饰p,指针p只读,不能修改。因此定义该指针时必须为其初始化。 p=&num//no*p=1000;//okconstint*constp;与下面等价。intconst*constp;p的指向不能修改,*p中的内容也不允许修改,记得初始化。

6.9 void*指针

void*:缺省类型指针。只是一个保存地址编号的变量。是一个万能指针

void*<——char*int*short*double*float*void*p;*(int*)p;*(char*)p;

char *int *short *double *float *:这些指针不仅保存地址,还有具体指向,可以明确指向sizeof(基类型)个字节空间。

注意void *可以看作一个高精度的指针,其余看作低精度,即可以将其看作一个隐式转换。

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

MyBatis-Plus分页机制深度解析与性能优化

1. MyBatis-Plus分页机制原理解析MyBatis-Plus的分页功能本质上是对MyBatis原生分页的增强封装。其核心实现原理是通过ThreadLocal保存分页参数&#xff0c;在执行SQL前动态拦截并重写语句。具体工作流程如下&#xff1a;调用Page构造函数创建分页对象时&#xff0c;会自动将分…

作者头像 李华
网站建设 2026/8/9 6:09:27

code-review:LLM 早就懂这些规则,为什么还会看走眼

同一个模型&#xff0c;同一份 review 清单。这次它精准指出"这个函数嫉妒了另一个对象的数据&#xff0c;该搬过去"&#xff0c;下次面对更简单的代码&#xff0c;它却只回一句"整体看起来不错"。 它不是忘了规则。Feature Envy、Duplicated Code、命名该…

作者头像 李华
网站建设 2026/8/9 6:06:34

OpenAI暂停Astra — 首次触发AI网络安全“关键级“红线深度解析

一、引言:AI安全史上的分水岭时刻 2026年8月7日,OpenAI在其官方博客上发布了一篇看似简短、却足以撼动整个AI行业的公告——《Responding to the next frontier of critical cyber capabilities》。公告的核心信息只有一句话: “We cannot rule out critical cyber capabil…

作者头像 李华
网站建设 2026/8/9 6:04:08

26年论文写作AI工具打分:5款一站式横评

又到论文季&#xff0c;后台私信里问“论文写作全流程AI工具到底哪个能打”的就没断过。市面上号称全能的一抓一大把&#xff0c;可真到开题、初稿、降重、改格式这一套走下来&#xff0c;能撑住的没几个。这次我挑了5款热度高、都宣称覆盖全流程的工具&#xff0c;用一篇文科硕…

作者头像 李华