第十一课 指针

指针

定义

通常在程序中:

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 减一个数,两个指针可以相减,两个指针可以比较大小;

三 利用指针来引用字符串

字符串有结束标志 :

1
st[i] != '\0'

从键盘输入一串字符,倒置字符串元素,例如 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);
Licensed under CC BY-NC-SA 4.0
本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy