以前用过octave, 和matlab类似的软件, 指定范围非常方便 i = 1:10:100;  就可以得到

10 20 30 ... 100

这一系列的数据, 但是在c里面, 必须手动写循环, 太不符合懒人的习惯了, 今天写了一个宏, 终于实现了, 貌似编译器没有优化, 还是在运行时获取整数的数值,不是在编译阶段, 但是无所谓了,一般这种偷懒都是在测试的时候使用, 正式代码不会用的。

代码如下:

#include <stdio.h>
#include <stdlib.h> #define FOR(i, ...) \
do{\
long i, __s__##i, __e__##i,__delta__##i;\
char *__pt__##i = #__VA_ARGS__;\
while(*__pt__##i)\
{\
if((*__pt__##i < '0' || *__pt__##i > '9') && *__pt__##i != ' ' && *__pt__##i != ',' && *__pt__##i != ':')\
{\
if(*__pt__##i != '-' || *(__pt__##i+1) < '0' || *(__pt__##i+1) > '9')\
{\
fprintf(stderr, "error of F(%s,%s)\n", #i, #__VA_ARGS__);\
exit(1);\
}\
}\
__pt__##i ++;\
}\
__pt__##i = #__VA_ARGS__;\
char *__end_ptr__##i;\
do{\
__s__##i = strtol(__pt__##i, &__end_ptr__##i, 10);\
while(*__end_ptr__##i == ' ') __end_ptr__##i++;\
if(*__end_ptr__##i == ':')\
{\
__delta__##i = strtol(__end_ptr__##i+1, &__end_ptr__##i, 10);\
while(*__end_ptr__##i == ' ') __end_ptr__##i++;\
if(*__end_ptr__##i == ':')\
__e__##i = strtol(__end_ptr__##i+1, &__end_ptr__##i, 10);\
else\
{\
__e__##i = __delta__##i;\
__delta__##i = 1;\
}\
}\
else\
{\
__e__##i = __s__##i;\
__delta__##i = 1;\
}\
for(i = __s__##i; __s__##i <= __e__##i ? i <= __e__##i: i >= __e__##i; i += __delta__##i)\
{(void)0; #define DO(...) __VA_ARGS__;
#define DONE(i) \
}\
__pt__##i = __end_ptr__##i;\
while(*__pt__##i == ' ' || *__pt__##i == ',') __pt__##i++;\
}while(*__pt__##i);\
}while(0); int main(void)
{
FOR(i, 1 2 -3 , -1:10 99:100 999 11:11, 111:3:119,1:-1:-1);
DO(
FOR(j, 88:2:91);
DO(
printf("i = %ld, j = %ld\n",i, j)
);
DONE(j);
);
DONE(i);
return 0;
}

定义变量使用##是为了防止嵌套使用时候的变量冲突。

逗号和空格可做分隔符, 冒号作为范围指定标记, a:b代表 从a到b, b必须大于a, 增量为1,包含两端, a:b:c  可以包含两端, b为增量, a < c b为正数, a>c b为负数。

范围错误获取不到数值不会报错, 但输入非法会报错,  -后面不紧跟数字会报错, 有abc等非数字字符,包括+也会报错,具体情况看代码。

使用的变量都是{}内的局部变量,对外面不会有影响。理论上和外面的变量名字冲突了也不会有影响。

测试代码

i分别取 1 2 -3 -1 0 1 2 3 4 5 6 7 8 9 10 99 100 999 11 111 114 117 1 0 -1

每一个i j分别取 88 90

FOR() DO() DONE()后面的; 可有可无,因为多余的; 编译器会兼容, gcc clang 测试都不会有警告, 如果没有; 可能vim等编辑器在对齐的时候会遇到麻烦。

编译, 执行,打印结果为预期结果。

i = 1, j = 88
i = 1, j = 90
i = 2, j = 88
i = 2, j = 90
i = -3, j = 88
i = -3, j = 90
i = -1, j = 88
i = -1, j = 90
i = 0, j = 88
i = 0, j = 90
i = 1, j = 88
i = 1, j = 90
i = 2, j = 88
i = 2, j = 90
i = 3, j = 88
i = 3, j = 90
i = 4, j = 88
i = 4, j = 90
i = 5, j = 88
i = 5, j = 90
i = 6, j = 88
i = 6, j = 90
i = 7, j = 88
i = 7, j = 90
i = 8, j = 88
i = 8, j = 90
i = 9, j = 88
i = 9, j = 90
i = 10, j = 88
i = 10, j = 90
i = 99, j = 88
i = 99, j = 90
i = 100, j = 88
i = 100, j = 90
i = 999, j = 88
i = 999, j = 90
i = 11, j = 88
i = 11, j = 90
i = 111, j = 88
i = 111, j = 90
i = 114, j = 88
i = 114, j = 90
i = 117, j = 88
i = 117, j = 90
i = 1, j = 88
i = 1, j = 90
i = 0, j = 88
i = 0, j = 90
i = -1, j = 88
i = -1, j = 90

如有错误, 欢迎更正。

本文和代码欢迎复制,但不做任何保证, 不承担任何责任,可用作商业用途,但不准拿去申请专利,对于副本也如此。

c 按范围快速指定整数的更多相关文章

  1. [原创]快速指定SQLDeveloper所使用JDK的方法

    就众多的免费SQL开发工具来讲,Oracle出品的SQLDeveloper 还是一个很不错的选择. 看到网上不少的帖子讨论SQL Developer 启动的时候报告找不到Java Home(或JDK) ...

  2. <转>快速找到整数约数集方法<python><stackoverflow>

    [背景] 我需要从N遍历到1,当我已经判断N不符合要求时,我知道N的所有约数也是不符合的,所以所有N的约数也不用遍历.因此,对于遍历的每个N,我需要快速找到它的所有约数,放到一个集合里面,而当我遍历到 ...

  3. java实验二——输出一个指定整数的所有质因数

    import java.util.Scanner; public class 实验二 { /** * @param args */ public static void main(String[] a ...

  4. IDEA中在目录中如何快速指定到当前的类

    类似于myeclipse的 Link with Editor 其实也在IDEA的这个位置,跟狙击镜的图标一样,叫做Scroll from Source 不同的的是,IDEA的这个功能,需要手动点击,才 ...

  5. 混合使用 ForkJoin, Akka, Future 实现一千万个不重复整数的排序

    定位  本文适合于想要了解新语言 Scala 以及异步并发编程框架 Akka, Future 的筒鞋. 读完本文后,将了解如何使用 ForkJoin 框架.如何使用 Akka 构建并发程序.如何使用 ...

  6. 使用matplotlib快速绘图

    matplotlib的pyplot子库提供了和matlab类似的绘图API,方便用户快速绘制2D图表.让我们先来看一个简单的例子: # -*- coding: utf-8 -*- import num ...

  7. 混合使用ForkJoin+Actor+Future实现一千万个不重复整数的排序(Scala示例)

    目标       实现一千万个不重复整数的排序,可以一次性加载到 2G 的内存里. 本文适合于想要了解新语言 Scala 并发异步编程框架 Akka, Future 的筒鞋. 读完本文后,将了解如何综 ...

  8. SpringBoot 2.X 快速掌握

    0.重写博文的原因 当初我的SpringBoot系列的知识是采用分节来写的,即:每一个知识点为一篇博文,但是:最近我霉到家了,我发现有些博文神奇般地打不开了,害我去找当初的markdown笔记,但是方 ...

  9. C语言位操作--判断两整数是否异号

    判断两整数是否异号: int x, y; //输入比较的两数 bool f = ((x ^ y) < 0); // 返回真,当且仅当x与y异号 说明:当x.y异号,x与y的最高位分别为0和1,取 ...

随机推荐

  1. Hadoop管理员的十个最佳实践

    前言 接触Hadoop有两年的时间了,期间遇到很多的问题,既有经典的NameNode和JobTracker内存溢出故障,也有HDFS存储小文件问题,既有任务调度问题,也有MapReduce性能问题.遇 ...

  2. delphi常用函数

    直接引用了 http://www.cnblogs.com/doit8791/archive/2012/05/17/2507073.html.

  3. YTU 2616: A代码完善--简易二元运算

    2616: A代码完善--简易二元运算 时间限制: 1 Sec  内存限制: 128 MB 提交: 280  解决: 187 题目描述 注:本题只需要提交填写部分的代码,请按照C++方式提交. 编写二 ...

  4. Objective-C编码规范:26个方面解决iOS开发问题

    介绍 我们制定Objective-C编码规范的原因是我们能够在我们的书,教程和初学者工具包的代码保持优雅和一致.即使我们有很多不同的作者来完成不同的书籍. 这里编码规范有可能与你看到的其他Object ...

  5. android测试常用的命令介绍

  6. leetcode:Delete Node in a Linked List

    Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...

  7. vi 每日练习

    vi 1.    4 空格 2.    ctrl + b, ctrl + f 3.     0 $ 4.    1G gg G 5.    10G 6.    10 回车 7.    / ? 8.   ...

  8. CSS 中浮动的使用

    float none 正常显示 left 左浮动 right 右浮动 clear none 允许两边浮动 left 不允许左边浮动 right 不允许右边浮动 both 不允许两边浮动 <!DO ...

  9. Ubuntu中文输入法的安装

    Ubuntu上的输入法主要有小小输入平台(支持拼音/二笔/五笔等),Fcitx,Ibus,Scim等.其中Scim和Ibus是输入法框架. 在Ubuntu的中文系统中自带了中文输入法,通过Ctrl+S ...

  10. 20160207.CCPP体系详解(0017天)

    程序片段:01.Point.c+02.进程.c+03.内存的栈和堆.c 内容概要:内存32位和64位的区别 ///01.Point.c #include <stdio.h> #includ ...