基本概念
1、 & 不能对没有地址的东西取址。
2、指针是能够保存地址的变量。
1 | int i; |
这说明指针也有内存地址,而且指针变量的值就是其他变量的内存地址。
3、* 是一个单目运算符, 用来访问指针的值所表示的地址上的变量。
可以做右值也可以做左值
• int k = *p;
• *p = k+1;
互相反作⽤:
- *&yptr -> * (&yptr) -> * (yptr的地址)-> 得到那个地址上的变量 -> yptr
- &*yptr -> &(*yptr) -> &(y) -> 得到y的地址,也就是yptr -> yptr
4、应用场景一:
交换两个变量的值:
1 | void swap(int *pa, int *pb) |
使用指针之前要初始化。
5、 以下四种函数原型是等价的:
1 | • int sum(int *ar, int n); |
6、指针与const
(1)指针是const:
一旦得到某个变量的地址,不能再指向其他变量。
(2)所指内容是const
表⽰示不能通过这个指针去修改那个变量(并不能使得那个变量成为const)
1 | int i; |
7、 const数组
- const int a[] = {1,2,3,4,5,6,};
- 数组变量已经是const的指针了,这⾥里的 const 表明数组的每个单元都是 const int
- 所以必须通过初始化进⾏行赋值
8、保护数组
- 把数组传⼊入函数时传递的是地址,则那个函数内部可以修改数组的值
- 为了保护数组不被函数破坏,可以设置参数为const
- int sum(const int a[], int length);
9、指针运算
(1) *p++
- 取出p所指的那个数据来,完事之后顺便把 p 移到下⼀一个位置去
- *的优先级虽然⾼高,但是没有 ++ ⾼高
(2) 两个同类型的指针变量可以相加减:
- 两个 T* 类型的指针 p1,p2
- p1 - p2 = (地址 p1 - 地址 p2)/sizeof(T)
(3) 指针变量加减一个整数的结果是指针:
p : T* 类型的指针
n :整数
p + n : 指向地址 :地址 p + sizeof(T)
(4)可以用“ NULL”关键字对任何类型的指针进行赋值。NULL实际上就是整数 0, 值为 NULL的指针 就是空指针。
(5) 指针的用处
需要传⼊入较⼤大的数据时⽤用作参数
传⼊入数组后对数组做操作
函数返回不⽌止⼀一个结果
• 需要⽤用函数来修改不⽌止⼀一个变量
(6)动态内存分配
C99可以⽤用变量做数组定义的⼤大⼩小,C99之前呢?
- int a = (int)malloc(n*sizeof(int));
如果申请失败则返回0,或者叫做NUL
1 | free() |
- 把申请得来的空间还给“系统”。
- 只能还申请来的空间的⾸首地址。
memset()函数:将内存的前n个字节设置为特定的值:
1 | //将数组 a 置 0。 |
10、指针与数组
数组的名字是一个指针常量,指向数字的起始地址。
指针和二维数组
1、二维数组
T a[M][N];
- a[i] 是一个一维数组。
- 列数 N必须给出,行数 M可以不给,由编译器给出。
- a[i] 的类型是 T*
- a[i] 指向的地址:数组 a 的起始地址 + i × N × sizeof(T)
2、指向指针的指针
- T **p;
p是指向指针的指针, p指向的地方应该存放着一个类型为 T * 的指针。
*p 的类型是 T *1
2
3
4
5
6
7int **pp;
int *p;
int n=1234;
p=&n;
pp=&p;
printf("%d",*(*pp));
3、指针和字符串
字符串常量的类型就是 char *
字符数组名的类型也是 char *
函数指针
将函数的入口地址赋给一个指针变量,使该指针变量向函数。然后通过变量就可以调用这个函数。种指向的指针变量称为“ 函数指针 ”。
类型名 (* 指针变量名 )( 参数类型 1, 参数类型 2,…);
例如:
1 | int (* pf )(int ,char); |
表示 pf 是一个函数指针,它所向的返回值类型应是int,该函数应有两个参数,第一是 int 类型,第二个是 char 类型。
函数指针和 qsort 函数
c 语言快速排序库函数:
1 | void qsort ( void *base, int nelem, unsigned int width, |
可以对任意类型的数组进行排序。

pfCompare: 函数指针,它指向一个“比较函数”。该比较函数应为以下形式:
1 | int 函数名 (const void *elem1, const void *elem2); |
比较函数是由我们自定义的。
比较函数编写规则:
- 如果 * elem1 应该排在 * elem2 前面 ,则函数返回值是负整数。
- 如果 * elem1和* elem2 哪个排在前面都行,那么函数返回0
- 如果 * elem1 应该排在 * elem2 后面 ,则函数返回值是正整数。
下面的程序,功能是调用 qsort qsortqsort库函数,将一个 库函数,将一个 unsigned int unsigned int unsigned int 数组按 照个位数从小到大进行排序。比如 8,23 ,15 三个数,按位从小到 三个数,按位从小到 大排序,就应该是 23 ,15 ,8
1 |
|