基本概念
1、 & 不能对没有地址的东西取址。
2、指针是能够保存地址的变量。1
2
3
4
5
6int i;
int* p = &i;
int* p,q; // p 是 int* 类型的指针,大小为8;q 是 int 整数,大小为4。
int *p,q; // p 是 int* 类型的指针,q 是 int 整数。
int *p,*q; // p 和 q 都是 int* 类型的指针。
这说明指针也有内存地址,而且指针变量的值就是其他变量的内存地址。
3、* 是一个单目运算符, 用来访问指针的值所表示的地址上的变量。
可以做右值也可以做左值
• int k = *p;
• *p = k+1;
互相反作⽤:
- &yptr -> (&yptr) -> * (yptr的地址)-> 得到那个地址上的变量 -> yptr
- &yptr -> &(yptr) -> &(y) -> 得到y的地址,也就是yptr -> yptr
4、应用场景一:
交换两个变量的值:1
2
3
4
5
6void swap(int *pa, int *pb)
{
int t = *pa;
*pa = *pb;
*pb = t;
}
使用指针之前要初始化。
5、 以下四种函数原型是等价的:1
2
3
4• int sum(int *ar, int n);
• int sum(int *, int);
• int sum(int ar[], int n);
• int sum(int [], int);
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,或者叫做NUL1
free()
- 把申请得来的空间还给“系统”。
- 只能还申请来的空间的⾸首地址。
memset()函数:将内存的前n个字节设置为特定的值:1
2//将数组 a 置 0。
memset(a,0,sizeof(a))
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 的类型是 T1
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
2void qsort ( void *base, int nelem, unsigned int width,
int (*pfCompare)(const void *, const void *));
可以对任意类型的数组进行排序。
pfCompare: 函数指针,它指向一个“比较函数”。该比较函数应为以下形式:1
int 函数名 (const void *elem1, const void *elem2);
比较函数是由我们自定义的。
比较函数编写规则:
1) 如果 elem1 应该排在 elem2 前面 ,则函数返回值是负整数。
2) 如果 elem1和 elem2 哪个排在前面都行,那么函数返回0
3) 如果 elem1 应该排在 elem2 后面 ,则函数返回值是正整数。
下面的程序,功能是调用 qsort qsortqsort库函数,将一个 库函数,将一个 unsigned int unsigned int unsigned int 数组按 照个位数从小到大进行排序。比如 8,23 ,15 三个数,按位从小到 三个数,按位从小到 大排序,就应该是 23 ,15 ,81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using namespace std;
int myCompare(const void* elem1, const void* elem2){
unsigned int *p1,*p2;
p1 = (unsigned int*) elem1;
p2 = (unsigned int*) elem2;
return (*p1%10)-(*p2%10);
}
int main(int argc, char** argv) {
unsigned int a[num]={8,123,11,10,4};
qsort(a,num,sizeof(unsigned int),myCompare);
for(int i=0;i<num;i++)
printf("%d ",a[i]);
return 0;
}