C语言深度解剖 (四)

2016-12-07 10:16:41来源:作者:镜缘浮影人点击

前言

C语言的水深不见底,好在一些前辈们已经将很多雷区探了一遍

这里分享一下我在学习 《C语言深度解剖》过程中的一些笔记和心得

概要 指针与数组 #include <stdio.h> void main(){int i=10; //&i 为 0x0018ff44int *p=&i;p=(int *)0x0018ff44;*p=11; *(int *)0x0018ff44=12;printf ("%x/t%d/t%d/n",p,*p,*(int *)0x0018ff44); //18ff44 12 12}

在VC++6.0中,上面的例子,数值变化都如预期,但是下面的数值变化会让人迷惑不解,因为p指针的值会随内容而变化(这个是不应该发生的事情,这是VC++6.0的bug)

#include <stdio.h> void main(){int *p;p=(int *)0x0018ff44;*p=11; *(int *)0x0018ff44=12;printf ("%x/t%d/t%d/n",p,*p,*(int *)0x0018ff44); }

不过,像这样,未经申请而直接使用内存的行为是很危险的

数组大小 void main(){int a[5]={1,2,3,4,5};int i=sizeof(&a); //20 这是一个地址,但为什么是20个字节的长度呢int j=sizeof(a); //20 a作为一个首地址,为什么是20个字节的长度呢int k=sizeof(&a[0]); //4int l=sizeof(&a[5]); //4 及便这个元素不存在}

可以将它们的地址分别取出来看看

首地址 #include <stdio.h> void main(){int a[5]={1,2,3,4,5};int *ptr=(int *)(&a+1); // 一次性跳数组长度的字符个数printf("%d,%d/n",*(a+1),*(ptr-1)); // 2,5 printf("%x,%x,%x,%x,%x/n",a,&a,a+1,&a+1,ptr-1); //18ff34,18ff34,18ff38,18ff48,18ff44}

对指针进行加1操作,得到的是连续内存中下一个元素的地址

一个类型为T的指针的移动,是以sizeof(T)为移动单位的

&a 与 a 的值是一样的,但是意思不一样

&a 是数组(结构体/构造体)的首地址

a 是数组首元素的首地址

&a+1,取数组a的首地址,该地址的值加上sizeof(a)的值,即&a+5*sizeof(int)

可以将a理解为结构体名,同时其值为&a[0]

a+1,是数组下一元素的首地址,即 a[1]的首地址

#include <stdio.h> void main(){char a[5]={'a','b','c','d','e'};char (*p1)[3]=&a;char (*p2)[3]=a;char (*p3)[10]=&a;char (*p4)[10]=a;printf("%x,%x,%x,%x,%x/n",a,p1+1,p2+1,p3+1,p4+1); //18ff40,18ff43,18ff43,18ff4a,18ff4a}

数组指针,是一个指针 ,但是它每次加一后,跳过的内存字节数为 n*sizeof(type)

地址的强制转换 #include <stdio.h> void main(){int a[4]={1,2,3,4};int *ptr1 =(int *)(&a+1);int *ptr2=(int *)((int)a+1);printf("%x,%x/n",ptr1[-1],*ptr2); // 4,2000000} 二维数组 #include <stdio.h> void main(){int a[3][2]={(0,1),(2,3),(4,5)};int *p;p=a[0];printf("%d/n",p[0]); //1}

这里千万要看清楚小括号里逗号分隔的表达式

#include <stdio.h> void main(){int a[5][5];int (*p)[4];p=a;printf("a_ptr=%#p,p_ptr=%#p/n",&a[4][2],&p[4][2]); // a_ptr=0X0018FF3C,p_ptr=0X0018FF2Cprintf("%p,%d/n",&p[4][2]-&a[4][2],&p[4][2]-&a[4][2]); //FFFFFFFC,-4}

&a[4][2]表示 &a[0][0]+4*5*sizeof(int)+2*sizeof(int)

&p[4][2]表示 &a[0][0]+4*4*sizeof(int)+2*sizeof(int)

所以差 4*sizeof(int),而地址相减获得的是此类型数据占用内存的单位数,所以,虽然相差16个字节,但是相差4个单位,一个int占4字节

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台