目录
数组内存地址
- 数组是内存中一块连续的空间
// 取一个变量的地址 &符号;
int a = 4; // &a取得变量A的内存地址;
// 数组是一块连续的内存,类型 名字[个数]
// sizeof(类型) * 个数,连续的内存;
// 局部变量的数组,所以这个数组的内存是分配在我们的栈上的
// 连续的内存,由低地址排到高地址;
- 操作数组地址的方法
- 名字为这块内存的首地址 ------> 名字 + offset,就可以确定元素的地址位置
- 数组元素取地址 ------> &名字[offset]
int b[3] = {1, 2, 3};
/* 数组的内存地址:
数组元素的内存地址,第2个元素的内存地址
(1)&(数组名字[索引]),数组的开始(首)地址,&数组名字[0];
(2)数组名字本身就是一个地址,它是这个数组的首地址;
int b[3]; b就是这个数组的内存起始地址,b == &b[0];
(3)使用数组名字+偏移offset,来获取从数组的首地址到offset这个元素的地址;
int b[3]; int offset = 2; b + offset 相当于 &b[offset], 数组内存的首地址;
*/
printf("0x%x, 0x%x\n", b, &b[0]);
int offset = 2;
printf("0x%x, 0x%x\n", b + offset, &b[offset]);
// 观察一下 b, b + 2 --> 8个字节 --> offset * sizeof(int);
// offset指的是数组元素的个数,
// b + offset的数值大小其实是: b + sizeof(数据类型) * offset;
// offset不是指的字节数,而是元素的个数;
// end
- 二维数组:(二维数组是按照每一行每一行的存储,内存里面就是连续的1维数组)
- 二维数组的名字为二维数组的首地址
- a[y] 表示是第y行的地址
- &a[i][j] ------> 元素(i,j )的地址
// 二维数组,
// 二维数组其实也是一维数组,它是数据元素一行一行的存到内存里面的;
int s_array[3][3] = {
{ 0, 1, 2, },
{ 10, 11, 12, },
{ 20, 21, 22, },
};
/*
二维度数组地址:
(0)二维数组每一个元素来取地址;
(1)二维数组的名字,就是二维数组的首地址--> &s_array[0][0]
(2)二维数组每行的地址: s_array[行数] --> &s_array[行数][0]
*/
printf("===============\n");
printf("0x%x, 0x%x, 0x%x\n", s_array, &s_array[0][0], s_array[0]);
printf("0x%x, 0x%x\n", s_array[1], &s_array[1][0]);
printf("===============\n");
// end
指针 + 偏移
- 指针变量指向数组中的内存地址
- 指针+偏移的方式访问内存
- *(p + offset)
- p[offset]
// *指针变量, 访问指针变量里面存放的内存地址的内存数据
// 存放地址的变量;
p = b; // *p --> p内存地址,内存数据,
printf("%d, %d\n", *p, b[0]);
p = b + 1; // p 存放的是数组第1个元素地址;
printf("%d, %d\n", *p, b[1]);
p = &b[2];
printf("%d, %d\n", *p, b[2]);
// end
// *指针变量, 指针变量[offset];
// 指针变量[offset]:访问的是从这个指针保存的地址开始,偏移offset个元素(sizeof(类型))的内存数据;
// 以指针变量为内存基地址(开始地址) 偏移offset个元素(不是字节);
// 为什么数组的索引是从0开始的,因为数组的名字表示的是首地址,而最开始的元素,就是从首地址开始存的,所以偏移是0;
p = b;
printf("%d, %d\n", p[0], b[0]);
指针加减法
- p = p + offset 指针加法是向后移动offset个元素的地址 ------> 注意不要越界,不要访问非法的内存区域
- p = p - offset 指针向前移动offset个元素
- p ++, p -- ------> 简洁
// 指针的加;
// p + offset, 是以p为首地址,然后正向偏移offset个元素(不是字节)的地址
// 数值上 p保存的内存地址 + offset * sizeof(数据类型);
p = b;
printf("b[1]的地址 0x%x, 0x%x, 0x%x\n", p + 1, &b[1], b + 1);
// *(指针变量 + offset) 来访问我们的内存数据;
printf("b[2]: %d, %d, %d\n", *(p + 2), p[2], b[2]);
// *(数组名字 + offset)来访问我们的内存数据;
printf("b[2]: %d, %d, %d\n", *(b + 2), p[2], b[2]);
// end
// 指针减: p - offset向前挪动offset个元素()
p = b + 1; // p指向了数组的第1个元素的地址;
printf("b[0]: %d, %d\n", b[0], *(p - 1));
// 指针和数组,不要越界,包保正使用指针访问的每一个内存是合法的;
// end
指针变量遍历数组
- 指针变量来遍历一维度数组
- 指针变量遍历二维数组
p = b;
for (int i = 0; i < 3; i++, p++) {
printf("%d, %d, %d\n", *p, p[0], *(p + 0));
}
p = s_array;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", *p);
p++;
}
printf("\n");
}
// 指针每次保存二维数组的每行的地址
p = s_array;
// 有多少行
for (int i = 0; i < 3; i++) {
// 每一行循环遍历
for (int j = 0; j < 3; j++) {
printf("%d ", p[j]);
}
p += 3; // 每行3个元素,所以跳到下一行;
printf("\n");
}