“支持非可变性”和“使用空数组而不是NULL”

本文分享了《EffectiveJava》一书中的实践经验,重点介绍了支持非可变性和使用空数组代替NULL的原则及其应用。支持非可变性通过限制对象修改、确保类不可继承等方法实现;使用空数组则被视为一种简单的NullObject模式。
最近拿到了《Effective Java》这本书,虽然有点旧,而且其中讲述的java是1.3左右,不过其中的一些思想到现在也可以使用。

首先被我实践使用的是下面两个原则:
1:支持非可变性
2:使用空数组而不是NULL

支持非可变性主要是通过一下几个方法来实现的:
1:不提供修改对象的方法,比较典型的是setXXX
2:保证没有可被子类改写的方法,可以通过设置类为final来完成
3:使所有域都是final的,这一步没有完全理解,可能和线程同步有关
4:使所有域都是私有的,貌似private好不够,需要和final搭配
5:保证对于任何可变组件的互斥访问,可以使用保护性拷贝

我的个人感觉,如果你的类只是包含原始数据类型的对象,就是不存在是否引用的那种,那么这里的方法要简单很多,不过如果不是的话(一般都不是),那么就需要仔细考虑了。

第二个比较容易理解,因为在了解了NullObject之后,其实这里的这个空数组也可以看作为NullObject的一种退化。

