指针: 内存中最小存储单元叫做字节,为了方便操作内存中的数据,生产商对每一个内存中的存储单元进行编号,这个编号就叫做地址,地址其实就是指针,指针就是地址;
访问内存中的数据有两种方式: 直接访问和间接访问
& 叫做取地址符号
&a 就是取到a的地址,并且返回
%p 是地址的占位符,打印地址的时候使用;
什么是指针变量: 指针变量就是存放地址的变量
如何定义一个指针变量:
// 类型修饰符 *指针变量名 = 初始值;
// 在定义指针变量的时候,*就是一个指针的标示符,告诉编译器,这是个指针变量;
int *p = NULL;
printf ( “%p\n”,p ); // 取出变量b的地址,赋值给指针变量p;
p = &b;
printf ( “b地址 = %p , p地址 = %p \n”,&b,p ) // 直接访问
* * 取值运算符
* *p 取出p指向的那块内存中存储的数据
printf("%d\n",*p);
// 定义整型的指针变量
int *p2 = NULL;
int *p3 = NULL;
int c = 20,d = 30;
p2 = &c;
p3 = &d;
printf("%d,%d\n",*p2,*p3);
// printf("%p\n",&a);
// 指针变量的重新赋值,叫做指针的重指向;
p2 = p3;
printf("%d\n",*p2);
// 练习1:使用指针交换整型变量a,b的值
/*
int a = 10,b = 8;
int *p1 = NULL;
int *p2 = NULL;
p1 = &a;
p2 = &b;
int temp = *p1;
*p1 = *p2;
*p2 = temp;
printf(“a = %d,b = %d\n”,a,b);
*/
// 练习2: 赋值
/*
int a = 6,b = 8,c = 10;
int *p = &a;
p = &c;
int *p1 = &b;
int *p2 = &c;
*p2 = 5;
*p = 12;
p = p1;
*p1 = *p + *p2;
printf(“%d %d %d\n”,a,b,c);
*/
指针常见的问题:
内存编号比较小的内存单元,是由系统控制的,不允许访问
/ / int *p = NULL; NULL是最小的地址 0X0000000
指针变量在内存中所占空间的大小与变量类型并没有关系,只与操作系统位数有关,64位系统占8字节,32位系统占4字节。
定义指针变量时,指针类型修饰符一定要和它指向的那块空间变量的数据类型一眼个只有遮掩刚才能完整把那块空间里的数据取出来,总结一句话: 什么类型的指针指向什么类型的变量。
int a = 2;
char *p = &a ; 不合法!
指针的算术运算:
类型修饰符的种类决定指针变量做+1操作时跳转多少个字节
int+1跳转4个 float: 4个 char 1个 ·····
nt *p1 = NULL;
printf(“%p\n”,p1); // 0x0
printf(“%p\n”,++p1);
// 0x4 等同于 p1 = p1 +1; 已经重新进行赋值,指针的值已经改变了
printf(“%p\n”,p1++); // 0x4
printf(“%p\n”,p1); // 0x8
*/
// p+1 ++p p++ 的关系:
// 相同: 取到的都是下一个空间的首地址
// 不相同: p+1没有造成指针的重指向,而p++和++p都造成了指针的重指向;
// 通过指针变量p来访问数组中的元素:
printf("%d\n",*p);
printf("%d\n",*(p+1));
printf("%d\n",*(p+2));
printf("%d\n",*(p+3));
printf("%d\n",*(p+4));
printf("遍历:\n");
for (int i = 0; i < 5; i++) {
printf("%d\t",*(p+i));
}printf("\n");
数组名和指向数组首地址的指针变量的区别:
* 数组名是一个指针常量,不能修改
* 指向数组首地址的指针变量是可以重指向的,可改变;
int a[5] = {1,2,3,4,5};
int *p = NULL;
printf(“%lu\n”,sizeof(a) ); // 20
printf(“%lu\n”,sizeof( p) ); // 8
用指针冒泡排序:
// 有10个元素的整型数组,通过指针变量为数组随机赋值[20 40], 然后冒泡排序
int a[10] = {0};
int *p = a;
for (int i = 0; i < 10; i++) {
*(p+i) = arc4random_uniform(40-20+1)+20;
}
for (int i = 0; i<9; i++) {
for (int j = 0; j<9-i; j++) {
if (*(p+j)>*(p+j+1)) {
int temp = *(p+j);
*(p+j) = *(p+j+1);
*(p+j+1) = temp;
}
}
}for (int i = 0; i<10; i++) {
printf("%d\t",*(p+i));
}
printf("\n");
使用 %s 打印字符串,从指针指向的那个地址开始打印:
char string[] = “qingrenjiekuaile”;
printf(“%s\n”,string);
printf(“%s\n”,string + 1);
printf(“%c\n”,*(string + 1));
打印的结果分别是:
qingrenjiekuaile
ingrenjiekuaile
i