欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > C语言指针

C语言指针

2025/5/15 6:18:02 来源:https://blog.csdn.net/DXY798/article/details/146610462  浏览:    关键词:C语言指针

1.指针变量和地址

其实在代码中定义一个局部变量,就是向内存中申请一块空间,这块空间的名称就叫做地址

而 地址==指针

1.1.指针的两个操作 & 和 *

&:取地址操作符

表示将a的地址取出来给p

*:解引用操作符

取出p指向地址中的值

int* p = &a;

int:在说明指向的对象是int

*:说明p是指针变量

1.2.指针变量的大小

也就是:

char*指向字符的指针

short*指向短整型的指针

int*指向整型的指针

float*指向单精度浮点型的指针
void*无具体类型的指针

的大小

32位平台下地址是32个bit位,指针变量⼤⼩是4个字节
64位平台下地址是64个bit位,指针变量⼤⼩是8个字节
注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。

2.指针变量类型意义

2.1.解引用

下面创建了一个int类型的a 

第一次解引用是用int*来接受

第二次解引用是用char*来接受

但是对解引用的值进行改变的时候,int*可以改变4字节没问题,但是char*只能改变一个字节

2.2.决定了指针的步长

也是用char*和int*进行对比

p地址+1的时候加的是int的4个字节

q地址+1的时候加的是的char的1个字节

结论:
指针类型决定了指针的步长,就是向前/向后走一步走多大距离


type* p;
p+i 是跳过i个type类型的数据相当于跳过了i*sizeof(type)个字节

 

2.3.void*

这种类型的指针可以⽤来接受任意类型地址。但是也有局限性, void* 类型的指针不能直接进
⾏指针的+-整数和解引⽤的运算。

3.count修饰

const本身的的作用是将可改变的变量修饰为不可改变的常变量,

但是,const修饰以后还是一个变量

const修饰指针

分为两种

1.const int * p:地址指向的内容本身不可以被修改

2.int *  const p:地址本身不能被修改

结论:const修饰指针变量的时候
const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。
但是指针变量本⾝的内容可变。
const如果放在*的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指
向的内容,可以通过指针改变。

4.指针之间的运算

指针的基本运算有三种,分别是:
1.指针+- 整数
2,指针-指针
根据    指针+整数=指针, 那么     指针-指针=整数
所以 指针-指针 得到的就是指针与指针之间的元素个数
但是有个前提条件,就是两个指针之间指向的是同一块空间
3. 指针的关系运算

5.野指针

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

5.1.野指针的形成

1. 指针未初始化

2. 指针越界访问

3. 指针指向的空间释放
随着函数的结束,其中的变量也会被进行销毁

5.2.野指针的规避

1.初始化为NULL

如果明确知道指针指向哪⾥就直接赋值地址,
如果不知道指针应该指向哪⾥,可以给指针赋值NULL.
NULL 是C语⾔中定义的⼀个标识符常量,值是0,0也是地址,
这个地址是⽆法使⽤的,读写该地址 会报错。
2.小心指针越界
⼀个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是 越界访问。
3.指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性
4.避免返回局部变量的地址

6.assert断言

assert.h 头⽂件定义了宏 assert()
⽤于在运⾏时确保程序符合指定条件,如果不符合,就报 错终⽌运⾏。这个宏常常被称为“断⾔”。
true继续执行,false进行报错

7.指针的使用

1.使用指针完成个strlen的功能

strlen的功能是求字符串⻓度,统计的是字符串中 \0 之前的字符的个数。

自我实现

2.使用指针完成数值之间的交换
结论:实参传递给形参的时候,形参会单独创建⼀份临时空间来接收实参,对形参的修改不影响实
参。

8.指针与数组

8.1.数组名的理解

都知道数组名就代表数组的首元素地址,

但是

其实数组名就是数组⾸元素(第⼀个元素)的地址是对的,但是有两个例外:
1.sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节
2.&数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)
接下来,来区分  &arr[0] ,  arr  ,  &arr  三者的区别
取地址操作:
看起来指向的都是一个相同的地址地址,

+1操作;

&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,
是因为&arr[0] 和 arr 都是 ⾸元素的地址,+1就是跳过⼀个元素
&arr是数组的地址,+1 操作是跳过整个数组的。

8.2.一维数组传参的本质

int arr[] 这种形式本质上等同于 int *arr也就是它实际上是一个指向 int 类型的指针,并非真正的数组。

当你把数组作为参数传递给函数时,传递的其实是数组首元素的地址,而非整个数组的副本。

8.3数组指针

数组指针就是指向数组的指针,也是一种指针变量,用于存放数组的地址

8.4.二维数组传参本质

假设存放的是int

二维数组传参的本质是传递数组首元素的地址,但是首元素是一个int整形

二维数组传参的本质是传递数组首元素的地址,但是首元素是一个int类型的一维数组

int (*arr)[4]是一个指向包含 4 个int元素的一维数组的指针。

9.二级指针

10.字符指针变量

 指向字符串常量 和  指向字符数组进行比较

1. 指向字符串常量

str 是一个字符指针变量,它指向了字符串常量 "akjfd"的首地址

字符串常量存储在只读内存区域,不能通过指针去修改它的值。如果尝试修改,会导致未定义行为

2.指向字符数组

 指向了字符数组 arr 的首字符地址。与字符串常量不同,

字符数组存储在可读写的内存区域,可以通过指针修改数组中的字符

例题:
1.str1和str2是指向不同内存的首地址,所以肯定不相同   str1!=str2
2.str3和str4都是指向  常量字符串的首地址,而常量字符串,不能被修改,而且有且只有一份,所以str3==str4

11.函数指针变量

函数指针变量的定义:

函数指针变量的使用:

x和y加上和不写上都是可以的

11.1.typedef关键字

函数指针这个变量名字过于冗余,所以使用typedef关键字对函数指针这个变量名字进行一个取别名的操作

语法格式:

实际调用:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词