【C语言 - 初阶指针 概念、类型、野指针、指针运算】

C语言 - 初阶指针

  • 一 指针概念
    • 注意:
    • 指针变量的大小:(与指向的数据类型无关)
  • 二 指针类型
    • 2.1指针类型的含义:
      • 2.1.1 不同指针类型决定解引用时候权限不同:
        • 总结:
      • 2.1.2 任何类型的指针变量都能存放地址(即使跨类型)
  • 三 野指针(非法的指针):
    • 3.1 可能出现野指针的情况:
      • (1) 指针未初始化:指针里面是一个随机值,解引用会造成非法访问内存
      • (2) 指针越界:
    • 3.2 如何避免野指针:
  • 四 指针运算:
    • 4.1 指针+-整数:
    • 4.2 指针-指针:
  • 五 数组和指针之间的关系
  • 六 二级指针:
  • 七 指针数组:存放指针的数组(本质上是数组)
  • 其他:

一 指针概念

内存单元都有对应的编号----这个编号就称为地址(地址能够找到内存单元,形象称指针)

两层含义:

(1)某元素的地址

(2)指针变量口头也被称为指针

注意:

对某变量取地址
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第1张图片
指针是一个变量,是用来存放地址的变量:指针变量

指针变量的定义:所指向的数据类型* 指针变量名

指针变量的大小:(与指向的数据类型无关)

在这里插入图片描述

二 指针类型

2.1指针类型的含义:

2.1.1 不同指针类型决定解引用时候权限不同:

(1)int型(整形)指针解引用可以访问四个字节:

int *p;

*(p+1):跳过4个字节

(2)char型(字符型)指针解引用只可以访问一个字节

char *p;

*(p+1):跳过一个字节

总结:

  • 指针的类型决定了对指针解引用时候的权限

  • 指针的类型也决定了指针向前或者向后走一步的距离

2.1.2 任何类型的指针变量都能存放地址(即使跨类型)

int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = 1;
}

return 0;

}

arr:
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第2张图片

p+i:表示下标为i的位置

第一次循环:

p+0,指向不变

第二次:

p+1,指向第一个(跳过一个元素,4个字节)

三 野指针(非法的指针):

野指针概念:-----野狗(属于谁不可知)

指针指向的位置位置(随机/不正确的,没有限制的)

3.1 可能出现野指针的情况:

(1) 指针未初始化:指针里面是一个随机值,解引用会造成非法访问内存

这里的p被称为野指针。

局部变量如果不初始化默认为随机值。

int main()
{
int* p;//p是局部指针变量,p里面随机的值被认为是地址
*p = 20;//对随机值进行解引用操作访问空间,找到一块未知的空间(非法访问内存)
return 0;
}

(2) 指针越界:

越界示例:
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第3张图片

p的指向:
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第4张图片

因为循环进行了11次,i++10次时候,指向的是越界的指针(越界了)

3 指针指向的空间被释放了(已经不属于已有的内存空间)
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第5张图片

*p不合法:因为指向的变量a在内存中已经被释放了(销毁了)。

3.2 如何避免野指针:

1 注意指针要初始化

(1)当指针变量p初始化不知道应该指向谁的时候,定义初始化为NULL(空指针)

(2)明确知道指针变量初始化的值,将某变量的地址赋给指针变量就可

2 小心指针越界

3 指针指向空间释放之后,及时将该指针变量置为空指针

4 指针使用前要检查有效性(使用指针变量时,指针变量不能等于空指针)

四 指针运算:

4.1 指针±整数:

【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第6张图片
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第7张图片
*vp++=0:指针变量vp先解引用并且赋值操作后,指针变量再进行更改vp++(指向的位置发生变化),这里的vp++就成为指针变量的加减运算(实质上的指针指向位置的变更)

指针的关系运算(指针变量的高低比较)

【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第8张图片
p<=pend是指针的关系运算,p++是指针加整数

4.2 指针-指针:

数组中第九个元素的地址减去第0个元素的地址,得到的结果是9(两者之间元素的个数)
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第9张图片

为什么指针相减得到的是一个整数?

是两指针之间的元素个数

指针相减的前提:是两个指针指向同一块空间

利用指针相减模拟实现strlen库函数实现对数组元素个数的计数:
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第10张图片

那么指针+指针? 没什么意义
在这里插入图片描述

五 数组和指针之间的关系

数组名:就是数组首元素的地址(多个字节中的第一个字节的地址)

【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第11张图片

前后一样(p为首元素的地址,p+i就是下标为i的元素的地址)

六 二级指针:

【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第12张图片

pa指针变量也是变量,在内存中也有指针变量的地址,&pa也是可行的,取出pa在内存中的起始地址:
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第13张图片

在内存空间中:
【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第14张图片
在这里插入图片描述

因此可以有无限级指针(无限套娃)

七 指针数组:存放指针的数组(本质上是数组)

【C语言 - 初阶指针 概念、类型、野指针、指针运算】_第15张图片

其他:

指针变量的*靠近变量名称,这样同时定义多个时候不会产生歧义。

(本质上编译器都能识别)

你可能感兴趣的:(C语言笔记,c语言)