网站首页 > java教程 正文
笔者在上一篇文章《C语言中为何不能直接对一个数组对象赋值》中谈到了为何C语言设计之初没有把对数组赋值的语法引入的各种缘由。当然,从其语法体系角度而言,一个数组对象作为表达式被使用时,其类型会被隐式转换为指向其元素类型的指针,而数组本身的引用是不能被修改的,所以像下面的代码会导致语法错误:
int arr1[3] = { 0 };
int arr2[3] = { 0 };
arr1 = arr2; // 相当于:(int * const)arr1 = (int *)arr2;
这是显而易见的。
那有没有办法能通过某种语法扩展来使得C语言能方便地对数组进行赋值呢?答案是可以被设计出来的!笔者这里通过GNU语法扩展中所引入的 Case Ranges(https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html),再结合C++17中所完善的折叠表达式(fold expression)为C语言设计出 [ from ... to ] 这一索引折叠表达式(index fold expression)的语法扩展。
基本定义
如果一个表达式中含有 [ from ... to ] 这种表达,那么该表达式即为索引折叠表达式。其通常表现形式为:
a[ 0 ... 2 ] = b[ 5 ... 7 ];
相当于:
( a[0] = b[5],
a[1] = b[6],
a[2] = b[7]
);
这里为了简化编译器实现,可以将 from 和 to 限定为常量表达式,即它们必须是编译时就能确定的常量。这一点是跟GNU语法扩展中所引入的 Case Ranges 所契合的。当 [ from ... to ] 的操作数是一个数组对象时,to 可被缺省。而当 to 被缺省时,其值为 sizeof(array) / sizeof(array[0]) - 1U。这一点也可适用于变长数组。
约束
- 对于任何一个 [ from ... to ],必须满足:from <= to。当 from == to 时,它即被退化为基本表达式(primary expression)。
- 如果一个表达式具有多个 [ from ... to ],那么所有子表达式中的 to - from 的值必须全都相同。
- 索引折叠表达式的返回值与其他约束均可继承于逗号表达式。
代码例子
int arr1[3] = { 1, 2, 3 };
int arr2[5] = { 1, 2, 3, 4, 5 };
// 相当于:(arr1[0] = arr2[2], arr1[1] = arr2[3], arr1[2] = arr2[4]);
arr1[0 ...] = arr2[2 ...];
// 相当于:int arr3[3] = { arr2[1], arr2[2], arr[3] };
int arr3[] = { arr2[1 ... 3] };
int sum = 0;
// 相当于:(sum += arr1[0], sum += arr1[1], sum += arr[2]);
sum += arr1[0 ...];
// 相当于:(arr1[0] += sum, arr1[1] += sum, arr1[2] += sum);
arr1[0 ...] += sum;
static bool IsLower(int a, int b)
{
return a < b;
}
bool bArr[3];
// 相当于:
// (bArr[0] = IsLower(arr1[0], arr3[0]),
// bArr[1] = IsLower(arr1[1], arr3[1]),
// bArr[2] = IsLower(arr1[2], arr3[2])
// );
bArr[0 ...] = IsLower(arr1[0 ...], arr3[0 ...]);
int FooInc(int arr[static 3])
{
// 相当于:(++arr[0], ++arr[1], ++arr[2]);
// 注意,arr作为函数形参,其本质上属于指针,而不是数组,
// 因此,这里 to 的位置不可缺省!
++arr[0 ... 2];
// 相当于:return (arr[0], arr[1], arr[2]);
// 因此最后其实返回的是 arr[2] 的值。
return arr[0 ... 2];
}
优化
如果对多个数组或是被 restrict 修饰的指针进行操作的话,编译器后端可以生成SIMD指令或是使用Intel TBB或微软的PPL这种并行库的 parallel_for,对这些数组元素做多线程并行操作。
- 上一篇: C语言中为何不能直接对一个数组对象赋值
- 下一篇: golang2021数据格式(3)数组使用与赋值
猜你喜欢
- 2024-11-16 java开发中经常使用的数组以及使用方法
- 2024-11-16 为什么要使用数组?如何使用数组?(什么是数组为什么要使用数组)
- 2024-11-16 PHP的SPL扩展库(二)对象数组与数组迭代器
- 2024-11-16 ES6 数组解构赋值(es6 结构赋值)
- 2024-11-16 java笔记之数组(java,数组)
- 2024-11-16 PHP笔记 (七)数组(php7 数组)
- 2024-11-16 Scala学习数组和元组了解(scala数组集合的操作)
- 2024-11-16 Java——数组函数(java 数组使用)
- 2024-11-16 VBA一组代码如何搞定赋值给数组arr及回填数据给工作表
- 2024-11-16 java数组(一)(java 数组)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)