指针就是变量的地址,通过指针可以找到他的地址单位,存放内存单元编号
内存单元大小:一个字节
指针变量:存放变量地址的变量
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a;//指针变量 p 存放 a 的地址
return 0;
}
指针变量大小:
32位、一个指针变量占 4 个字节
64位、一个指针变量占 8 个字节
指针类型:决定指针解引用操作时候,能访问空间大小
char* p; *p 能访问 1 个字节
int* p; *p 能访问 4 个字节
double* p; *p 能访问 8 个字节
指针+-整数
指针类型决定指针走一步做多远(多少字节)(步长)
指针向后平移多少字节
char* p; p + 1 --> 1
int* p; *p; p + 1 --> 4
double* p; p + 1 --> 8
野指针 :指针指向位置不可知(不确定,不正确,无限制,随机)
导致原因:
1、指针未初始化 局部变量不初始化就是随机值
int* p; //局部指针变量
*p = 10;
2、指针越界访问
访问数组超出数组的宽度后
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i < 12; i++)
{
*(p++) = i;
}
}
3、指针指向内存空间释放
规避野指针:
指针初始化:
int a = 10;
int* p = &a;//指针初始化
int* pa = NULL;//定义空指针,((void *)0)
指针不越界:
不让指针访问超过的可访问空间
指针指向空间:
指针指向空间被释放,可以将指针置NULL
指针使用前检查有效性:
指针与数组
数组的首元素的地址和数组名等价
绝大多数情况下数组名就是数组的首地址(有两种特殊情况)
下面两种情况:
1、&数组名:不是数组首地址,整个数组的地址(数组名表示整个数组)
2、 sizeof(数组名):数组名表示整个数组,计算的是整个数组的大小(字节)
指针减指针得到的是指针之间的个数(大地址减小地址)
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存空间的指针比较,不允许与指针指向第一个元素之前的那个内存位置指针比较。
计算字符串长度
#include<stdio.h> int my_strlen(char* str)//计算字符串长度 { char* start = str; char* end = str; while (*end != '\0') { end++; } return end - start; } int main() { char arr[10] = "hello";//h e l l o \0 int len = my_strlen(arr); printf("%d\n", len); return 0; }
指针访问数组:
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = arr;
for (i = 0; i < sz; i++)
{
*(p + i) = i;
}
for (i = 0; i < sz; i++)
{
printf("%d", *(p+i));
}
return 0;
}
二级指针:
写法:
#include<stdio.h>
int main()
{
int a = 10;
int* pa= &a;
int* * ppa = &pa;//ppa 为二级指针
int* * * pppa = &ppa;//pppa 为三级指针
//.........多级指针依此类推return 0;
}
原理:
数组指针--是指针
指针数组--是数组
#include<stdio.h>
int main()
{
//指针数组
int a = 1;
int b = 2;
int c = 3;
int* arr[3] = { &a,&b,&c };
for (int i = 0; i < 3; i++)
{
printf("%d ", *arr[i]);
}
return 0;
}