1.指针是什么
指针是内存中一个最小单元的编号,也就是地址
平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量总结:指针就是地址,口语中说的指针通常指的是指针变量。
指针就是地址,口语中说的指针通常指的是指针变量。
对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0)
就会有2的32次方地址 4GB
在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。
那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址
2.指针和指针类型
指针类型的意义
指针类型决定了指针在被解引用的时候访问几个字节
int* 的指针,解引用访问4个字节
char*指针,解引用访问1个字节
指针类型决定了指针+-1操作的时候,跳过了几个字节
int*p *p+1 跳过四个字节
char*p *p+1 跳过一个字节
3.野指针
概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
成因:(1)没有初始化//一个局部变量不初始化,放的值是随机的
(2)指针越界访问
(3)指针指向空间释放
如何避免:(1)指针初始化
(2)小心指针越界
(3)指针只想空间释放即设置NULL
(4)避免返回局部变量的地址
(5)指针使用之前检查有效性
int*test()
{
int a=10;
return &a;
}
int *p=test()
变量a出函数之后就销毁了,指针没有控制a地址的权力
此时执行别的操作可能会改变a的值
int*p=NULL;
if(*p!=NULL)
{
*p=100;
}
4.指针运算
(1)指针加减整数
int main()
{
int arr[10] = { 0 };
int i = 0;
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
arr[i] = 1;
}
for (i = 0; i < sz; i++)
{
*p = 1;
p++;
}
return 0;
}
(2)指针-指针
//指针减指针 指针-指针的绝对值,得到的是指针和指针之间元素的个数
//指向同一块空间的指针相减才有意义
int main()
{
int arr[10] = { 0 };
printf("%d",&arr[9]-&arr[0]);//结果为9
return 0;
}
int my_stlen(char* str)
{
char* start = str;
if (*str != '\0')
{
*str++;
}
return (str - start);
}
(3)指针的关系运算
允许指向数组元素的指社与指向数组最后一个元素后面的那个内存位置的指针比较,
但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
5.指针和数组
数组可以通过指针来访问
数组名表示数组首元素地址
&arr[i]==p+i *[p+i]=*[arr+i]
6.二级指针
用来存放一级指针变量的地址
int main()
{
int a = 10;
int* pa = &a;//pa是一个指针变量,一级指针变量
int* *ppa=&pa;//ppa是一个二级指针变量,前面一颗星表示ppa指向的的数据类型是int*
*ppa = 20;
return 0;
}
7.指针数组
存放指针的数组
int* parr[10] = { &a,&b }; *(parr[i])
可以用来模拟二位数组