以前用过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. ubuntu 默认 进入 命令行

    图形模式下,首先进入终端:1. 运行 sudo vi/etc/default/grub2. 找到 GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash”3.改为 GRUB_ ...

  2. php去除数组中重复数据

    <?php /** * 去除数组中重复数据 * by www.jbxue.com **/ $input = array("a" => "green" ...

  3. AOJ-2249 Road Construction(最短路)

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=45523 有一个国王想在首都与各个城市之间修建公路,但是他的预算太高,所以必须 ...

  4. Java 数据类型转换

    int iValue = new Integer(strValue).intValue();String str = intObj.toString();int number = Integer.pa ...

  5. Jenkins+Maven+Git搭建持续集成和自动化部署的配置手记

    前言    持续集成这个概念已经成为软件开发的主流,可以更频繁的进行测试,尽早发现问题并提示.自动化部署就更不用说了,可以加快部署速度,并可以有效减少人为操作的失误.之前一直没有把这个做起来,最近的新 ...

  6. JAVA反射技术的使用

    前言 在开发html使用jquery提交post的时候,可以使用jquery遍历from元素里面的input元素实现参数组合,这样就不用手动打参数了,特别是在参数很多的时候,费神费时. 我开发Andr ...

  7. WinCE5.0中文模拟器SDK(VS2005)的配置

    WinCE5.0中文模拟器SDK的安装过程不细说了,一路默认即可,下面主要介绍如何配置,使其能在VS2005中正常使用. 安装完成后,打开VS2005,点击菜单“工具”——“选项”——“设备工具”—— ...

  8. System.Linq.Dynamic 和Nhibernate

    var session = NHibernateSessionManager.Instance.GetSession(); "); var staffList = session.Query ...

  9. 浅谈网络爬虫爬js动态加载网页(三)

    上一篇讨论了web driver对动态网页的抓取与分析,可以很清楚的看出这是一种集中式处理方式,简单说,就是利用服务器,打开一个真正的brower,然后将需要解析的地址交给浏览器,浏览器去解析,然后将 ...

  10. C++获取进程号及窗口

    #include <TlHelp32.h> //根据进程名获取进程ID BOOL GetPidByProcessName(TCHAR *pProcess, DWORD*dwPid) { H ...