数组溢界地址的正确使用: 即 int a[6] 中的 a[-1] 和 a[6] 正确使用

正如大家所知道的那样:

数组  int a[6] ,  编译器阅读到这句数组定义,会为分配6个int 类型的地址;a[0]  a[1]   a[2]   a[3]  a[4]  a[5]。我们 可以正确的使用这6地址内容来存放数据。而本文想说的是a[0]前一个地址和 a[5] 后一个地址的正确使用。

可能有人会有疑问,这两个地址是非法的,是不允许访问和使用的。

幸运的是,我们并不需要引用这两个元素,而只是引用这两个元素的地址,并且着脸个地址在所有C语言实现中都是存在的。ANSIC C 标准明确允许这种用法:数组中实际不存在的“溢界”元素地址位于数组所占内存之后,这个地址可用于进行赋值和比较。当然如果要引用元素就是非法的。

可能有人会问,如何使用?

答案就是“不对称边界”

解释下就是“当我们使用指针遍历数组元素时使用”

下面是一个简单的例子:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
 int a[10];
 int *p;
 int  i=0;
  for(p=a;p!=&a[10];p++) 
     {
      *p=i;
      i++;
     }
  for(p=a;p!=&a[10];p++) 
    printf("%d\n", *p);
return 0;
}

程序可以正常运行,使用 gcc编译器  centOS操作系统

运行结果:

[[email protected] C_test]$ gcc -o arry_over_test arry_over_test.c
[[email protected] C_test]$ ./arry_over_test
0123456789
[[email protected] C_test]$

可以看到 for 循环中是使用了 P!=&a[10] 作为循环结束判断条件,是不是感觉有点 STL标准中 iterator 的感觉,对这就是不对成边界的使用。当然a[-1]使用来从后往前遍历数组的不对称边界。

尤其当你的数组元素是结构体, 类 等复杂结构时使用这两个地址可以简化操作。(前提是使用指针遍历数组)

数组溢界地址的正确使用: 即 int a[6] 中的 a[-1] 和 a[6] 正确使用

时间: 2024-11-05 20:13:28

数组溢界地址的正确使用: 即 int a[6] 中的 a[-1] 和 a[6] 正确使用的相关文章

c语言--二维数组的首地址问题

对于一个二组数组int a[3][4],以下几个地址值是相等的,但是地址类型不尽相同: 1)a 2)a[0] 3)*(a+0) 4)*a 5)&a[0][0] int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };printf("%x,%x,%x,%x,%x\n", a, (int *)a, *a, a[0], &a[0][0]); 结果如下: 把上面的地址各+1: printf("%x,%x,%x,%

C语言中与指针相关问题——论数组名和数组名取地址的关系

这是由一道面试题联想到的一些问题,这里自己给做个小总结! 首先看看这道面试题: #include <stdio.h> int main() { int a[5] = { 1, 2, 3, 4, 5 }; int *pi = &a + 1; printf("%d, %d\n", *(a + 1), *(pi - 1)); return 0; } 答案是2, 5.至于是为什么,我后面说一下我自己的理解. 这里有个要注意的地方,以上代码在CodeBlock中会有个警告,但

对数组名取地址

int a[5]={1,2,3,4,5}; int b[100]; 一个数组名代表的是数组中第一个元素的位置,通过数组名我们可以访问数组,先看下面两个问题 问题一:看到一篇文章这么写的..int array[10];int (*ptr)[10];ptr=&array;//这里说明&array是指向数组的指针,但为什么&array是指向数组的指针?答一:对数组名取地址在C标准里面是未定义的行为.由于数组名是右值,而&操作符要求操作数具有具体的内存空间,换言之就是一个变量,因此

C语言中对数组名取地址

在C/C++中,数组名相当于一个指针,指向数组的首地址.这里"相当于"不代表等于,数组名和指针还是有很多区别的,这个在<C陷阱与缺陷>里有详尽的讲述.而这里要说的是对于数组名取地址的这么一个操作. 如果声明有如下数组: int arr[5]; 那么,&arr这个操作得到了什么值呢? 如果简单的认为arr就是一个指向数组首地址的指针的话,那么很自然会想到&arr得到的是一个指向存放arr这个指针的指针,也就是一个二级指针,然而事实却并不是这样. 观察以下代码:

C语言对数组名取地址

你有没有想过,对一个一维数组名取地址,然后用这个地址进行加减运算.这会出现什么样的结果呢? 示例: int a[5] = {1,2,3,4,5}; int *p = (int *)(&a+1); printf("%d\n",*(p-1)); 这个输出会是多少呢? 咦?为什么第二行需要强制转化类型呢? 答:a是一个一维数组的名字,&a相当于一个指向一维数组的指针.怎么感觉这么熟悉?指向数组的指针,那不就是行指针吗?int (*p)[]. 行指针+1,就是对指针进行加减操作

C语言中,为什么指针表达式的值+1.对应的地址值却+4?/为什么两个数组元素的地址相减之差不为地址之差?

在C语言中,我们常常用到的一个运算是让某个变量的值+1. 例如 M = M + 1. 而在实际运用中,我们发现 对于指针进行+1运算,算出来的结果是+4. 如下图 图中我们定义的 变量M 和指针Matrix如下: int M = 3; int* Matrix = {1,2,3}; 可以看到,对于M和 Matrix ,+1运算的效果是不同的. 这个差异是因为C语言的标准中规定了 加法与减法运算对于地址的操作和对于值的操作是不同的,如下文中粗体所示: C89 3.3.6 Additive opera

C语言 对数组名取地址

作者 : 卿笃军 你有没有想过,对一个一维数组名取地址,然后用这个地址进行加减运算.这会出现什么样的结果呢? 示例: int a[5] = {1,2,3,4,5}; int *p = (int *)(&a+1); printf("%d\n",*(p-1)); 这个输出会是多少呢? 咦?为什么第二行需要强制转化类型呢? 答:a是一个一维数组的名字,&a相当于一个指向一维数组的指针.怎么感觉这么熟悉?指向数组的指针,那不就是行指针吗?int (*p)[]. 行指针+1,就是

C/C++拾遗(一):关于数组的指针和数组元素首地址的一道经典题

代码如下: #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&a+1); int *p1 = a; int *p2 = &a[0]; int *p3 = (int *)(&a); if(p1 == p2){ printf("p1 == p2\n"); }else{ printf("p1 != p2\n"); } i

二维数组元素的地址

一维数组元素的地址大家都比较容易理解,但对于二维数组,就很容易搞混了.今天我又被这个问题给弄糊涂了,翻了翻老谭的书本,对这个问题有了更深的认识. 首先给出一个二维数组a,它的定义为: int a[3][4] = {{1,3,5,7}, {9,11,13,15}, {17,19,21,23}}; a数组包含3个行元素,a[0],a[1],a[2].而每个行元素又是一个一维数组,它包含4个元素. 从二维数组的角度来看,a代表二维数组首元素的地址,现在的首元素不是简单的整型,而是由4个整型元素所组成的