内存的访问形式:1、直接访问:通过变量名进行访问。2、间接访问:先找到变量存放的地址,然后根据地址去访问对应的内存空间。
指针---
// 定义一个整形指针变量,用来存储num1在内存中的地址
int *p = NULL; // 定义一个整形指针变量,指向0x0,NULL恒等于0
printf("%p
", p); // 输出指针变量的值,使用"%p"
printf("&num1 = %p
", &num1); // 取址运算符,取得变量所在的内存地址
p = &num1; // 给整形指针变量重新赋值
printf("p = %p
", p);
printf("*p = %d
", *p); // "*"取值运算符,取出地址里面存储的数据
// 当我们定义指针变量的时候,"*"只是起一个标识作用,告诉我们这个变量是一个指针变量。
// 当我们使用指针变量的时候,"*"表示的是从当前地址里面取出存储的数据。
// 指针的算术运算,只有加和减
int num1 = 100;
int num2 = 200;
int *p = &num2;
printf("*p = %d
", *p);
printf("*(p + 1) = %d
", *(p + 1)); // p + 1是指针向高位移动n个字节,n指的是指针指向的数据类型所占有的字节数(int *p移动4个字节, char *p1移动1个字节)
printf("&num1 = %p
", &num1);
printf("&num2 = %p
", &num2);
printf("p = %p
", p);
printf("p + 1 = %p
", p + 1);
printf("p - 1 = %p
", p - 1); // p - 1是指针向低位移动n个字节,n指的是指针指向的数据类型所占有的字节数(int *p移动4个字节, char *p1移动1个字节)
printf("++p = %p
", ++p);
// 指针和数组
int array[3] = {1, 3, 5};
printf("array = %p
", array); // 数组名就是数组元素的首地址
printf("&array[0] = %p
", &array[0]);
int *p = array;
printf("%d
", *p);
printf("%d
", *(p + 1));
printf("%d
", *p + 1);
*(p + 2) = 6;
p[1] = 10; // 指针可以当做数组名来使用
// 指针和数组的区别:所占空间不同:指针所占的空间只喝操作系统有关,数组占用的空间等于数组的元素个数*数组元素类型所占的字节数。
// 数组名是常量地址,不能重指向。指针可以进行重指向。
int *p1 = NULL;
// array = p1;
p = p1;
// 指针和字符串
char str[10] = "iPhone"; // 把常量区的字符串"iPhone"拷贝到了栈区,所以可以进行更改
char *p = str;
printf("%s
", str);
printf("%s
", p);
*(p + 1) = 'X'; // 使用字符指针操作单个字符
printf("%s
", p); // 使用字符指针操作字符串
printf("%c
", p[3]);
printf("%c
", *(p + 3));
printf("%s
", p + 2);
char *str1 = "iPhone"; // 栈区的指针str1指向常量区的某一块区域
printf("str1 = %s
", str1);
// *(str1 + 1) = 'X'; // 常量不能修改
printf("str = %p
", str);
printf("str1 = %p
", str1);
// 指针数组
char *strings[3] = {"iOS", "iMac", "iPad"};
printf("%s
", *strings); // 取出数组中的第一个元素(数组里面的元素是地址)
printf("%s
", *(strings + 1));
printf("%s
", *(strings + 2));
printf("%c
", *(*strings));
printf("%c
", *(*strings + 1));
printf("
");
printf("%p
", strings);
printf("%p
", strings + 1);
printf("%p
", strings + 2);