指针(Pointer)"/>
初阶指针(Pointer)
⛩️博主主页:@威化小餅干
📝系列专栏:【C语言】藏宝图
🎏 ✨绳锯⽊断,⽔滴⽯穿!一个编程爱好者的学习记录!✨
🚀目录
指针是什么
指针和指针类型
野指针
指针运算
指针和指针数组
指针数组
🤔一、指针是什么
计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节,char 占用 1 个字节。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。
我们将内存中字节的编号称为地址(Address)或指针(Pointer)
生活栗子🌰
指针的理解:
把内存划分为一个个的内存单元,这个内存单元的大小是1个字节。
每个字节都给唯一的编号,这个编号我们称为地址,地址在C语言中也叫指针。
指针是内存中最小单元的编号,也就是地址。
用一句话说就是:
编号==地址==指针
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>int main()
{int a = 10;//a是整型,占用4个字节的内存空间,每一个字节都有对应的地址int* pa = &a;//&a——得到的是a的地址(指针),其实得到的是a所占内存中4个字节中第一个字节的地址,pa是指针变量pa = 10;//10放在指针变量pa里,就是地址return 0;
}
总结:
指针就是地址,平时口语中说的指针通常指的是指针变量。
只有把一个值放到指针变量里,它都会被当成地址处理。
”在锤子的眼里,什么都是钉子;在指针变量眼里,什么都是地址。“
一个小单元为1个字节
内存,就好比一间大房子,里面有很多房间,为了能快速找到内存里面的值,我们给每一个房间一个编号,这就是内存编号,这样就可以通过编号找到相应的值了。
经过仔细的计算和权衡,我们发现一个字节给一个对应的地址是比较合适的,太大浪费,太小又存不下。
🤔内存是如何编址的?
对于32位的机器,假设有32根地址线,那么每根地址线在寻址的时候产生高电压和低电压就是(1或0)
32根地址线产生的二进制序列:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
....
11111111 11111111 11111111 11111111 ——>一个地址编号
经过计算,可以得到有2的32次方个地址,每一个地址标识一个字节,能对4G的空间进行编址。
指针的大小
在32位平台中,占用4个字节
在64位平台中,占用8个字节
🌈二、指针和指针类型
根据指针指向元素的类型不同,指针也有不同的类型 int*, char*...等。
我们知道,在32位平台下,所有的指针类型都是占用4个字节,既然指针类型占用的内存空间都是个字节,又何必搞这么多不同类型的指针呢? 🤔
指针类型的第一个意义:
指针类型决定了,在解引用指针的时候能够访问几个字节,不同类型的指针访问的权限不同。
int* //能访问4个字节,对数据进行修改时,一次将会修改4个字节
char* //能访问1个字节,对数据进行修改时,一次只会修改1个字节
指针类型的第二个意义:
指针类型决定了,指针进行+1,-1的时候,一步能走多远。(距离)
#include<stdio.h>int main()
{int a = 10;int* pa = &a;char* pc = &a;printf("%p\n", pa);printf("%p\n", pa + 1);printf("\n");printf("%p\n", pc);printf("%p\n", pc + 1);return 0;
}
pa指向整型,因此pa+1应该指向下一个整型,一个整型类型的大小为4个字节,则整型指针+1后跳过4个字节。
pc指向字符型,因此pc+1应该指向下一个字符,一个字符类型的大小为1个字节,则字符型指针+1后跳过1个字节。
🚨三、野指针
概念:野指针就是指针指向的位置是不可知的、随机的、不正确的,没有明确限制的。
野指针是很危险的,它访问的空间是不可知的,就好比在大街上的一条疯狗,到处乱逛,随时都会咬人。
野指针成因:
指针未初始化
一个指针不知道应该指向哪里的时候,暂时可以初始化为空指针NULL
int* p = NULL;
指针越界访问
指针指向的空间释放
就好比如有一个男孩和一个女孩恋爱了,在一起了建立了联系;有一天男孩和女孩分手了,分手之后呢,那个男孩还老是记得女孩的电话号码,原来他俩关系还是很好的,所以p里面可以存放她的地址(电话号码),但是现在已经分手了,a已经不是他的女朋友了,那个男孩还老是记得女孩的电话号码,天天打电话骚扰,这样就很尴尬了,可能连朋友都做不了了。
🤔如何规避野指针
指针初始化
小心指针越界
指针指向空间释放,及时置为空指针NULL
避免返回局部变量的地址
指针使用之前检查有效性
...
💪四、指针运算
指针+-整数
指针-指针
指针的关系运算
指针-整数
例如在自行设计strlen函数中:
#include<stdio.h>int my_strlen(char* str)
{int count = 0;while (*str != '\0'){count++;str++; //str = str + 1; 指针+-整数}return count;
}int main()
{int len = my_strlen("abcdef");printf("%d ", len);return 0;
}
指针+-整数 ==指针
指针-指针
地址-地址
前提:两个指针指向同一块空间
指针-指针得到的是指针和指针之间的元素个数。
指针-指针==整数
指针的关系运算
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
🌞五、指针和指针数组
指针就是指针,数组就是数组,它们 不是等价的。
区别:
指针的大小:4/8个 字节,指针是存档地址,地址的存放需要多大空间,指针变量的大小就是多少。
数组的大小:取决数组的元素个数和每个元素的类型。
指针与数组的联系:
指针是可以指向数组元素的。
因为指针可以运算,所有借助于指针可以访问数组。
📌六、二级指针
指针变量也是变量,是变量就有地址,那么指针变量的地址又可以存放在哪里呢?🤔
答案——>二级指针
*ppa通过对ppa中的地址进行解引用,这样找到的是pa
*ppa其实访问的是pa
💡七、指针数组
🤔指针数组是指针还是数组?
答案:是数组。是存放指针的数组。
#include<stdio.h>
int main()
{int a = 10;int b = 20;int c = 30;//指针数组就是存放指针的数组int* arr[] = { &a,&b,&c };int i = 0;for (i = 0; i < 3; i++){printf("%d ", *(arr[i]));}return 0;
}
arr是一个数组,有六个元素,每一个元素是一个整型指针。
完结
✨✨创作不易,还请各位小伙伴多多点赞关注收藏✨✨
更多推荐
初阶指针(Pointer)
发布评论