指针 数组
来源:互联网 发布:四川广电电视网络套餐 编辑:程序博客网 时间:2024/04/30 09:09
指针规律:
1.int *p其实应该写成int* p更合适,int*是一个模子,一个整体,一个类型。
2.指针的加减是对单元数量(比如int*,则加1表示增加4个字节)的加减,不是单纯的数学实数加减。
3.强制转换:
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
假设p的值为0x100000。 如下表表达式的值分别为多少?
p + 0x1 = 0x100014 ?
(unsigned long)p + 0x1 = 0x100001?
(unsigned int*)p + 0x1 = 0x100004?
4.凡是在指针定义处赋值的操作,都是针对指针变量本身的,而不是针对指针所指向的地址的内容的,
比如:int *p = NULL 和*p = NULL 有什么区别?
很多初学者都无法分清这两者之间的区别。我们先看下面的代码:int *p = NULL;
这时候我们可以通过编译器查看p的值为0x00000000。这句代码的意思是:定义一个指针变量p,其指向的内存里面保存的是int类型的数据;在定义变量p的同时把p的值设置为0x00000000,而不是把*p的值设置为0x00000000。这个过程叫做初始化,是在编译的时候进行的。
明白了什么是初始化之后,再看下面的代码:
int *p;
*p = NULL;
同样,我们可以在编译器上调试这两行代码。第一行代码,定义了一个指针变量p,其指向的内存里面保存的是int类型的数据;但是这时候变量p本身的值是多少不得而知,也就是说现在变量p保存的有可能是一个非法的地址。第二行代码,给*p赋值为NULL,即给p指向的内存赋值为NULL;但是由于p指向的内存可能是非法的,所以调试的时候编译器可
能会报告一个内存访问错误。这样的话,我们可以把上面的代码改写改写,使p指向一块合法的内存:
int i = 10;
int *p = &i;
*p = NULL;
在编译器上调试一下,我们发现p指向的内存由原来的10变为0了;而p本身的值, 即内存地址并没有改变。
再比如:需要往内存0x12ff7c地址上存入一个整型数0x100。
int *p = (int *)0x12ff7c; // P是指针变量,存储的内容为内存地址0x12ff7c
*p = 0x100; // 向内存地址0x12ff7c处写入0x100
上述代码等同如下:*(int *)0x12ff7c = 0x100;
数组
a[0],a[1]等为a的元素,但并非元素的名字。数组的每一个元素都是没有名字的。
sizeof(a)的值为sizeof(int)*5,32位系统下为20。
sizeof(a[0])的值为sizeof(int),32位系统下为4。
sizeof(a[5])的值在32位系统下为4。并没有出错,为什么呢?我们讲过sizeof是关键字不是函数。函数求值是在运行的时候,而关键字sizeof求值是在编译的时候。虽然并不存在a[5]这个元素,但是这里也并没有去真正访问a[5],而是仅仅根据数组元素的类型来确定其值。所以这里使用a[5]并不会出错。
sizeof(&a[0])的值在32位系下为4,这很好理解。取元素a[0]的首地址。
sizeof(&a)的值在32位系统下也为4,这也很好理解。取数组a的首地址。
a有两个含义:数组名、数组a[0]的地址(等于&a[0])。
&a则表示数组的地址,值与a相等。
这里&a[0]和&a到底有什么区别呢?a[0]是一个元素,a是整个数组,虽然&a[0]和&a的值一样,但其意义不一样。前者是数组首元素的首地址,而后者是数组的地址。举个
例子:湖南的省政府在长沙,而长沙的市政府也在长沙。两个政府都在长沙,但其代表的意义完全不同。这里也是同一个意思。
a作为左值与作为右值
x=y。
左值:在这个上下文环境中,编译器认为x的含义是x所代表的地址。这个地址只有编译器知道,在编译的时候确定,编译器在一个特定的区域保存这个地址,我们完全不必考虑这个地址保存在哪里。
右值:在这个上下文环境中,编译器认为y的含义是y所代表的地址里面的内容。这个内容是什么,只有到运行时才知道。
a作为右值时其意义与&a[0]是一样,代表的是数组首元素的首地址,而不是数组的地址。
a不能作为左值。
编译器会认为数组名作为左值代表的意思是数组a的地址,但是这个地址开始的一块内存是一个总体,我们只能访问数组的某个元素而无法把数组当一个总体进行访问。所以我们可以把a[i]当左值,而无法把a当左值。其实我们完全可以把a当一个普通的变量来看,只不过这个变量内部分为很多小块,我们只能通过分别访问这些小块来达到访问整个变量a的目的。
指针和数组关系
数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型和个数。数组可以存任何类型的数据,但不能存函数。
相似点
例子B)
定义了一个数组a,a拥有7个char类型的元素,其空间大小为7。数组a本身在栈上面。对a的元素的访问必须先根据数组的名字a找到数组首元素的首地址,然后根据偏移量找到相应的值。这是一种典型的“具名+匿名”访问。比如现在需要读取字符‘5’,
我们有两种方式:1),以指针的形式:*(a+4)。a这时候代表的是数组首元素的首地址,假设为0x0000FF00,然后加上4个字符的偏移量,得到新的地址0x0000FF04。然后取出0x0000FF04地址上的值。2),以下标的形式:a[4]。编译器总是把以下标的形式的操作解析为以指针的形式的操作。a[4]这个操作会被解析成:a作为数组首元素的首地址,然后加上中括号中4个元素的偏移量,计算出新的地址,然后从新的地址中取出值。
由上面的分析,我们可以看到,指针和数组根本就是两个完全不一样的东西。只是它们都可以“以指针形式”或“以下标形式”进行访问。一个是完全的匿名访问,一个是典型的具名+匿名访问。一定要注意的是这个“以XXX的形式的访问”这种表达方式。
注:偏移量的单位是元素的个数而不是byte数。
a 和&a
理解
char a[100];
char *p = “abcdefg”;
文件2
extern char p[];
指针数组与数组指针
参考文献
- 指针数组、数组指针
- 指针数组/数组指针
- 指针数组/数组指针
- 数组指针 指针数组
- 指针数组,数组指针
- 数组,指针,数组指针
- 数组,指针,数组指针
- 指针数组&数组指针
- 指针数组&数组指针
- 数组指针 指针数组
- 指针数组/数组指针
- 数组指针&指针数组
- 数组指针 指针数组
- 数组指针 指针数组
- 指针数组 数组指针
- 指针数组,数组指针
- 指针数组 数组指针
- 指针数组&数组指针
- 关注时间维度
- JFreeChart用法
- flex 组件显示手型 光标
- svn回滚操作(撤销修改)
- ios 绘图
- 指针 数组
- Differences between Datasource and XADatasource
- solr data-config.xml配置文件的见解mysql数据源
- qt5 deploy 部署 双击 myProgram.exe时 提示找不着 ...windows 不能运行
- 让我们摸清楚多表连接的原理
- Spring 3 Ioc 容器装在bean
- 谈学习和比较
- android view或button的setVisibility方法值的意思
- VC++中List Control控件的使用方法介绍