理解指针那些事

复习C/C++又到指针这里,想起大一那时候第一次学C这个简单的问题弄了好久都没理解,也是笨

关于指针在我第一次学的时候觉得绕来绕去以至于就没理解到就混了过去,网上很多文章讲指针都能讲错 也是服了

 

 

 

 

最近很想说的话: 很多以前学过的基础的东西还是有的模棱两可,学了一次不叫会了,写了博客也不叫会了,

得熟记于心能运用才叫会。

 

 

 

 

目录:

  0x01 指针定义和使用

  0x02 常量指针、指针常量、指向常量的常量指针

  0x03 野指针、空指针、万能指针

       0x04 数组指针与指针数组

  0x05 多级指针

 

 

0x01 指针定义和使用

指针:是一种数据类型 指针变量也是一种变量

指针格式: 对应的数据类型 * p:指针类型变量 用来指向一个变量的地址

int* p = &a;

通过指针修改变量的值

 *p = 200;

4、指针类型在内存中的大小 : 在32位操作系统中所有指针大小都是4个字节大小 64位是8个字节大小

  打印指针内存大小格式:

 sizeof(int *) || sizeof(p)

内存按照 unsignned int 为每个一个内存分配编号

 

解释:

①定义变量 int a =10;  数值10 存在内存 为a开辟的空间中 a的地址为0xff00 

②定义指针 int * p = &a  指针变量p 在内存中存贮的是 a的地址 0xff00,指针变量p 在内存中的大小在32位系统中都是4个字节大小

③*p = 200 通过操作指针变量p 所存储的 a的地址 来改变a的值

④指针p 有一个自己的内存地址 指针p地址 与 定义变量a的地址 0xff00不同

 

 一个很好区别的概念

*前面的是对被指向对象的修饰*后面的是对指针本身的修饰

 

 

 

0x02 常量指针、指针常量、指向常量的常量指针

常量指针(被指向的对象是常量)

又叫常指针,可以理解为常量的指针,指向的是个常量

int const* p; const int* p;

 

 

const修饰指针类型 int * 不能改变指针变量指向的内存地址的 但是可以改变指针指向的地址

#include<stdio.h>

int main()
{
    int qing = 100;
    int const* p = &qing;
    int qing2 = 200;
    printf("qing :%X\n", p);
    p = &qing2;
    printf("qing 2: %X", p);

}

 

 

 

 

 

 

指针常量(指针本身是常量)

本质是一个常量,而用指针修饰它。指针常量的值是指针,这个值因为是常量,所以不能被赋值

int* const p;

const修饰指针变量    能改变指针指向地址的,但不能改变指针指向的地址

 

#include<stdio.h>

int main()
{
    int qing = 100;
    int* const p = &qing;
    *p = 200;
    printf("qing: %d", qing);

}

 

 

 

 

 

 

指向常量的常指针

指向常量的指针常量就是一个常量,且它指向的对象也是一个常量

const修饰指针类型修饰指针变量  不能改变指针指向的的值   也不能改变指针指向的地址 

const int* const p;

一个指针常量,指向的是一个指针对象;

它指向的指针对象且是一个常量,即它指向的对象不能变化;

 

 不过这里还是可以通过原来的声明修改变量a的值 : a++;

 

 

0x03 野指针、空指针、万能指针

 

野指针:野指针是指向一个未知的内存空间,可能在读写的时候出现错误。

 0-255都是系统保留的 不可以读,不可以写

 

空指针 没有指向任何的地址(其指向0的地址)

空制指针就是指向内存编号为零的空间,操作该内存空间会报错,一般情况空指针用于程序条件判断

 

万能指针:void *  指针可以指向任意变量的内存空间

 

 

 

 

0x04 数组指针与指针数组

数组名是数组的首地址,这是一个常量

 

 

 

 

 

数组指针

指向数组的指针 

int (*p)[n]

 格式

int arr [10] = { 0 } ;  

int * p = arr;

如要将二维数组赋给一指针
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
 p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
 p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针

 

当操作指针的时候 间接操作了数组 arr[i] = p[i];

指针的降级操作 ,取当前地址的值:p[5]、*p 

 

 

 

 

指针数组

指针数组,它是数组,数组的每个元素都是指针类型。

int *p[n]

存储char *类型的地址数组

 char * arr[] ={"hello","world","niao","baobei"};

 

 

 

如要将二维数组赋给一指针数组:

int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
for(i=0;i<3;i++)
p[i]=a[i]

这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]

 

 

数组指针只是一个指针变量,指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。

 

 

 

 

 

 

 

0x05 多级指针

 

多级指针就是指针的指针的指针

例如:

int **q;

int**q 可以把它分为两部分看,即 int* 和 (*q),后面 (*q) 中的“*”表示 q 是一个指针变量,前面的 int* 表示指针变量 q 只能存放 int* 型变量的地址。

对于二级指针甚至多级指针,我们都可以把它拆成两部分。首先不管是多少级的指针变量,它都是一个指针变量,指针变量就是一个“*”,其余的“*”表示的是这个指针变量只能存放什么类型变量的地址。比如“int****a;”表示指针变量 a 只能存放 int*** 型变量的地址。

 

 

二级指针前面加** 代表指针指向一级指针指向地址的值,加*降维度

如果n级指针在前面加n个*就是指针指向一级指针指向地址的值

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章