【C语言】指针

指针是什么?

指针理解的2个要点:

  1. 指针是内存中一个最小单元的编号,也就是地址。
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量。

总结:指针就是地址,口语中说的指针通常指的是指针变量。

那么这里就有以下两种理解:

  1. 内存

把内存划分为一个一个的内存单元,这个内存单元的大小为一个字节。给每个字节一个唯一的编号,我们将这个编号称为地址,地址在C语言中也叫指针。

【C语言】指针_第1张图片

编号 == 地址 == 指针

  1. 指针变量

我们可以通过&(取地址操作符)取出变量的内存的起始地址,把地址可以存放到一个变量中,这个变量就是指针变量。

【C语言】指针_第2张图片

总结:指针变量,用来存放地址的变量。(存放在指针变量中的值都被当成地址处理)。

指针和指针类型

指针和变量一样,都有不同的类型。要将&num(num的地址)保存到p中,我
们知道p就是一个指针变量,我们需要给指针变量相应的类型:

  • char* 类型的指针是为了存放 char 类型变量的地址。
  • short* 类型的指针是为了存放 short 类型变量的地址。
  • int* 类型的指针是为了存放 int 类型变量的地址。
  • long* 类型的指针是为了存放 long 类型变量的地址。
  • float* 类型的指针是为了存放 float 类型变量的地址。
  • double* 类型的指针是为了存放 double 类型变量的地址。

指针的定义方式是: type + * 。

  • char* p = NULL;
  • short* p = NULL;
  • int* p = NULL;
  • long* p = NULL;
  • float* p = NULL;
  • double* p = NULL;

而无论指针类型是什么,指针的大小始终在32位平台是4个字节,在64位平台是8个字节。那么指针类型存在的意义又是什么呢?请接着往下看看吧!

指针±整数

指针类型的第一个意义:指针的类型决定了指针向前或者向后走一步有多大(距离)。

【C语言】指针_第3张图片

指针的解引用

指针类型的第二个意义:指针的类型决定了对指针解引用的时候有多大的权限(能操作几个字节)。

int* 的指针的解引用就能访问四个字节。

【C语言】指针_第4张图片
【C语言】指针_第5张图片

char* 的指针解引用就只能访问一个字节。

【C语言】指针_第6张图片
【C语言】指针_第7张图片

野指针

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

野指针成因

  1. 指针未初始化(局部变量指针未初始化,默认为随机值)
#include 
int main()
{
    int *p;   //局部变量指针未初始化,默认为随机值
    *p = 20;
    return 0;
}
  1. 指针越界访问
#include 
int main()
{
    int arr[10] = {0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
    {
            //当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
    }
    return 0;
}
  1. 指针指向的空间释放
#include
 
int* test()
{
    int a = 10;  //变量a在出了test()函数后消失
    return &a;
}
 
int main()
{
    int* p = test();
    *p = 100;
    return 0;
}

如何规避野指针

  • 指针初始化
  • 小心指针越界
  • 指针指向空间释放,及时置NULL(一个指针不知道该指向哪里的时候,暂时可初始化NULL)
  • 避免返回局部变量的地址
  • 指针使用之前检查有效性

指针运算

指针±整数

示例1:模拟实现求字符串长度的函数。

【C语言】指针_第8张图片

示例2:利用指针初始化数组。

【C语言】指针_第9张图片

指针-指针

指针-指针相当于地址-地址,但有两个前提:

  1. 两个指针指向同一块空间
  2. 指针的类型是一致的。

指针-指针得到的是元素之间的个数。(大指针-小指针是正数,小指针-大指针是负数)

【C语言】指针_第10张图片
【C语言】指针_第11张图片

示例1:模拟实现求字符串长度的函数。

【C语言】指针_第12张图片

指针的关系运算

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

【C语言】指针_第13张图片

化简上述代码后:

【C语言】指针_第14张图片

虽然比原来的代码阅读起来更清晰,但是不推荐,原因如下:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

指针和数组

数组名表示的是数组首元素的地址。(2种情况除外,数组博客有讲解)

【C语言】指针_第15张图片

指针可以指向数组元素,因为指针可以运算,所以可以借助指针访问数组。

【C语言】指针_第16张图片

二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在二级指针里。

【C语言】指针_第17张图片

【C语言】指针_第18张图片

关于二级指针的运算:

  • *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa。
  • **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a 。

指针数组

指针数组:存放指针的数组。

【C语言】指针_第19张图片

使用指针可以将一维数组模拟为二维数组。

【C语言】指针_第20张图片

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