js数组删除元素首元素的首地址和js数组删除元素的首地址有什么区别

8346人阅读
C/C++(7)
C语言数组首地址和数组名取地址区别
申明:本文系原创,转载时请注明出处,本人保留追究责任的权利。
原文地址:/surfmygod/blog/item/53d44914cdb8a5d6a7ef3f13.html
本文适用于机器为32位,编译器为VC6.0。
先来看下面一个例子:
int a[5]={0xxxxx};
int *ptr1=(int *)(&a+1);
int *ptr2=(int *)(a+1);
printf(&%x,%x&,ptr1[-1],*ptr2);
打印输出的结果是多少?第4行&a是不是写错了?数组名怎么还取地址呢?
你可以试着在软件中编译运行一下,结果是222324,没错,就是它了。你可以试着写以下程序再在计算机中编译运行下:
int a[5]={0xxxxx};
printf(&%p\n%p\n&,a,&a);
printf(&%d\n%d\n&,sizeof(a),sizeof(&a));
printf(&%p\n%p&,&a+1,a+1);
你可以看到前两行a和&a打印的结果是一样的(比如0012FF6C),后两行的结果是都是20,而&a+1的结果是0012FF6C,即a的起始地址后移20字节。看到这里对于a和&a的区别是不是有些眉目了?不错,a和&a的值虽然一样,但是前者表示的是数组a的首地址,进阶为数组元素长度,而后者也是表示数组a的首地址(或许有些人不同意我这个观点,对地址取地址应该是指向指针的指针呀。不过你注意了没有,a和&a值是一样的,试想如果这里表示的是指向指针的指针,那么a的地址和指向a的指针的地址可能一样么?两个指针都指向数组首地址,怎么会是指向指针的指针?还有一点需要强调,对一个指针进行sizeof运算,32位系统下应该得到4,而对数组名进行sizeof运算得到的结果却是20,这说明了什么?很显然,数组名虽然能够拿出来代表一个地址,但是它和指针还是有区别的,对它进行sizeof运算也不会得到指针的大小。不信?你可以试试sizeof(&a[0])和sizeof(a),看看结果是不是相同),但是是将整个数组作为一个对象来看待的,进阶为整个数组长度。也就是说,a和&a虽然值相同,但是a是将所有数组元素看成一个个不同的个体来对待的,而&a是将整个数组作为一个整体来对待的。这里要强调的是,a+1和&a[1]其实是一样的,都是代表a数组向后偏移一个元素的地址,你可以再用sizeof关键字打印一下两个的值。但是a和&a[0]的意义相同么?若打印地址的话,两者确实是一样的,但是你也用sizeof打印下两者,一样么?再试试a+0呢?很显然,a和a+0是有区别的,但是a+0和&a[0]是含义相同的。所以,你可以说a+i和&a[i]含义相同,但是绝不能说a和&a[0]或a+0含义相同。所以&a+1后移20位为&a+sizeof(&a),而a+1却是a+sizeof(a[i])。(《C语言深度解剖》认为在32为系统下sizeof(&a)的值仍为4,我觉得是不对的。他觉得是VC6.0错了,其实不止VC,其他很多编译器得到的结果也不会是4,这说明a和&a在C中本来就不是作为指针来用的,只是具有指针的部分性质而已。)ptr1是将&a+1强转为int类型指针,此时打印ptr1[-1]即将ptr指针前移sizeof(int)个字节,故打印结果是5。这样一来后面的也明了了,a+1的值为在数组a的首地址上后移sizeof(int)个字节,然后强转为int类型指针(其实强转并没有改变什么,原来类型即为整型指针,可以去掉强转),最后输出结果为。
再想一下,如果将第一例第五行改为int *ptr2=(int *)((int)a+1);打印结果会是什么?
这里要考虑数据在计算机中的存储模式:大端模式和小端模式。解释一下:
大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。
在大端模式下,a在计算机中存储如下(从低地址到高地址,一个十六进制数代表内存的一个字节,下同):
0x11 0x12 0x13 0x14 0x21 0x22 0x23 0x24 0x31 0x32 0x33 0x34 0x41 0x42 0x43 0x44 0x51 0x52 0x53 0x54
在小端模式下,a在计算机中存储如下:
0x14 0x13 0x12 0x11 0x24 0x23 0x22 0x21 0x34 0x33 0x32 0x31 0x44 0x43 0x42 0x41 0x54 0x53 0x52 0x51
(int)a表示将a的首地址强转为整型数据(若原来是0012FF6C,转换后仍为0012FF6C,但是这时已经不是表示地址而是一个十六进制整型数了),这时+1代表整型数(int)a加1(变为0012FF6D),再把结果强转为整形指针,故指向的数据地址为0012FF6D,即上述存储去的第二个字节开始处。此时输出*ptr2,即输出a数组存储区中第二到第五字节组成的一个整型数,若为大端模式则输出,若为小端模式则输出。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:15916次
排名:千里之外2维数组元素的首地址都是指向同一个值么?_c语言吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:519,082贴子:
2维数组元素的首地址都是指向同一个值么?收藏
比方说a[2][3]这个2维数组可看成2个1维数组,那么这2个一维数组的首地址相同么?~。。还有指针数组的元素是不是可以用来赋予2维数组首地址。。新手求解。。
c语言海同强大的师资阵容,因人制定课程内容,分阶段学习.c语言就到正规IT技术培训机构-海同科技,培训IT技术面对面教学,免费重读!
如果相同那就只有一个数组了…
二为就是一为的
是人们这样想象成2为,在内存中也是一为的形式存在,也就是说,他只是把1为的某个数字把他当成了2为的0号
对1为进行重新排列,其实在内存中存放还是1为的
LS的意思是不是说2维的首地址和一位的首地址一样,都只有一个呢?
指针与数组,的确是道坎,蛋白质给各位新手做个简单说明。。。能不能看懂,不关偶的事。。。内存本身是一维的,所谓多维数组,最终都是要转成一维的。比如 int A[5][6][7]一共分配了 5*6*7=210个 int (840字节),而A所代表的数值,就是这840字节的首地址。数组是怎么工作的呢?这就要看编译器是怎么做的了:比如int A[210]那么就有A[i*(6*7) + j*7 + k] &==& A[i][j][k]实际上,编译器也是这么做的,这个下标转换工作,是在运行时完成的,一般要做乘法IMULA[i+1][j][k]和A[i][j][k]所代表的元素位置是相差[6]*[7]=42个的,也就是说,A[5][6][7]实际上是由 5个 [6][7]的二维数组连接而成的,同理,一个[6][7]的二维数组是由6个[7]的一维数组连接而成的。数组的名称代表的是数组的首地址int B[3][4]那 B[i]就是一个[4]的一维数组的名称,他代表的地址值是 B + i*4,因为他是第i个[4]数组。B[i]这个值,它是一种介于常数和变量之间的一种数,它不是变量,因为它没有实际的存储位置,它是运行时即时计算出来的,所以它也不是常数。那指针与数组的差别在什么地方呢?一维数组的名称,实际相当于一个常量型的int*,也就是本身的值不可以改变的int*指针int A[5];int B[10];int *p=A;那么,以后使用中,p[i] 与 A[i]几乎是等效的,p与A的区别就是,p可以被改变,如p=B;那p[i]就与B[i]等效了.int A[5][8]int *p;p=(int*)A;那么, p[i*8+j] 与 A[i][j]等效。再举个复杂一点的int A[5][8];int **p; //这是一个指针,指针所指向的东西也是一个指针。p= (int**) malloc(sizeof(int*)*5); //给p分配5个int*单位的空间for(i=0;i&5;i++){ p[i]=A[i];}
//p的元素值设成A的5个[8]一维数组的首地址。这样,p所指向的是一个5 (int*)空间的内存,第i个空间本身也是一个指向A[i]首地址的指针。那么:p[i][j] 将与 A[i][j] 代表同样的一个内存单位,使用上没有区别。但运行效率上,肯定是p[i][j]要快的多,为啥呢,因为,运行的时候,A[i][j]是要做一次乘法的 i*8, A+i*8+j ,而 p[i}[j]
&==& *(*(p+i) + j),只要读一次p[i]中的值,不要做乘法了。这个例子也可以看出,A[i]是一个需要运行时计算的值。而p[i]本身有存储位置,一但初始化了,就不用再计算了。(8这个数字是一个2的倍数,在实际编译时,会被优化成 shr 3,再加上int本身就是4字节,还要*4,所以实际字节位移是*32,也就是优化成shr 5,也是很快的,但其它数值,就不一定好优化了)定义数组时,可以这样int A[][5][8],这是神马东西呢?它与 int (*A)[5][8]是等效的.就如同 int B[] 与 int* B是等效一样.这里,int (*A)[5][8],A外边的()很重要,不能省掉。int (*A)[5][8] //A是一个指针,它所指向的元素是 [5][8]这样的二维数组int *A[5][8] //A是一个[5][8]的二维数组,数组的每一个元素都是 int*型的指针。int A[5][][8] 或者 A[5][8][] 或者 A[][][8]都是不合法的,为啥呢,前面已经说了,编译器是要用A[][5][8]的5 和 8来计算 A[i][j][k]的位置 A+i*5*8 + j*8 +k的,所以,只有第一个下标是不需要的,其它一定不能省,要不编译器没法计算下标了。
当然,实际int A[]是无意义的,所以一般编译器认为无效。
明白,但是如何作为局部函数的参数用来值传递呢?我都是static··
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或21ic官方微信-->
后使用快捷导航没有帐号?
查看: 1799|回复: 3
能分别对二维数组的每一行的首元素指定地址吗?
&&已结帖(0)
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
主题帖子积分
专家等级:结帖率:66%
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
比如说有这样的两维数组Array[3][4],在KEIL里面可以at命令将这个数组分配到想要的地址空间,分配好了第0行的第0个元素,剩下其他元素的就是编译器自己安排了。我现在想这样子,就是将这个数组的第0行的第0个元素分配在某个地址空间(这一行剩下其他元素由编译器自己安排),然后分配第1行的第0个元素到某个地址空间,这样依次分配下去直至分配完成,这个做法行得通吗?
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
技术总监, 积分 39962, 距离下一级还需 10038 积分
技术总监, 积分 39962, 距离下一级还需 10038 积分
主题帖子积分
专家等级:结帖率:3%
主题帖子积分
技术总监, 积分 39962, 距离下一级还需 10038 积分
技术总监, 积分 39962, 距离下一级还需 10038 积分
只需指定首地址,其它的就已经固定了
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
中级工程师, 积分 3272, 距离下一级还需 1728 积分
中级工程师, 积分 3272, 距离下一级还需 1728 积分
主题帖子积分
专家等级:结帖率:91%
主题帖子积分
中级工程师, 积分 3272, 距离下一级还需 1728 积分
中级工程师, 积分 3272, 距离下一级还需 1728 积分
本帖最后由 刘前辈 于
13:02 编辑
概念没搞清呢。
对于 Array[3][4],, Array[n-1]就是第n-1行的首地址!即Array[行首地址][行内容],
举例:例如char&&Array[][]= {&ab &,&abc &,abcd&&&};
你想把第1行定位在相对Array[0][0]大于3的合理变化地址,只要控制初始化&ab &后面的空格就行了。——这样第一行初始地址就会变化。
& && &&&例如你想把第1行首地址定位在相对数组0地址后面第6字节,只要在初始化时,把第0行写5个字符就行了 &ab& && 。第 n-1 行以此类推,以前面一行为相对地址参考,可以任意定位后面一行的首地址。
做自己所热爱的,并热爱自己所做的。
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
主题帖子积分
专家等级:结帖率:66%
主题帖子积分
初级技术员, 积分 63, 距离下一级还需 37 积分
初级技术员, 积分 63, 距离下一级还需 37 积分
只需指定首地址,其它的就已经固定了
ayb_ice 发表于
你说的“首地址”也就是首行的首个元素的地址吧?
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
荣誉元老奖章
等级类勋章
坚毅之洋流
发帖类勋章
时间类勋章
技术领袖奖章
人才类勋章
热门推荐 /2

我要回帖

更多关于 js数组删除元素 的文章

 

随机推荐