1.什么是指针
计算机中所有的数据都必须存放在内存中,不同类型的数据占用的字节数不一样,为了正确地访问这些数据,必须为每个字节都编上号码,每个字节的编号是唯一的,根据编号可以准确地找到某个字节,我们将内存中字节的编号称为地址或者指针,地址从0开始依次增加,对于32位环境,能使用的内存位4gb。
2.定义指针变量
定义指针变量与定义普通变量非常类似,不过要在变量前加上*号
datatype*name或者datatype*name=&value
int main()
{
int a = 10, b = 20;
int* ip = NULL;
ip = &a;
*ip = 100;
ip = &b;
*ip = 200;
return 0;
}
ip=>&a
*ip=>*&a 编译器自动删除*&
int main()
{
int a = 10, b = 20;
int* ap = &a;
int* bp = &b;
if (ap > bp)//&a>&b
{
}
if (*ap > *bp)//a>b
{
}
}
值传递
void swap_a(int a, int b)
{
int c = a;
a = b;
b = c;
}
int main()
{
int x = 10, y = 20;
printf("x=%d y=%d", x, y);
swap_a(x, y);
printf("x=%d y=%d", x, y);
return 0;
}
地址传递
void swap_b(int *ap, int *bp)
{
int c = *ap;
*ap = *bp;
*bp = c;
}
int main()
{
int x = 10, y = 20;
printf("x=%d y=%d", x, y);
swap_b(x, y);
printf("x=%d y=%d", x, y);
return 0;
}
int fun(int* p)
{
int a = 200;
*p = 100;
p = &a;
}
int main()
{
int x = 0;
int* s = &x;
fun(s);
printf("%d %d\n", x ,* s);
return 0;
}
3.野指针和空指针,空悬指针,失能指针
int main()
{
int a;//随机值
int* ip;//随机值 野指针
a = 10;
a = *ip;//未初始化不能使用
*ip = 100;
return 0;
}
int main()
{
int a = 10;
int* p = &a;
int* s = NULL;//如果在定义指针变量时不能确定此指针变量指向哪个地址,就可以把它定义成空
if (s != NULL)//使用指针前要判空
{
a = *s;
*s = a;
}
return 0;
}
定义指针变量要初始化
如果在定义指针变量时不能确定此指针变量指向哪个地址,就可以把它定义成空
使用指针前要判空
4.失效指针 悬空指针
void printfAr()
{
int x = 20;
int ar[10] = { 12,34 };
}
int* fun()
{
int a = 100;
int* p = &a;
return p;
}
int main()
{
int* ip = NULL;
ip = fun();
// printfAR();
if (ip != NULL)
{
printf("ip %p => *ip %d\n", ip, *ip);//ip的地址 100
}
return 0;
}
*ip的值改变的原因:栈帧被释放了
在调用过fun函数后,fun函数所占用的栈帧被释放了,残留数据被再次调用的print函数覆盖,所以*ip找不到原来的值了,当不调用print函数时,*ip还可以找到残留的值。所以*ip变成了失效指针。
总结:不要返回一个局部变量的地址,当我们调动此函数,系统为它分配栈帧,当调用结束时,系统会收回栈帧,即使能拿到地址,这个地址也是一个失效指针,它已经还给系统了,不能对他赋值和取值。
q:如果使用静态关键字,可以正常返回地址吗?
a:局部静态变量不占用栈区,编译器会将其放入.data区,数据区的生存期不受函数的影响。
int* fun()
{
static int a = 10;
return &a;
}
int main()
{
int* ip = NULL;
ip = fun();
printf("%d\n", *ip);
return 0;
}