数组名、指针和地址
来源:互联网 发布:淘宝装修导航颜色代码 编辑:程序博客网 时间:2024/05/18 02:21
首先看这个:
#include <stdio.h>#include <iostream>using namespace std;int main() { int a[2] = {1, 2}; cout << "The address of int_array: " << endl; cout << a << " " << &a << endl << endl; double b[2] = {1.2, 1.3}; cout << "The address of double_array: " << endl; cout << b << " " << &b << endl << endl; char c[2] = {'a', 'b'}; cout << "The address of char_array: " << endl; cout << c << " " << &c << endl << endl; int d[5] = {1, 2, 3, 4, 5}; int dd[5] = {6, 7, 8, 9, 0}; int j = 2, k = 1, i = 3; cout << d[i] << " " << i[d] << endl << endl; //this code is so strange, but in fact, d[i] = *(d + i) = *(i + d) = i[d]. return 0;}
这里发现,a和&a好像是一样的,还有char类型的怎么就不一样?
首先是关于a和&a:
#include <stdio.h>int main() { int a[5] = {1, 2, 3, 4, 5}; printf("a = %p\n", a); printf("&a = %p\n", &a); printf("a + 1 = %p\n", a + 1); printf("&a + 1 = %p\n", &a + 1); return 0;}
显然,a是数组第一个元素的地址,而&a指的是整个数组(两者长度根本不同)
后来自己写了些东西:
#include <iostream>using namespace std;int main() { int a[5] = {305210130, 1164203589, 2023197048, 4, 5};//前三个数字在十六进制中表示分别是12312312、45645645、78978978,这样写主要为了测试方便 int *ptr1 = (int *)(&a + 1); int *ptr2 = (int *)((int)a + 1); for (int i = 0; i < 20; i++) {//01 cout << hex << *(int *)((int)a + i) << dec << ' '; } cout << endl << endl; cout << "&a + 1 : " << &a + 1 << endl;//02 cout << "*(&a + 1) : " << *(&a + 1) << endl;//03 cout << "**(&a + 1) : " << **(&a + 1) << endl;//04 cout << "*(a + 5) : " << *(a + 5) << endl;//05 cout << "(int *)(&a + 1) : " << (int *)(&a + 1) << endl;//06 cout << "*((int *)(&a + 1)) : " << *((int *)(&a + 1))<< endl;//07 cout << "*ptr1 : " << *ptr1 << endl;//08 cout << "ptr1 : " << ptr1 << endl;//09 cout << "ptr1[-1] : " << ptr1[-1] << endl;//10 cout << "ptr1[-5] : " << ptr1[-5] << endl;//11 cout << "(int)a : " << (int)a << endl;//12 cout << "(int)a + 1 : " << (int)a + 1 << endl;//13 cout << "(int *)((int)a + 1) : " << (int *)((int)a + 1) << endl;//14 cout << "the address of a's first element : " << a << endl;//15 cout << "*ptr2 : " << *ptr2 << endl;//16 cout << "ptr2 : " << ptr2 << endl;//17 cout << "the hex of *ptr2(*ptr2 = (int *)((int)a + 1)) : " << hex << *ptr2 << dec << endl;//18 ptr2 = (int *)((int)a + 3);//19 cout << "the hex of *ptr2(*ptr2 = (int *)((int)a + 3)) : " << hex << *ptr2 << dec << endl;//20 return 0;}
现在来试着解释一下,解释点对应代码中的注释序号:
01、
http://www.cnblogs.com/y041039/archive/2012/04/11/2442345.html
这篇博客里对数据的储存做了很好地说明,可以解释这一点
我的电脑用的显然是Little Endian,这么一来,
实际数据为:(十六进制下)
12 31 23 12 45 64 56 45 78 97 89 78 00 00 00 04 00 00 00 05
内存中的数据应为:(第一行是标号,第二行是数据,同样在16进制下)
0x22ff————2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44
12 23 31 12 45 56 64 45 78 89 97 78 04 00 00 00 05 00 00 00 ?? ?? ?? ??
另外一点要了解的是,*(int *)((int)a + i)的意思,(int)a将a的地址转化成int类型(注释12), 然后(int)a + 1是地址加一,这个一是真正的一,不按照int的大小加四(注释13),(int *)((int)a + i)再将int类型的地址转化为指向int的地址(也就是16进制),也就是0x22ff31(注释14),最后取内容。
那么输出结果也就明白了:
0x22ff30: 12312312
0x22ff31: 45123123
0x22ff31: 56451231
.
.
.
注意高位的零被省略了:
0x22ff3a: 00047897——>47897
02、
这里指出了&a的含义:依然是数组的地址(特殊的地址),但是表示了长度,所以后面的加一直接加上了一个数组的长度(也就是20, 转化为十六进制就是14),输出就是0x22ff30 + 14;
03、这里就说明了02中&a的特殊性,相当于自己指向自己?所以取内容仍然是自己;
04、取两次,取第一次是地址,再来一次是地址上的内容;
05、这里是为了验证04的正确性;
06到11都是对上述的实验,注意ptr1的类型决定了地址偏移的大小(-1就是-1个int长度);
12到15还行吧,不太难;
16、这个时候ptr2的地址是0x22ff31那么由01中的解释,*ptr2就是45123123,转化为十进制就是1158820131;
17、16中已讲到;
剩下的几个就是对01的验证了。
注意到这么一道题:
这么一来就没什么问题了,&a + 1指的是数组最后一位的下一个地址,而ptr1[-1] = *(ptr1 + (-1)),也就是数组最后一位,内容是5;
而这个时候的数组值为:(注意进制)
00 00 00 01 00 00 00 02 00 00 。。。
在内存中:(注意进制)
01 00 00 00 02 00 00 00 03 00 。。。
这样一来a的地址对应的是上面的第三个00,转化为int,加一(真正的一),也就是第三个00的下一个——02,再将它转化为指向int的,也就是00 00 00 02,真实值(16进制)02000000,也就是2000000。
0 0
- 数组名、指针和地址
- 有关指针,地址和数组名等等。。
- 数组名和数组名取地址、指针数组和数组指针的区别
- 指针 数组 数组名和数组名取地址的区别
- 数组名 和 指针
- 数组名和指针
- 数组名和指针
- 数组名和指针
- 数组名 和 指针
- 数组名和指针
- 数组名和指针
- 数组名和指针
- 指针和数组名
- 指针和数组名
- 数组名和指针
- 数值名,数组首地址,数组指针
- 数组名和数组名加地址符的区别(了解指针)
- 数组名和数组地址
- Android Studio导入项目的几种方法
- HTML5结构标签、border-radius、box-shadow与text-shadow
- Github教程
- 【猫猫的Unity Shader之旅】之简述3D图形学
- 简便使用jQuery(下)-jQuery自定义插件的编写
- 数组名、指针和地址
- Zobrist哈希,研究棋类博弈必须了解的一个小工具
- 简单的java缓存实现
- POJ 1742 解题报告
- javascripts深入了解(三)
- SQLServer 集合函数 COUNT 优化分析
- Combine Two Tables
- 代码控制按钮点击事件的触发
- LeetCode - Median of Two Sorted Arrays