1、指针
● 我们将内存中字节的编号称为 地址 或 指针;
● 地址从 0 开始依次增加,32 位环境下,程序能够使用的内存为 4 GB,最大地址为:FFFFFFFF;
#include <stdio.h>
using namespace std;
//如何输出地址
int main() {
int a = 20;
char arr[] = "www.csdn.net";
printf("%#x,%#x", &a, arr);
return 0;
}
● 如果一个变量存储了一份数据的指针,我们就称它为指针变量;
2、定义指针变量
● 指针变量也可以改变值;指针变量格式为:
//a,b的数据类型是 int*,而不是int
int a = 100;
int b = 200;
//指针变量前有*号
int *p_a = &a;
//定义指针变量是必须带 *,给指针变量赋值另一个指针时不能带 *
p_a = &b;
● 指针变量也可以连续定义
int *a,*b,*c;
3、通过指针变量取得数据
● 使用指针是间接获取数据;
先取得该指针变量存储的另一个变量的地址,然后再用该地址取得那个变量的值,是两步运算;
而使用变量的话是通过该变量的地址直接取得该变量的值,只有一步运算;
也就是说,使用指针获取数据比使用变量获取数据的代价要高;
#include <stdio.h>
using namespace std;
//都可以取得值
int main() {
int a = 100;
int *p = &a;
printf("%d, %d\n", a, *p);
return 0;
}
4、用指针修改内存上的值
● 直接用变量来修改指针变量存储的地址对应的变量的值的时候,指针变量必须带 *;
如果是将一个新的指针赋值给指针变量,指针变量可以不带 *;
#include <stdio.h>
using namespace std;
int main() {
int a = 100, b = 200, c = 300;
int *p = &a;
*p = b;
c = *p;
printf("%d,%d,%d", a, b, c);
return 0;
}
5、定义和使用的不同意义
● 以下两个语句的 * 的意义是不同的:
定义指针变量的 * ,意思是:声明 a 是一个指针变量,以和普通变量区分开;
使用的时候的 * ,意思是:取得该指针指向的值;
第三个没有 * ,意思:将另一个指针赋值给 a,只有指针变量才能存储指针,所以此处不需要带 * 来说明 a 是指针变量;
int *a = &b;
*a = 100;
a = &c;
6、指针变量的运算
● 指针变量的运算并不是数值的 +1 和 -1,而是地址的增加;
int 类型指针 +1,则地址 +4;
double 类型指针 +1,则地址 +8;
……
数据在内存中的存储是连续的,所以 +1 就表示指向下一个元素,-1 就表示指向上一个元素;
C 语言并没有规定变量的存储方式,如果连续定义多个变量,它们有可能挨着,也有可能分散,所以不要尝试通过指针加减来读取数据,因为这样没意义,谁都不知道读取到的是不是我们希望读取到的数据;
● 两个指针变量进行比较的时候,比较的是它们本身的值,也就是数据的地址;
如果地址相等,说明两个指针指向同一份数据,否则就指向不同的数据;
#include <stdio.h>
using namespace std;
int main() {
int a = 10, *p_a1 = &a, *p_a2 = &a;
printf("%d\n%d\n%d\n", a, *p_a1, *p_a2);
printf("%#x\n%#x\n", *p_a1, *p_a2);
if (p_a1 == p_a2) {
printf("Yes!");
}
else {
printf("No!");
}
return 0;
}