用宏实现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,进入 ...
随机推荐
- POJ 1904 King's Quest(SCC的巧妙应用,思维题!!!,经典题)
King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 10305 Accepted: 3798 Ca ...
- 使用git初始化本地仓库并提交到远程分支
创建本地文件并提交到github远程分支,步骤如下: 1.通过github创建repository,本例中repository名称为maven_demo,工程为maven + spring + myb ...
- jquery的$(document).ready()与js的window.onload区别
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- redis的使用,相比memcached
redis支持数据持久化,不像memcached断电或者重启就丢失数据了. 支持持久化主要有两种方式,在redis.conf配置文件里配置. 1. 使用.rdb格式存储,配置save参数(save N ...
- Mac 如何显示隐藏文件夹并设置快捷键
通过在终端运行命令可以控制隐藏文件是否显示: 输入defaults write com.apple.finder AppleShowAllFiles NO 就不显示, 输入defaults write ...
- Modelsim SE 和 Quartus II 编译器(综合器)的区别
当对目标模块进行RTL描述后,习惯先会用Modelsim做一下功能仿真.当我们写好Tensbench文件,直接在Modelsim SE中对源文件(design和Testbench)进行编译时,如果源文 ...
- 带Alpha通道的色彩叠加问题
css3的rgba色彩模式.png/gif图片的alpha通道.canvas的rgba色彩模式.css3的阴影.css3的opacity属性等等,这些应用在网页中,有意无意间,我们的页面多了许多半透明 ...
- 【LG3768】简单的数学题
[LG3768]简单的数学题 题面 求 \[ (\sum_{i=1}^n\sum_{j=1}^nij\text{gcd}(i,j))\text{mod}p \] 其中\(n\leq 10^{10},5 ...
- Boyer and Moore Fast majority vote algorithm(快速选举算法)
问题来来自于leetcode上的一道题目,https://leetcode.com/problems/majority-element/,大意是是找出一个数组中,出现次数超过一个半的数字,要求是O(n ...
- .Net Core 分布式微服务框架介绍 - Jimu
系列文章 .Net Core 分布式微服务框架介绍 - Jimu .Net Core 分布式微服务框架 - Jimu 添加 Swagger 支持 一.前言 近些年一直浸淫在 .Net 平台做企业应用开 ...