指针:
指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑储存器中另一个地方的值,由于通过地址能找到所需的变量单元,地址指向该变量单元,因此将地址形象化的称为“指针”,意思是通过他能找到以他为地址的内存单元。描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。
int main()
{
int a = 10;
int* p = &a;//指针变量
return 0;
}
注:指针就是变量,用来存放地址的变量(存储在指针内的值都当成地址处理)
指针和指针类型
指针类型决定指针进行解引用操作的时候,可以访问空间的大小以及对指针解引用的时候有多大的权限(能操作几个字节)
int* p: *p可以访问四个字节
char* p:*p可以访问一个字节
double* p :*p可以访问八个字节
指针的意义
指针+-整数
int main()
{
int a = 0x11223344;
int* pa = &a;
char* pc = &a;
printf("%p\n", pa);
printf("%p\n", pa+1);
printf("%p\n", pc);
printf("%p\n", pc+1);
return 0;
}
int* p:p+1 ——> 4
char* p; p+1——> 1
double*p: p+1——>8
sum: 指针类型决定了:指针走一步走多远(指针的步长)(距离)
野指针
概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
1.指针未初始化
int main()
{
//int a;//局部变量不初始化,默认是随机值
int* p;//局部的指针变量,就被初始化随机值
return 0;
}
2.指针越界访问
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i < 12; i++)
{
p++;
}
return 0;
}
当指针指向的范围超过数组arr的范围时,p就是野指针
3.指针指向的空间释放
test()
{
int a = 10;//局部变量a
return &a;
}
int main()
{
int* p = test();
*p = 20;
return 0;
}
如何规避野指针:
1.指针初始化
2.小心指针越界
3.指针指向空间释放即设置NULL
4.指针使用之前检查有效性
int main()
{
int a = 10;
int* pa = &a;//初始化
int* p = NULL;//用来初始化的,给指针赋值
return 0;
}
指针运算
1.指针+-整数
2.指针-指针
3.指针的关系运算
指针+-整数
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
for (i = 0; i < 10; i++)
{
printf("%d ", *p);
p = p + 1;
}
return 0;
}
指针-指针
指针减指针得到的是指针和指针之间的元素个数
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", &arr[9] - &arr[0]);
return 0;
}
利用指针减去指针实现求字符串的长度
int my_strlen(char* str)
{
char* start = str;
char* end = str;
while (*end != '\0')
{
end++;
}
return end - start;//指针减指针
}
int main()
{
//strlen - 求字符串长度
char arr[] = "bit";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
指针的关系运算(比较大小)
规定:允许指向数组的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较
指针与数组
int main()
{
int arr[10] = { 0 };
printf("%p\n", arr);//地址 - 首元素的地址
printf("%p\n", &arr[0]);
return 0;
}
1. &arr -&数组名 - 数组名不是首元素地址- 数组名表示整个数组 -&数组名 取出的是整个数组的地址
2. sizeof(arr) - sizeof(数组名) - 数组名表示的整个数组 - sizeof(数组名)计算的是整个数组的大小
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%p ========= %p\n", p + i, &arr[i]);
}
return 0;
}
其实p + i 计算的是数组arr下标为i的地址
那我们就可以直接通过指针来访问数组
二级指针
int main()
{
int a = 10;
int* pa = &a;
int* * ppa = &pa;//ppa就是二级指针
int** * pppa = &ppa;
return 0;
}
指针数组:数组:存放指针的数组
数组指针:指针