C---指针
目录
- 什么是指针变量?
- 指针偏移问题:
- 为什么用指针?
- 1.强制给指针选地址:
- 2.交换两个变量的值
- 指针与数组
- 1.指针数组:数组中的每一项都是个指针
- 2. 指针数组的用法
- 数组指针:一个指向数组的指针
- 函数指针:
- malloc
- 内存泄露(面试)
- 野指针:
- 指针综合:
什么是指针变量?
整形变量存放的是整数
字符变量存放的是字符
指针变量存放的是地址
int a;
int *p = &a;
*p = &a; // 不能这么写
*只有在定义指针变量时,才是指针的标识符。
其他情况只是个运算符,同+-*/
指针偏移问题:
int *p;
p++ // 偏移4个字节
char *p2;
p2++ // 偏移1个字节
为什么用指针?
1.强制给指针选地址:
int *p = (int *)0x0060ff00; // 强制在某个地址里写东西(指针的牛逼之处)
//这种写法在以后学习ARM架构 裸机编程 ARM驱动 用的多
volatile:(编译器的优化)(面试)
在本次线程内,当读取一个变量时,为了提高读取速度,编译器进行优化时有时会先把变量读取到一个寄存器中;以后,再读取变量值时,就直接从寄存器中读取;当变量值在本线程里改变时,会同时把变量的新值复制到该寄存器中,以保持一致。
2.交换两个变量的值
int main()
{
int a = 10;
int b = 5;
int tmp;
tmp = a; //把a的值给tmp 此时tmp = 10
a = b; //把b的值给a 此时 a = 5
b = tmp; / / 把tmp的值给b 此时 b = 10;
return 0;
}
执行结果 a= 5 b=10
函数封装:
void swap(int a,int b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 10;
int b = 5;
swap(a,b);
printf("a = %d\n",a);
printf("b = %d\n",b);
return 0;
}
执行结果a = 10 b=5
因为子函数是在另一个地址空间修改a的值,子函数调用结束后,该内存空间被释放(白修改了)到主函数时a的值没有改变。
值不会发生改变,但是用指针就可以改变了
使用指针:
void swap(int *a,int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a = 10;
int b = 5;
swap(&a,&b);
printf("a = %d\n",a);
printf("b = %d\n",b);
return 0;
}
执行结果 a= 5 b=10
相比于上一种,传参时应该把地址传过去,直接在a的地址里改动,而不是新申请一个地址改动
指针与数组
1.指针数组:数组中的每一项都是个指针
int a = 2;
int b = 3;
int c = 4;
int array[3];
int *parray[3];
parray[0] = &a;
parray[1] = &b;
parray[2] = &c;
2. 指针数组的用法
int array[5];
int *parray;
parray = array;
for(i=0;i<5;i++){
printf("%d\n",parray[i]); //可以这样写
因为数组名就是地址,指针指向了该数组名,就可以用指针加[i]
}
数组指针:一个指向数组的指针
1.写法: int (*p)[3];
2.数组指针偏移问题:++偏移整个数组的大小
函数指针:
1.写法: void *p();
(定义指针时带个括号就肯定是函数指针)
2.格式要求:参数 类型 个数 返回值
void printwelcome()
{
printf(".......");
}
void (*p2)(); //定义
p2 = printwelcome; //给函数指针赋值
//两种调用方式:
p2(); //调用
(*p2)(); //调用 把内容取出来
malloc
size_t: 整型数的子集
int *a = (int *)malloc(12);
语句解释:malloc的返回值是无类型的,开辟出来的12个字节的内存空间强制给他变成整型。
(把无类型变成整形)
再定义一个指针指向开辟出的这块空间。
也可以是数组的定义方式。
int main()
{
int n;
printf("请输入学生个数:\n");
scanf("%d",&n);
int *parray = (int *)malloc(n* sizeof(int )); //开辟空间,定义数组
int i;
for(i=0;i<n;i++){
printf("请输入第%d个学生的成绩:\n",i+1);
scanf("%d",&parray[i]);
}
for(i=0;i<n;i++){
printf("第%d个学生的成绩是:%d\n",i+1,parray[i]);
}
system("pause");
return 0;
}
内存泄露(面试)
1.内训泄露的现象:程序刚跑起来时没问题,一段时间(几天,几周)后程序崩溃
2.malloc申请的空间,程序不会主动释放,程序结束后,系统会回收这个空间
3.如何避免:
注意在循环中有没有一直申请;
有没有及时合理的释放 free();
while(1){
sleep(1); //每隔一秒
int *p = malloc(1024); //申请1M空间
}
free(p); //及时释放
p = NULL; //不让他变成野指针
野指针:
int *p; //野指针
int *p = NULL; //不是野指针
指针综合:
1.定义一个整型变量:
int a;
2.定义p为指向整行数据的指针变量
int *p;
3.定义整型数组a,他有五个元素
int a[5];
4.定义指针数组p,它由四个指向整形数据的指针元素组成。
int *p[4];
5.p为指向包含4个元素的一维数组的指针变量。
int (*p)[4];
6.f为返回整型函数值的函数
int f();
7.p为返回一个指针的函数,该指针指向整型数据。
int *p(); //记住
8.p为指向函数的指针,该函数返回一个整型值。
int (*p)(); //不熟悉
9.p是一个指针变量,它指向一个指向整型数据的指针变量
int **p //二级指针
10.p是一个指针变量,基类型为void,不指向具体对象。
void *p