1. 指针运算
① 算术运算:
给指针进行加减运算,+1、- 1、++、- -等运算,实际是地址计算。
例1:指针加一
int main(void)
{
char ac[]={0,1,2,3,4,5,6,7,8,9};
char *p=ac;
int ai[]={0,1,2,3,4,5,6,7,8,9};
int *q=ai;
printf("p=%p\n",p);
printf("p+1=%p\n",p+1);
printf("q=%p\n",q);
printf("q+1=%p\n",q+1);
return 0;
}
运行结果:
从上面可以看出,对char类型指针进行加一,地址加1;对int类型指针加一,地址加4。实际上,对指针进行加一,是对地址加了一个sizeof的大小。
② *p++
取出所指的那个数据,并把p移到下一个位置,*的优先级虽然高,但是没有++的高。
这一语句常用于数组这一类的连续空间的操作,比如遍历。
例2:数组遍历
int main(void)
{
char ac[]={0,1,2,3,4,5,6,7,8,9,-1};
char *p=ac;
int i;
//法一
for(i=0;i<sizeof(ac)/sizeof(ac[0]);i++) //
{
printf("%d ",ac[i]);
}
printf("\n");
//法二:使用指针与*p++
for(p=ac;*p!=-1;)
{
while(*p!=-1)
printf("%d ",*p++);
}
printf("\n");
return 0;
}
运行结果:
③ 指针比较
<, <=, ==, >, >=, !=都可以对指针做,表示比较指针中存放地址的大小。
数组中的单元的地址线性递增,比如在一个数组中,指向a[0]的指针比指向a[5]的小。
2. 0地址
内存中会有0地址,但是0地址通常不能随便碰,所以指针不应该具有0值。
0地址可以用于表示特殊的事情,比如:返回的指针无效;指针没有真正的初始化。
NULL是一个预定定义的符号,表示0地址,如果你要用0地址,最好就使用NULL。
3. 指针类型
无论指针指向什么类型,所有的指针大小都是一样的,因为都表示地址;但是指向不同类型的指针不能互相赋值。
指针类型转换:
void* 表示不知道指向什么东西的指针,计算时与char相同,指针也可以转换类型:
int p=&I;
voidq=(void)p;
这并没有改变p所指变量的类型,而是让后人用不同的眼光通过p看它所指的变量。
4. 动态内存分配
① 输入数据
如果输入数据时,先告诉你个数,然后再输入,要记录每个数据。如果事先不知道数据个数,在程序运行中才输出数据个数,要使用动态内存分配使用:
int *a=(int*)malloc(n*sizeof(int));
需要使用头文件 #include<stdlib.h>;
向malloc申请的空间的大小以字节为单位;
返回的结果是void*,需要类型转化为自己需要的类型;
例3:输入数据(动态内存分配)
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int number;
int *a;
int i;
printf("输入数量:");
scanf("%d",&number);
// int a[number];
a=(int*)malloc(number*sizeof(int)); //动态内存分配
for(i=0;i<number;i++) //顺序输入
scanf("%d",&a[i]);
for(i=number-1;i>=0;i--) //逆序输出
printf("%d ",a[i]);
printf("\n");
free(a); //将分配的空间还回去
return 0;
}
运行结果:
② 系统分配的空间大小
例4:分配空间大小
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
void *p;
int cnt=0;
while((p=malloc(100*1024*1024)))
{
cnt++;
}
printf("分配了%d00MB的空间\n",cnt);
return 0;
}
运行结果为:
代码分析:
while((p=malloc(100*1024*1024)))
100* 1024* 1024表示每次申请100MB的空间,这里将申请的空间赋值给p这个变量;这一句话表示得到的地址进行判断,如果分配空间不是0则运行循环体,如果是0则退出。
③ free()
把申请来的空间还给系统,只能还申请来的空间的首地址。
④ 常见问题
问题1:申请了没free
:长时间运行内存逐渐下降,如果是一个很大的程序,需要一直运行,就会出问题。
问题表现为:忘记free或者找不到合适的free的时机。
问题2:free过了再free
问题3:地址变过了,直接去free