2017年04月08日22時26分09秒に更新されたバージョンを表示しています.
最新のページはこちらをご覧ください.


cLay概要(version 20170408-3)

概要

C++っぽい言語をC++言語に変換します.
無駄にライブラリを張るのがめんどくさい,鬱陶しい,ライブラリを整備していても綺麗に書けない処理があるなどを解消したいというのが目的.目的の達成はそのうち….
blogにコード載せる時にライブラリとかincludeとかが長ったらしい,のをなんとかしたいというのも動機の1つです.

#include<bits/stdc++.h>およびgetchar_unlocked,putchar_unlockedなどを使用しているので,それが動かない環境だと動かないし,動かないコードが出てきます.
(その場合は,フラグの欄を見て下さい)

コードはこちら(最新版はこちら).C++っぽいコードを標準入力から食わせるとC++のコードが標準出力から出てきます.

未対応なもの

重要度が高い順に,下線付き太字太字,普通です.重要度が低いものはそもそも対応させる気がないものが多いです.
この欄ではC++ではできるけど…というもの主にリストアップ.

制限

以下の単語は変数名などで使うとやばい.
基本的にバージョンアップするときは互換性を保ちたいけど,此処の欄は普通に増やす.

chmax, chmin,
rd, reader,
wt, wtLn, wtSp, wt_L, writer, writerLn, writerSp,
int_inf, ll_inf, double_inf

色々

最初に

#include<bits/stdc++.h>
using namespace std;

が強制的に挿入されます.
#includeを書く必要はないですが,GCC以外で動かなくなる.

int main()は省略可能です.
いきなり関数の中じゃなくて{で始まるブロックが最初に出てきたときにint main()が補われます.
int main()で補われたブロック内の最後がreturn文でない場合は,return 0;が最後に補われます.

フラグ

途中で(プログラムの先頭が推奨)
//hogehoge
という形式でフラグを立てておくと色々な環境に対応させるために出力されるコードが変更されます.

llはlong longに,ullはunsigned long longに置き換えられます.

入出力

rd(i, j, k)で標準入力からi,j,kが読み込まれます.scanf("%d%d%d",&i,&j,&k);などと似た感じですが,スペース区切りじゃなく,数字以外で区切られます.
rd(i, j(n), k)はrd(i, j[0], j[1], ..., j[n-1], k)に置き換わります(左から処理するのでrd(n, A(n))とか可能です).
また,rd(N, (A,B)(N)) は rd(N, A[0], B[0], A[1], B[1], ..., A[N-1], B[N-1]) に置き換わります.グラフのエッジの入力とかに.
rdの代わりにreaderでもOK.
rdは今のところint型,ll型,char型の配列(文字列)にのみに対応.他の型もそのうち対応

wt(i, j, k)でスペース区切りでi, j, kを標準出力に吐き出し,改行します.
wt(i, j(n), k)はwt(i, j[0], j[1], ..., j[n-1], k)に置き換わります.
また,wt(N, (A,B)(N)) は wt(N, A[0], B[0], A[1], B[1], ..., A[N-1], B[N-1]) に置き換わります.式の一部がこの形でも同様に置き換わります(以下の例を参照).
最後に改行する代わりにスペースを出力する場合はwtの代わりにwtSpを,改行区切りで出力する場合はwtLnを使います.
wtの代わりにwriter,wtSpの代わりにwriterSp,wtLnの代わりにwriterLnでもOK.
wtは今のところint型,ll型,char型の配列(文字列)のみに対応.他の型もそのうち対応

また,出力に関してオプションで B=n と指定すると整数系のものは n 進数で出力されます.
例えば,wt[B=3]("hello", 10); は hello 101 と出力されます(文字列に関しては基数は無視されます).
62進数まで指定可能で,文字は 01...9ABC...Zabc...z の順番です.

例:

int N, A[10], B[10], res[10];
rd(N, (A,B)(N));
wt(N, 2*res(N)+1);

は以下と同じ意味になります.

int i, N, A[10], B[10], res[10];
scanf("%d", &N);
for(i=0;i<N;i++) scanf("%d%d", A+i, B+i);
printf("%d ", N);
for(i=0;i<N;i++) printf("%d%c", 2*res[i]+1, i==N-1?'\n':' ');

ループ

rep(i,n)およびREP(i,n)はfor(i=0;i<n;i++)に置き換えられます.
rep(i,a,b)およびREP(i,a,b)はfor(i=a;i<b;i++)に置き換えられます.

また,括弧内((),[],{}のどれか)で2つ以上のドットで区切ると範囲を指定でき,勝手にループに展開されます.
ドットの数が等しいものが同じ変数だと思われて,同じドットの数のものは2回目以降に登場したときには区間の終わりは省略可能です.
(ドットの数が多いほうが内側のループになります.2次元配列のアクセス順で速度がかなり変わるので気をつけたほうが良い場合があります)
例えば,単位行列を作るコード,行列のコピーのコード,転置しながらコピーするコードは

int A[10][10], B[10][10], C[10][10];
A[0..9][0...9] = 0;
A[0..9][0..9] = 1;
B[0..9][0...9] = A[0..9][0...9];
C[0..9][0...9] = A[0...9][0..9];

のように書け,これは

int i, j, A[10][10], B[10][10];
for(i=0;i<=9;i++) for(j=0;j<=9;j++) A[i][j] = 0;
for(i=0;i<=9;i++) A[i][i] = 1;
for(i=0;i<=9;i++) for(j=0;j<=9;j++) B[i][j] = A[i][j];
for(i=0;i<=9;i++) for(j=0;j<=9;j++) C[i][j] = A[j][i];

と同値です(B[0..9][0...9] = A[0..9][0...9];はB[0..9][0...9] = A[0..][0...];と書くこともできます).

括弧で囲まれていなければならないことに注意して下さい.

A[0..9] = (0..9)
B[0..9] = 50 - (23..)


for(i=0;i<=9;i++) A[i] = i;
for(i=0;i<=9;i++) B[i] = 50 - (23 + i);

と同値ですが, A[0..9] = 0..9; などとは書けません.

文字列の中に2個以上ドットが並ぶとバグる実装なのでそのうちなんとかする.

演算子

昔のGCC拡張で存在した<?および>?演算子の同時に代入するバージョンのみ使えます.
つまり,a <?= b; は a = min(a, b); と,a >?= b; は a = max(a, b); と大体同じです.
代入しないバージョンは素直にminおよびmaxを使え.

定数

int_inf は 1073709056 ($2^{30}-2^{15}$) に,
ll_inf は 4611686016279904256LL ($2^{62}-2^{31}$) に,
double_inf は 1e150 に置換されます.

int_infおよびll_infはそれぞれ2倍してちょっとした数を足してもint型,long long型でオーバーフローしないという値に設定しています.
また,double_infは2乗してもオーバーフローしないという値に設定しています.

マジで置換してるだけで,int_infを部分文字列に含む何かが有ったらバグるので,それは,そのうちなんとか….

更新履歴


Current time: 2021年10月28日00時15分42秒
Last modified: 2017年04月08日22時26分09秒 (by laycrs)
Tags: no_tags
トップページに戻る

Logged in as: unknown user (not login)

ログイン: