用宏实现C/C++从非零整数开始的数组
相信大家在刚学习C/C++时,都会对数组下标从0开始编号有疑惑。尽管我是喜欢从0开始编号的“0党”,但是也有很多的人是喜欢从1开始编号。
意识到C/C++数组与指针具有一定的相似性后,我开始构思如何仿造Pascal实现类似于array[1..100]这样的声明方法。
今天和大神gjs讨论后,他给出第一个实现方案:
int buf[];
int a[];
a = buf + ; //等价于a = &b[10]
这样目的是访问a[0]的时候相当于访问b[10],因此a[-10]相当于访问b[0],这样我们可以通过访问a来访问buf,相当于得到一个从-10开始,长度为100的数组。
可惜的是,编译不通过。听说是数组不能作为左值。
因此我们改用指针实现。
int buf[];
int *a = buf + ;
a[-] = ;
编译成功。
我们决定改写成宏。
#define array(type, name, lb, ub) type buf[ub - lb + 1]; type* name = buf - lb
这样,我们就可以使用array(int, abc, -5, 5)来声明一个下标范围为-5到5的“数组”。
似乎是没有问题了。
不过,遇到多个array声明就有问题了:
int main(){
array(int, a, , );
array(int, b, -, );
}
编译器抗议了:
:: error: conflicting declaration 'int buf [3]'
9:5: error: 'buf' has a previous declaration as 'int buf [100]'
这是由于使用了两个临时变量造成的。展开定义:
int buf[ - + ]; int* a = buf - ;
int buf[ - - + ]; int* b = buf - -;
声明了两个buf!
为了解决这一问题,我们使用这样的方法:改名。
这是新的array声明:
#define array(type, name, lb, ub) type name##buf[ub - lb + 1]; type* name = name##buf - lb
注意到##号了吗?这是连接的意思。这样,他们展开后就得到了:
int abuf[ - + ]; int* a = abuf - ;
int bbuf[ - - + ]; int* b = bbuf - -;
当然,这并不能保证没有bug。比如说我又声明了一个char abuf[30]。
最好的方法是将它改复杂一些,再加上大量的随机字符,然后还要加上文件名、行数,将冲突的可能性改到最小。当然,故意作死的人我们也拦不住。
好了,现在使用是一点问题都没有。但是使用memset的话……
你可能会说“不就是不用memset(a, 0, sizeof a),而用memset(a + lb, 0, sizeof a)嘛,有什么不会的?”
这就不对了。我们声明的a是指针,sizeof a的结果一般是4,因为指针大小是4。这样无法达到初始化的结果。
gjs:如果你不嫌麻烦,可以再写个宏,把原来的变量名找回来,然后……
我还是不搞了。
用宏实现C/C++从非零整数开始的数组的更多相关文章
- 回数是指从左向右读和从右向左读都是一样的数,例如 12321 , 909 。请利用 filter() 滤掉非回数
不管在什么地方,什么时候,学习是快速提升自己的能力的一种体现!!!!!!!!!!! 最近一段时间学习了廖雪峰老师学的Python学习资料,给自己的帮助很大,同时也学到的了很多,今天做了一道练习题,对于 ...
- Oracle 表的行数、表占用空间大小,列的非空行数、列占用空间大小 查询
--表名,表占用空间大小(MB),行数select table_name, round(num_rows * avg_row_len /1024/1024, 8) as total_len, num_ ...
- [饭后算法系列] 数组中"和非负"的最长子数组
1. 问题 给定一列数字数组 a[n], 求这个数组中最长的 "和>=0" 的子数组. (注: "子数组"表示下标必须是连续的. 另一个概念"子 ...
- 非旋 treap 结构体数组版(无指针)详解,有图有真相
非旋 $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ ...
- py-统计一个矩阵中每一列的非0数的个数
1.文件类型类似于这样: 不过数据量比这个要更大一点. 2.对应上述数据的运行结果: import matplotlib.pyplot as plt with open('test.txt') as ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- n!最末尾非0数
最小周期串:如果s是ss的周期串,那么ss就可以表示成几个周期的s,如果s是ss的最小周期串,那么s就是ss的周期串中最小的一个.例,ZgxZgxZgxZgx的最小周期串是Zgx.{很好理解} 给你一 ...
- 238. Product of Array Except Self 由非己元素形成的数组
[抄题]: Given an array of n integers where n > 1, nums, return an array output such that output[i] ...
- hdu 3887 Counting Offspring(DFS序【非递归】+树状数组)
题意: N个点形成一棵树.给出根结点P还有树结构的信息. 输出每个点的F[i].F[i]:以i为根的所有子结点中编号比i小的数的个数. 0<n<=10^5 思路: 方法一:直接DFS,进入 ...
随机推荐
- linux_vim
今天稍微学习以下vim 学习的一些课件: 1. 2. 3. 4. 5.
- 大数据入门第二十天——scala入门(一)入门与配置
一.概述 1.什么是scala Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性.Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序. ...
- 20155229《网络对抗技术》Exp8:Web基础
实验内容 (1).Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. (2).Web前端javascipt 理解JavaS ...
- # 2017-2018-2 20155231《网络对抗技术》实验九: Web安全基础实践
2017-2018-2 20155231<网络对抗技术>实验九: Web安全基础实践 实验要求: 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验内容: ( ...
- Exp6
实验内容 一.公开渠道信息搜集 本次信息搜集在metasploit平台上实现(使用msfconsole命令进入) 1.通过DNS和IP挖掘信息 (1)使用whois进行域名信息查询 使用原因:目前互联 ...
- python 生成器按指定大小读取文件
#!/usr/bin/env python import osimport sys def read_file(fpath): Block_Size = 1024 with open(fpath,&q ...
- Lambda学习---方法引用和其他基本应用
package com.zx; import java.util.*; import java.util.function.*; import java.util.stream.Collectors; ...
- 【中间件】Redis 实战之主从复制、高可用、分布式
目录 简介 持久化 主从复制 高可用 Redis-Sentinel .NET Core开发 分布式 Redis-Cluster 配置说明 常见问题 简介 本节内容基于 CentOS 7.4.1708, ...
- react脚手架改造(react/react-router/redux/eslint/karam/immutable/es6/webpack/Redux DevTools)
公司突然组织需要重新搭建一个基于node的论坛系统,前端采用react,上网找了一些脚手架,或多或少不能满足自己的需求,最终在基于YeoMan的react脚手架generator-react-webp ...
- SpringBoot日记——编码配置篇
插入一个小篇章,有人在编写代码的时候,要么控制台乱码,要么页面乱码等等, 我这里有个配置,可以解决各种乱码问题,直接来看. # ==================== 编码配置 ========== ...