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

本文介绍了一种在C语言中使用数组时的特殊技巧——不对称边界。通过对数组元素的巧妙利用,可以在遍历数组时简化代码并提高效率,尤其是在处理结构体或类等复杂类型时。

正如大家所知道的那样:

数组  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操作系统

运行结果:

[trageday@trageday C_test]$ gcc -o arry_over_test arry_over_test.c 
[trageday@trageday C_test]$ ./arry_over_test 
0123456789
[trageday@trageday C_test]$ 

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

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

<think>好的,我现在需要回答用户关于Java中数组声明的问题:“Java中int a[20];是不是正确数组声明”。用户可能刚接触Java,对数组的声明方式不太清楚,或者之前学过其他语言比如C/C++,导致混淆了语法。 首先,我要确认Java中正确数组声明方式。Java的数组声明语法与C/C++有所不同。在C/C++中,确实可以使用类似int a[20];的方式来声明数组,但在Java中这是不正确的。Java的语法要求数组的声明中,方括号跟在类型后面或者变量名后面,但初始化大小的时候必须使用new关键字,或者在声明时直接初始化元素,而不能在声明时直接指定大小,除非是在创建数组对象的时候。 接下来,我需要回忆Java的数组声明规则。Java数组的声明有两种方式: 1. 类型[] 数组名; 例如:int[] a; 2. 类型 数组名[]; 例如:int a[]; 这两种方式都是合法的,但通常推荐第一种,因为更符合Java的规范,将类型数组符号放在一起,提高可读性。但无论是哪种声明方式,声明时都不能指定数组的大小,比如int[20] a; 或者int a[20];都是错误的。正确的做法是在声明后,使用new关键字来初始化数组并指定大小,例如:a = new int[20]; 或者在声明的同时初始化:int[] a = new int[20]; 用户给出的例子是int a[20];,这看起来像是混合了C/C++的语法,在Java中是不允许的。Java不允许在声明数组变量时直接在变量名后的方括号里写大小。正确的做法应该是将大小放在new表达式中,比如int[] a = new int[20];或者分开写:int[] a; a = new int[20];。 接下来,我需要检查是否有例外情况。例如,Java是否允许在声明数组变量时直接指定大小而不使用new?比如在声明时初始化数组元素,例如int[] a = {1,2,3}; 这种情况下是允许的,但这里是通过初始化列表隐式确定数组大小,而不是显式指定数字。用户的问题中的例子是显式指定大小20,这时候必须使用new关键字。 另外,用户可能存在的误区是认为在变量名后的方括号中直接写大小是合法的,这在C/C++中是可行的,但在Java中不行。因此需要指出JavaC/C++在数组声明上的区别,避免用户混淆。 还需要考虑用户可能的后续问题,比如如何正确声明数组,或者为什么Java不允许这样的语法。这时候回答中需要明确正确的声明方式,并解释原因,可能涉及Java的语法设计,比如强调类型安全内存分配的方式。 总结来说,用户的问题是要确认int a[20];是否正确,而正确的回答是否定的,并指出正确的声明方式。同时需要解释Java中数组声明的正确语法,可能对比C/C++的不同,帮助用户理解为什么这样的写法是错误的,以及如何正确声明初始化数组。</think>### Java 中 `int a[20];` 是否是合法的数组声明?——逐步解析 **直接答案**: **`int a[20];` 不是 Java 中合法的数组声明语法**。这种写法会直接导致编译错误。 --- #### 1. **Java 数组声明的核心规则** - **规则 1**:Java 数组的声明**不能直接指定大小**。 大小必须在**创建数组对象**时通过 `new` 关键字指定(或在初始化列表中隐式确定)。 **错误示例**: ```java int a[20]; // 错误:声明时直接写大小 int[20] b; // 错误:声明时直接写大小 ``` - **规则 2**:Java 数组的声明语法有两种合法形式: - **推荐写法**:`类型[] 变量名;` ```java int[] arr; // 合法:声明一个 int 数组变量 ``` - **兼容 C 风格的写法**:`类型 变量名[];` ```java int arr[]; // 合法但不推荐 ``` --- #### 2. **正确声明并初始化数组** - **步骤 1:声明数组变量** 仅定义数组的引用(未分配内存): ```java int[] arr; // 声明一个 int 数组变量 ``` - **步骤 2:创建数组对象** 使用 `new` 关键字分配内存并指定大小: ```java arr = new int[20]; // 创建长度为 20 的数组 ``` - **一步完成声明初始化**: ```java int[] arr = new int[20]; // 正确写法 ``` - **直接初始化元素**(隐式指定大小): ```java int[] arr = {1, 2, 3}; // 合法:数组长度为 3 ``` --- #### 3. **错误示例分析** - **错误写法**:`int a[20];` **编译错误信息**: ``` error: ']' expected int a[20]; ^ ``` **原因**:Java 语法不允许在声明时通过 `变量名[大小]` 直接指定数组长度。 - **对比 C/C++**: 在 C/C++ 中,`int a[20];` 是合法的,但 Java 的数组声明语法与之不同,这是常见的混淆点。 --- #### 4. **总结与对比表** | 操作 | Java 语法 | C/C++ 语法 | |--------------------|-------------------------------------------|---------------------| | **声明数组变量** | `int[] arr;` 或 `int arr[];` | `int arr[20];` | | **创建数组对象** | `arr = new int[20];` | 无需 `new`(栈分配) | | **声明+初始化一步** | `int[] arr = new int[20];` 或 `int[] arr = {1,2,3};` | `int arr[20] = {1,2,3};` | **关键点**: - Java 中数组是对象,必须通过 `new` 动态分配内存。 - 声明时指定大小会导致语法错误。 --- ### 常见问题解答 **Q:为什么 Java 不允许 `int a[20];` 这种写法?** - **A**:Java 将数组视为对象,其内存分配需通过 `new` 显式管理,而声明时仅定义引用变量,不涉及内存分配。这种设计强制开发者明确区分“声明引用”“创建对象”。 **Q:如何快速记忆 Java 数组正确写法?** - **技巧**: 1. 始终将 `[]` 紧贴类型(如 `int[]`),强调“这是一个数组类型”。 2. 将 `new int[20]` 视为“创建长度为 20 的数组对象”。 3. 避免使用 C 风格的 `int arr[];`(虽然合法,但降低可读性)。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值