对于我来说,第二个比较容易实践,而第一个其实还存在一些问题。
基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)内容概要:本文档围绕基于遗传算法的异构分布式系统任务调度算法展开研究,重点介绍了一种结合遗传算法的新颖优化方法,并通过Matlab代码实现验证其在复杂调度问题中的有效性。文中还涵盖了多种智能优化算法在生产调度、经济调度、车间调度、无人机路径规划、微电网优化等领域的应用案例,展示了从理论建模到仿真实现的完整流程。此外,文档系统梳理了智能优化、机器学习、路径规划、电力系统管理等多个科研方向的技术体系与实际应用场景,强调“借力”工具与创新思维在科研中的重要性。; 适合人群:具备一定Matlab编程基础,从事智能优化、自动化、电力系统、控制工程等相关领域研究的研究生及科研人员,尤其适合正在开展调度优化、路径规划或算法改进类课题的研究者; 使用场景及目标:①学习遗传算法及其他智能优化算法(如粒子群、蜣螂优化、NSGA等)在任务调度中的设计与实现;②掌握Matlab/Simulink在科研仿真中的综合应用;③获取多领域(如微电网、无人机、车间调度)的算法复现与创新思路; 阅读建议:建议按目录顺序系统浏览,重点关注算法原理与代码实现的对应关系,结合提供的网盘资源下载完整代码进行调试与复现,同时注重从已有案例中提炼可迁移的科研方法与创新路径。
【微电网】【创新点】基于支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文提出了一种基于支配排序的蜣螂优化算法(NSDBO),用于求解微电网多目标优化调度问题。该方法结合支配排序机制,提升了传统蜣螂优化算法在处理多目标问题时的收敛性分布性,有效解决了微电网调度中经济成本、碳排放、能源利用率等多个相互冲突目标的优化难题。研究构建了包含风、光、储能等多种分布式能源的微电网模型,并通过Matlab代码实现算法仿真,验证了NSDBO在寻找帕累托最优解集方面的优越性能,相较于其他多目标优化算法表现出更强的搜索能力稳定性。; 适合人群:具备一定电力系统或优化算法基础,从事新能源、微电网、智能优化等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于微电网能量管理系统的多目标优化调度设计;②作为新型智能优化算法的研究与改进基础,用于解决复杂的多目标工程优化问题;③帮助理解支配排序机制在进化算法中的集成方法及其在实际系统中的仿真实现。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注支配排序、拥挤度计算蜣螂行为模拟的结合方式,并可通过替换目标函数或系统参数进行扩展实验,以掌握算法的适应性与调参技巧。
<think>我们在讨论指针数组的初始化。指针数组是一个数组,其元素都是指针。现在需要将指针数组的所有元素初始化为NULL。根据引用[3],我们可以通过定义指针变量并初始化为NULL。对于指针数组,我们可以使用类似的方法,在定义时初始化整个数组。例如,如果我们有一个指针数组,包含5个整数指针,我们可以这样初始化:int*arr[5]={NULL};但这种方式会将第一个元素初始化为NULL,其余元素会被初始化为0(即NULL),因为C语言规定如果初始化列表的元素个数少于数组长度,则剩余元素被初始化为0。不过,为了确保所有元素都是NULL,我们可以显式地初始化每个元素:int*arr[5]={NULL,NULL,NULL,NULL,NULL};或者,我们可以在定义后使用循环进行初始化。下面给出两种方法的示例代码:方法1:定义时初始化(显式列出所有元素)方法2:定义后循环初始化同时,我们也可以使用静态初始化,或者使用memset函数(但注意memset通常用于内存块设置,对于指针数组,我们也可以使用,因为NULL就是0,但是要注意指针表示不一定与全0相同,不过通常NULL就是0。标准保证指针常量(即0或(void*)0)转换为指针类型后成为指针,而指针不一定用全0表示,但memset(ptr,0,size)对于指针数组是否安全?实际上,由于指针常量0转换为指针类型时是指针,而memset将内存置0后,当我们读取这些指针时,它们将为指针(因为标准规定用0表示的指针常量转换为指针类型就是指针,而内存全0的指针表示在大多数平台上是指针,但并所有平台都如此,所以最好避免使用memset来初始化指针为指针,而是用赋值NULL的方式)。因此,推荐使用循环赋值或者初始化列表。示例1:初始化列表(适用于已知大小的数组)示例2:循环初始化(适用于大小可变或不想写多个NULL的情况)下面我们分别给出两个示例。</think> ### C语言中指针数组初始化为NULL的方法 在C语言中,指针数组是一个数组,其元素均为指针类型。将指针数组初始化为`NULL`的操作有几种常用方法: #### 📌 方法1:定义时显式初始化 ```c #include <stdio.h> int main() { // 定义包含5个指针的数组,全部初始化为NULL int *ptrArray[5] = {NULL, NULL, NULL, NULL, NULL}; for (int i = 0; i < 5; i++) { printf("ptrArray[%d] = %p\n", i, (void *)ptrArray[i]); } return 0; } ``` - **执行结果**:所有元素输出`(nil)`或`0x0`(指针值) - **优点**:语法简洁直观 - **注意**:需要手动指定每个元素[^1] #### 📌 方法2:使用循环初始化(推荐用于大型数组) ```c #include <stdio.h> int main() { int *ptrArray[10]; // 声明包含10个指针的数组 // 循环初始化所有元素为NULL for (int i = 0; i < 10; i++) { ptrArray[i] = NULL; } // 验证初始化结果 for (int i = 0; i < 10; i++) { if (ptrArray[i] == NULL) { printf("Element %d initialized to NULL\n", i); } } return 0; } ``` - **执行结果**:输出所有元素已初始化提示 - **优点**:适合未知大小或动态数组 - **内存示意**: ``` 索引: 0 1 2 ... 9 值: NULL NULL NULL ... NULL ``` #### 📌 方法3:静态初始化(全局数组) ```c #include <stdio.h> // 全局数组自动初始化为NULL int *globalPtrArray[3]; int main() { for (int i = 0; i < 3; i++) { printf("globalPtrArray[%d] = %p\n", i, (void *)globalPtrArray[i]); } return 0; } ``` - **特点**:未显式初始化的全局指针数组自动设为`NULL` - **标准依据**:C标准规定全局变量自动初始化为零值(即`NULL`)[^3] ### 💡 关键概念 1. **NULL本质**:在C语言中定义为`(void*)0`,表示无效指针 2. **内存安全**:初始化为`NULL`可防止野指针导致的未定义行为 3. **检测机制**:使用`if (ptr == NULL)`判断指针是否有效 ### ⚠️ 常见错误 ```c // 错误:只初始化第一个元素 int *ptrArray[5] = {NULL}; // 错误:memset不能保证NULL兼容性 memset(ptrArray, 0, sizeof(ptrArray)); ``` > 第一种错误导致后续元素值为0(但不一定是指针),第二种可能在不兼容平台上出错[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值