C语言指针(初阶)

C语言指针的内容比较多,同时也比较难,打算将指针的内容分成两部分,指针中比较容易的内容放在初阶,指针高阶的内容后续会出

目录

1.什么是指针?

1.1地址的产生

2.指针的类型

3.野指针

3.1野指针成因

3.2规避野指针

 4.指针运算

4.1指针+/-整数

4.2指针-指针

4.3指针关系运算

5.二级指针

6.指针数组


1.什么是指针?

这个在之前博客中有过介绍,这里再重复一遍,顺便水一下博客字数

指针就是地址,我们口头说的指针通常指的是指针变量。关于地址那就需要从内存说起

为使内存空间的大小有效的使用和管理,内存空间被划分为多个小的内存单元,就像我们国家有23个省,各个省又划分为多个城市,城市又划分为多个区等等,一个内存单元的大小是1个字节,每个内存单元都有一个编号,这个编号就是地址,指针变量就是用于存储这些地址的变量

那么这些地址是怎么产生的?

1.1地址的产生

地址的产生和计算机的操作系统有关,右击“我的电脑”点击属性,可以看到计算机的操作系统,有些是32位,有些是64位,这些数字代表的是地址线的数量。在计算机通电后,电信号转换成数字信号(1/0),1和0随机排列组合,这些随机排列的1和0就是地址。

在32位机器下一个地址的大小为32bit,即4byte,64位机器地址大小为8byte,32位机器下共产生2^32个地址,一个地址代表着一个字节大小的内存单元,2^32byte=4GB,所以32位机器的内存通常为4GB,64位机器同理,内存大小通常为8GB

2.指针的类型

数据有不同的类型,像char、int等,相应的也会有不同类型的指针用于接收,那不同类型的指针它们不同在哪里?

1.不同类型的指针访问的字节大小不同

我们来看看下面代码的结果:

int main()
{
	int a = 0x11223344;
    char *pc = (char*)&a;
    *pc = 0;
    printf("%x\n", a);
    return 0;
}

现在把pc的类型改为int

 

 会有这样的结果是因为指针类型的不同,指针在进行访问的时候访问的字节的大小也不同,int*pc可以访问4个字节大小,所以*pc=0时a也为0,而char*pc在进行访问的时候只能访问一个字节大小,但a本身的大小为4个字节,故只能修改部分数据,为什么修改的是44这个和数据的存储有关,后续博客中会详细介绍

2.指针类型不同,步长不同

如图:

 同样的,*p和*c的值还是不同,初始时二者都是指向数组的首元素,因为指针类型的不同,p和c分别++后,p走的字节大小为4,而c是1,所以++后*p指向数组的第二个元素,而c依旧在首元素内

3.野指针

概念:指针指向的地址不可知

3.1野指针成因

1.指针未初始化

像下列代码:

int main()
{ 
    int *p;
    *p = 20;
    return 0;
}

这个代码是无法运行的,运行时程序直接报错

 指针未初始化的时候,它指向的地址以及地址里的内容都是未知的,所以指针一定要初始化

2.越界访问

比如数组里面10个元素,你用指针访问第11个元素,指针访问的内容超出了数组的界限,这时指针就成为了野指针

3.指针指向的空间释放的时候指针未指向NULL

这里不展开,后续在动态内存开辟的时候详细讲解

3.2规避野指针

1.指针初始化

2. 小心指针越界

3. 指针指向空间释放即使置NULL

4. 避免返回局部变量的地址

5.在使用指针之前检查指针的有效性

关于第4点,假设现在有如下代码:

int*test()
{
    int a=100;
    return &a;
}
int main()
{
    int *p=test();
    printf("%d",*p);
}

虽然结果是100,但a是函数内的局部变量,程序出函数的时候a就被销毁,空间也返还给了内存,此时p保存着a的地址,但地址里面已经不是a了

 4.指针运算

4.1指针+/-整数

指针+/-整数表示的是指针走的步长

int main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int *p=arr;
    p=p+2;
    return 0;
}

p最初指向arr[0],+2后便指向arr[2]

4.2指针-指针

指针和指针相减,结果为二者之间的相隔的元素的个数,前提是两个指针指向的是同一块空间

4.3指针关系运算

C语言的标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与 指向第一个元素之前的那个内存位置的指针进行比较

如图:

5.二级指针

既然指针是用来存储变量的地址的,那么理论上指针本身的地址也可以被存储,那么存储指针的地址的变量是什么?

这便是二级指针,二级指针的创建如下:

int a=10;
int*p=&a;
int**pa=&p;

 二级指针解引用时,*pa找到的是指针p,**pa找到的是a

既然有二级指针,那么理论上也应该有三级指针、四级指针等等,不过意义不是特别大,就像数组使用最多的也只是一维数组和二维数组

6.指针数组

主体是数组,数组中的元素是指针

指针数组创建

int* arr3[5];
//数组arr内有5个元素,元素的类型为指针

 

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星鸦wyk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值