指针
定义
通常在程序中:
1
2
3
|
int x; // in system 为该变量分配一个存储空间
x = 10; // 将 10 存入该存储空间,与变量息息相关的存储空间
x = x+1;
|
通过变量能够找到存储在对应空间中数据,既然如此,那么可以直接去引用这个空间地址( address 编号);
问:如何获取变量地址呢?获取的地址又如何存放?(指针)
利用一个取地址运算符:& 读作 and
格式:
1
2
3
4
|
// 类型 *指针名 = &x; 获取地址编号,数;利用指针来存储变量的地址
int x;
int *px; // 指针定义
px = &x; // px 指针保存 x 变量的地址;
|
指针:用于存储地址(指针指向变量);
⚠️ 指针类型必须和被指向的变量类型一致;
星号,取指针所指向存储空间中的数据;
指针本身可以运算
1
2
3
|
int p[10];
int *q = p;
q++
|
操作系统如何管理内存
栈空间: 4~8M 大小,每进入一个函数时,会分配空间,离开时,系统自动回收。
堆空间: 内存较大,需要手动分配回收,一旦分配,在所有函数中只要知道地址就可以访问
内存映射: 磁盘的文件映射到内存,对内存修改,磁盘的文件同时发生变化
1
2
|
void * mem = malloc(size); // size 需要字节对齐
free(mem);
|
不断的向系统申请内存,不释放会造成内存泄漏,使用已经释放内存的指针称为野指针。
函数指针
返回值类型 (*指针变量名) ([形参列表]);
1
2
3
|
int func(int x); // 声明函数
int (*f) (int x); // 声明函数指针
f = func;
|
例题
一 从键盘输入三个数求最小值,对变量数据引用,通过地址引用;
1
2
3
4
5
6
7
8
9
|
int x,y,z,min;
int *px=&x,*py=&y,*pc=&z;
printf("input x,y,z,空格隔开:")
scanf("%d %d %d",px,py,pc);
min = *px<*py?*px:*py;
min = min>*pz?*pz:min;
printf("%d\n",min);
|
二 利用指针引用数组元素的值
数组名就是数组元素的首地址;
1
2
3
4
5
|
&a[0] == a; // 两者等价,首地址
int *p = a; // 使 p 指针指向数组元素首地址
p++; // 指针移动到第二个元素
p+1; // 表示第二个元素,但是指针依然停留在首地址
|
数组中元素的地址是连续的;
数组名是首地址,这个地址是固定不变的,constant;因此不能有 a++;
当一个指针指向数组的首地址,此时指针和数组名具有完全的等价效果;(凡是数组名能做的事情,指针都可以做到)
1
2
3
4
5
6
7
|
// 数组名作为地址,可以加减;其余效果待验证;
int *p;
int a[10] = {1,2,3,4,5,6,7};
p = a+4; // p 指针指向下标为 4 的元素,等价 a[4];
a = a+4; // Error,常量不能赋值
printf("%d\n",*(a+3)); // a是地址,故此等价于 *(p+3)
// a[3] == *(a+3) == *(p+3) == p[3]
|
三 从键盘输入10个数,存入数组中,求10个数平均数,对数组元素的引用使用指针;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int a[10];
int *p = a;
int i,sum=0;
while(p <= a+9){ // 读入10个元素
scanf("%d",p);
p++;
}
p = a; // 将指针恢复到数组首地址
for(i=0; i<10; i++){
sum += *(p+i); // * 的运算符很高,先取地址需要加括号
}
printf("%f\n",sum/10.0); // 若是求平均数,一定要除以 浮点数
|
对指针来说,可以加一个数 or 减一个数,两个指针可以相减,两个指针可以比较大小;
三 利用指针来引用字符串
字符串有结束标志 :
从键盘输入一串字符,倒置字符串元素,例如 abced —> decba;
解题思路:在字符串的首位分别设置一个指针,交换以后i++,j–;直到两个指针相遇后停止;
1
2
3
4
5
6
7
8
9
10
11
12
|
char st[100];
char *i,*j,t;
gets(st);
i = st;
j = st+strlen(st)-1; // 总数-1 = 最后一个下标
while(i<=j){
t = *i;
*i = *j;
*j = t;
i++; j--;
}
printf("%s\n",st);
|