- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
深入解析CC
C语言
关键字
符号
预处理
指针和数组
指针
指针的内存布局
“*”与防盗门的钥匙
Int * p=NULL 和 *p=NULL有什么区别
第一行代码,定义了一个指针变量p,其指向的内存里面保存的是int 类型的数据;但是这时候变量p 本身的值是多少不得而知,也就是说现在变量p 保存的有可能是一个非法的地址。
第二行代码,给*p 赋值为NULL,即给p指向的内存赋值为NULL;但是由于p 指向的内存可能是非法的,所以调试的时候编译器可能会报告一个内存访问错误。
这样的话,我们可以把上面的代码改写改写,使p 指向一块合法的内存:
int i = 10;
int *p = i;
*p = NULL;
如何将数组存储到指定的内存地址
*(int *)0x12ff7c = 0x100;
编译器的bug
数组
数组的内存布局
Int a[5];
sizeof(a)的值为sizeof(int)*5,32 位系统下为20。
sizeof(a[0])的值为sizeof(int),32 位系统下为4。
sizeof(a[5])的值在32 位系统下为4。
sizeof(a[0])的值在32 位系下为4,这很好理解。取元素a[0]的首地址。
sizeof(a)的值在32 位系统下也为4,这也很好理解。取数组a的首地址。
省政府和市政府的区别----a[0]和a的区别
a[0]是一个元素,a 是整个数组,虽然a[0]和a的值一样,但其意义不一样。前者是数组首元素的首地址,而后者是数组的首地址。
数组名a作为左值和右值的区别
比如,x=y;
左值:在这个上下文环境中,编译器认为x 的含义是x 所代表的地址。
右值:在这个上下文环境中,编译器认为y 的含义是y 所代表的地址里面的内容。
a 作为右值时其意义与a[0]是一样,代表的是数组首元素的首地址,而不是数组的首地址。
a 不能作为左值!
指针与数组的关系
以指针的形式访问和以下标的形式访问指针
指针与数组
指针就是指针,指针变量在32 位系统下,永远占4 个byte,其值为某一个内存的地址。
指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到。
例子
char *p = “abcdef”;
char a[] = “123456”;
1),以指针的形式:*(p+4)。先取出p 里存储的地址值,假设为0x0000FF00,然后加上4 个字符的偏移量,得到新的地址0x0000FF04。然后取出0x0000FF04 地址上的值。
2),以下标的形式:p[4]。编译器总是把以下标的形式的操作???析为以指针的形式的操作。p[4]这个操作会被解析成:先取出p 里存储的地址值,然后加上中括号中4 个元素的偏移量,计算出新的地址,然后从新的地址中取出值。也就是说以下标的形式访问在本质上与以指针的形式访问没有区别,只是写法上不同罢了。
以指针的形式访问和以下标的形式访问数组
A和a的区别
例子
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(a+1);
printf(%d,%d,*(a+1),*(ptr-1));
}
对指针进行加1 操作,得到的是下一个元素的地址,而不是原有地址值直接加1。所以,一个类型为T 的指针的移动,以sizeof(T) 为移动单位。因此,对上题来说,a 是一个一维数组,数组中有5 个元素; ptr 是一个int 型的指针。
a + 1: 取数组a 的首地址,该地址的值加上sizeof(a) 的值,即a + 5*sizeof(int),也就是下一个数组的首地址,显然当前指针已经越过了数组的界限。
(int *)(a+1): 则是把上一步计算出来的地址,强制转换为int * 类型,赋值给ptr。
*(a+1): a,a 的值是一样的,但意思不一样,a 是数组首元素的首地址,也就是a[0]的首地址,a 是数组的首地址,a+1 是数组下一元素的首地址,即a[1]的首地址,a+1 是下一个数组的首地址。所以输出2。
*(ptr-1): 因为ptr 是指向a[5],并且ptr 是int * 类型,所以*(ptr-1) 是指向a[4] ,输出5。
a 在这里代表是的数组首元素的地址即a[0]的首地址,其值为0x0012ff6c。
a 代表的是数组的首地址,其值为0x0012ff6c。
a+1 的值是0x0012ff6c+1*sizeof(int),等于0x0012ff70。
指针和数组的定义域声明
定义为数组,声明为指针
char a[100];
extern char *a;
数组就是数组,指针就是指针,它们是完全不同的两码事!他们之间没有任何关系,只是经常穿着相似的衣服来迷惑你罢了。
指针和数组的对比
指针数组和数组指针
指针
文档评论(0)