指针
计算机科学中,指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中的另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变单元。因此,将地址形象的称为"指针"。意思就是它能找到以它为地址的内存单元。
指针是地址,指针变量是变量存放的内容是地址,但实际中并不区分两者,说指针就是说指针变量
指针是用来存放地址的,地址是唯一标识一块地址空间的。
指针就大小在32平台是4个字节,在64位平台就是8个字节。
指针类和指针类型
指针:type+*
指针的类型决定了指针向前或先后走一步有多大。(对指针加1,其实是加上指针所指向类型的大小(等于加上sizeof(type类型如int char…甚至int*,char*…表示指针大小为4个字节(32位平台))))
指针的类型决定了对指针解引用的时候有多大的权限(能操作几个字节)。比如char的指针引用就只能访问一个字节,而int的指针解引用就能访问4个字节。
野指针
概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
野指针成因
- 指针未初始化
- 指针越界访问
- 指针指向的空间释放
规避野指针
- 指针初始化
- 小心指针越界
- 指针指向空间释放即置NULL
- 指针使用之前检查有效性
指针运算
- 指针±整数
#define N_VALUES 5
float values[N_VALUES];
float *vp;
for(vp=&values[0];vp<&values[N_VALUES];)
{
*vp++=0;//后置加加,先*vp再++,j就是讲数组的每个元素都置为0
}
- 指针-指针
两指针相减(两指针相减必须指向同一内存,才有意义)代表两指针之间所经历的元素(元素的类型由指针类型决定)个数
理由:
1.抽象举例:假如mine住在广场小区100号(地址)房,you住在广场小区120(地址)号房,每两个放假之间隔2个地址号 ,那么you和mine相隔10个房间
2.形象举例:两个指向同一内存的int型指针,指向不同的地址,相减为何是元素数二不是字节数,首先指针指向某个元素,其实指向的是这个元素所字节的最小字节,但是取的时候是连续读取元素类型大小的字节数,因此指针相减可以理解为是元素整体的空间相减。
int myStrlen(char *s)
{
char *p=s;
while(*p!='\0'){
p++;
}
return p-s;
}
- 指针的关系运算
for(vp=&values[N_VALUES];vp>&values[0])
{
*--vp=0;
}
for(vp=&values[N_VALUES];vp>=&values[0];vp--)
{
*vp=0;
}
实际在绝大部分的编译器上是可以顺利完成任务的,然而我们要规避这种代码,因为标准规定它不一定可以运行。
标准规定:
允许指向数组元素的指针与指向数组最后的一个元素侯曼的那个内存位置的指针进行比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
总结
2.数据的小(低)字节放到小(低)地址的地方叫做小端
3.指针之间可以进行大小比较,通常要比较的指针指向同一内存(常见指向同一数组,同一字符串)
5.指针和数组毫无关系,只是使用特征相似
6.数组名传参发生降维原因:
不降维发生数组拷贝效率低
数组传参传的是数组名,数组名就是地址也就是指针。
7.unsigned int a=-100;printf("%d",a);//a=255
理由:a变量的空间是无符号整型的四个字节,-100是负数以补码形式存在11111111最高位为符号位,存进去再次拿出来就是无符号数11111111=255
8.int a[5]={0}
指针加1就是加上指针所指向目标的类型的大小
printf("%p",a);
printf("%p",a+1);//数组首元素的地址+4个字节(int的大小) a是整型指针
printf("%p",&a+1);//数组首元素的地址加+20个字节(整个数组的大小) &a是数组指针
9.
数组元素的个数也充当数组类型的一部分。
int a[5]={0};
int (*p)[6]=&a;//警告下标不一致
10.
int *p[5];//指针数组
int (*p)[5];//数组指针