【要回答】出席票フォーム (授業内容に関する課題もあります)
講義資料(PDF)
【講義3】で使ったコード一覧
[Wandbox] https://wandbox.org/permlink/uD9Rkis2vlMelgAo
使い方
まず「コピーして編集」をクリック
「実行」をクリックすると、一番左の📃タブに書いたコードが実行される
各コードのタブからコードを一番左の📃タブのコードエリアにコピー&ペーストして使う
前回の課題:資料P31以外で、typedefや#defineを使った一工夫を考えよ。どのような "良いこと" があるかも示せ。
の皆さんの解答
#define print(i) printf("%d\n", i) と書くと、数値1つを出力したい場合楽に書くことができる。(求められる出力の形に応じて適宜変更を加えることもできる)
#define all(x) x.begin(), x.end() コンテナの開始と終了イテレータを簡潔に指定できる(sort(all(v))など)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP0(n) for (int i = 0; i < n; i++)
#define REP1(i, n) for (int i = 0; i < n; i++)
#define REP2(i, l, r) for (int i = l; i < r; i++)
#define REP3(i, l, r, d) for (int i = l; i < r; i += d)
#define REP(...) OVERLOAD_REP(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
OVERLOAD_REPによって引数が1つから4つまでに対応し、よく使うfor文のパターンを全て短縮して書くことができ、速くて楽であるため、競技プログラミングで特に使いやすい。
#define SWAP(x, y) ((x != y) & (x = x + y, y = x - y, x = x - y))
2つの値x,yを交換するためには毎回数行のコードを書く必要があるが、マクロSWAPを定義しておくことで1行で済む様になる上にコードの可読性が上がる。
#define PRT_INT(a) printf("%d\n", a)
printf("%d\n", a) と書くのに時間がかかるが、マクロPRT_INTを定義しておくことで少し速く書く事ができる。
# typedef unsigned long long ull
unsigned long long と書くには非常に時間がかかるが、型 ull を定義しておくことで速く書く事ができる。
#define print(a) printf(“%d/n”,a)
一回一回printf(“%d/n”,a)と書くのはshiftの押す押さないが混乱したり単純に面倒だがprint(a)なら楽
#define PR(a) printf("%d",a) プリントをいちいち入力するのが面倒であるためにそれを省略するため
#define IN_INT(x) scanf("%d", &x) 入力の受け取りはよく使うが,記号が多いと打ち込むのが大変なので,それを少し簡単にすることができる。
#define DEBUG 1/#define DEBUG 0
電子工作などでデバッグする際(センサーの値をモニターに出力するなど)にmain関数の中でif(DEBUG)として書いておくとラク。
#define scan(a) scanf("%d",&a) 整数型のscanf関数を省略できるから楽である。
#define dbl double
#define EL "\n" 改行コードを打つのがめんどくさいので、ELと打てば良いようにしている。
#define print_int(x) printf("%d\n", (x)) 数値を出力するときにフォーマットを指定するのが面倒なのでこれを使って楽したい
#define flt float
#define SIZE;
配列の要素数に毎回10000など具体的な数字を入力しなくて済むため楽。また、配列の要素数を変更したい時、SIZEの値さえ変更すれば全ての配列の要素数を変更できて楽。
#define TOP 0; VSCodeでコードの一番上を覗き見たい時に、TOPと書いてCtrlを押しながらクリックするとコードの一番上を確認できる(Ctrl + Zで元の位置に戻る&TOPを消す)。
typedef struct customer{
double gender;
double item;
}
などとすることで、顧客情報を専用の型で管理することができる。
#define print(d) printf("%d\n", d)
これでprt(100)など出力したい整数値をdに代入すれば簡単に出力することができ、かつ改行もできて楽になる。
#define MAX(a,b) ((a) > (b) ? (a) : (b))とすると、MAX(a,b)とするだけで、2つの値aとbを比較して、大きい方の値を返すことができて楽である。
複数の変数を連続して定義する場合、typedefは定義されたすべての変数が同じ型であることを保証するが、#defineはそれができない。例えば:
#define PTR_INT int *
PTR_INT p1, p2; //p1、p2 の型が違う,int *p1, とp2;
typedef int * PTR_INT
PTR_INT p1, p2; //p1、p2 の型が同じ,全部ポインタである。
#define sq(n) n*n
与えられた数値の二乗を返す。
二乗する変数名が長い時に、それを2度書く手間が省け、文章も短くなり見やすくなる。
#define LENGTH(array) (sizeof(array))/sizeof(array[0]); 配列の要素数を求めるプログラムを速く楽に書くことができる。
#define TRUE 1; #define FALSE 0; 真偽値かただの数値かをわかりやすくできる。
typedef struct npol{
double r;
double th;
}npol;
実数の極座標表示を扱う際に用いられる。
図形の面積や体積の公式を、#defineを用いて表すことで複数回使う際に短いプログラムですむ。例えば#define PI 3.14、#define volumeofcorn(radius,height) radius*radius*PI*height/3など。
typedef printArray(array, num) for (int i = 0; i < num; i++) {printf("%d ", i, array[i]);} printf("\n"); よく使う出力方法なので、タイピング量を減らせる他、タイプミスもなくせるため嬉しい。
#define PI 3.14159265358979
#define CIRCLE_AREA(r) (PI * r * r); 面積を求める計算などで公式が複数回登場するとき、これをマクロ化することで記述を簡略化し、かつ可読性の向上が見込める。
#define swap(x, y) {auto temp = x; x = y; y = temp; } ; ソートなどで頻繁に行われる文字の入れ替えが見やすくなる。
#define mod 998244353; 割った余りを出力する時、法としてしばしば998244353を用いるがいちいち書くのは面倒であり、modの方が楽である。
#define swap(x, y) { auto temp = x; x = y; y = temp; }; こうすることで、ソートなどで頻繁に行われる文字の入れ替えを見やすくすることが可能になる。
typedef struct {
int x;
int y;
} Point;
Point p1 = {10, 20};
=> struct Pointではなく、Pointと簡潔に記述できるようになるから、コードが読みやすくなる。
#define PI 3.14159
double circumference = 2 * PI * radius;
=> PIを定義することで、プログラム全体で定数を使う場合にタイポを防げるし、値を変更する際に一箇所だけ修正すれば良い。
#define DEBUG #ifdef DEBUG~#endifなどと組み合わせることで、デバッグ用のprint関数などのONOFFを切り替えられるようになる。
#define PB push_back
#define MP make_pair
vectorで後ろに要素を追加するときにv.PB(a)と書くことができ、pairを作るときにp=MP(a,b)と書くことができるため楽。
#define REP3(i, m, n) for(ll i = (m); i < (n); ++i)
#define helth 100と宣言して、int length[helth]などと宣言する方法。
配列のサイズに直接数字を入れると自分以外の人が見たときになぜその数字なのかわからない場合があるので、配列のサイズに意味がある場合などにそれを事前に宣言しておき、用いることで読みやすくなる。
0, 1などのフラグ数字に意味の入ってる名前を付けることができる。(#define MY_FALSE 0)
#define min(a, b) ((a) < (b) ? (a) : (b))
min関数の代わりになる。関数を作る場合は引数の型が限られるが、こちらは幅が広い
#define TRUE (1)
#define FALSE (0)
;C言語は数値で真偽値を表すが、この定義によりTRUEとFALSEで真偽値を表すことができ、コードが読みやすくなる。
#define pf(i) printf("%d\n") printfと書く時間を省くことができる
typedef int16_t i16; 標準ライブラリの型に別の短い名前を付け、書くのを楽にする。
typedef unsigned int uint; と書けば、符号なし整数を一文字で定義出来て楽
まず構造体を使うことで関連のあるデータをまとめることができる コードの見通しがよくなり、無関係な値を変更してしまうリスクを減らすことができる。そして、typedef 指定子を使うと、わかりやすい型名を自由に付けることができる。その為、プログラムの可読性が向上する。その他にも、ソフトを移植する時に修正する箇所がtypedf宣言の部分に限定できる。
typedef char* string; char*をstring型のように扱えて文字列の操作が便利になる。
typedef int *PINT;
int *p1, *p2; と書かずに、「intを指すポインタ」のp1 と p2 を作成できる。
typedef struct _List_ {メンバの定義など} *List, ListObj; のように宣言すると、その後にListの処理を実装する際、(List)malloc(sizeof(ListObj))のように書けて、処理の意図が分かりやすくなって良い。
#define newline printf("\n")
newline;の一言で改行できるようにすることで、改行を出力する際に簡略化して速く書くことができるようにする。
typedef struct pokemon{
char name[5];
int atk;
int def;
}pk; 構造体をpkと簡略表記できる
#define CUBE(x) (x*x*x); 三乗を引数一個で行える
#define SQUARE(x) ((x) * (x)) マクロ関数の定義に有効
mathライブラリのpow等を使わずに表現可能
#define Hello printf("Hello World!\n")
デバックしているときにとある部分のプログラムが実行されているかを確認するために、僕はprintf("Hello World!\n")を入れがちなのでhello;だけで記述できるようにした。
#define x *; 変数xを用いない限りでは、掛け算演算子としてxを入力して良い。*を入力するにはシフトキーを同時に押さなければならないが、xであれば単押しで良いので楽。
#define flaot floatとすると、僕がよくやってしまうfloat をflaotとタイプミスしてしまいエラーが出てしまうのを防ぐことができる。
#define LENGTHとして、配列を作成する際の長さとして代入すると、配列長が足りなくなった際に簡単に足すことができる。
#define SWAP(x,y) {typeof(x) temp=(x); (x)=(y); (y)=temp;} 大小比較やソートなどでよく使用する値の入れ替え関数をすぐに実装できる。
配列のサイズにおいて、#define SIZE 1000とした上で、array[SIZE]のようにすれば、配列のサイズをまとめて変更したいときに、配列一つ一つの数字を訂正する必要がなく、便利である。
typedef unsigned int ui; unsigned intと書くのが面倒で時間がかかるためuiで早く楽にかける。
#define address(a) &a &の表す意味について考えなくても関数名を見れば一目でわかる。
#define Cubed(x) ((x) * (x) * (x)); 簡単な関数を定義することで簡単に3乗を使うことができ、コードも読みやすくなる。
#define PRINT(n) printf("%d",n)
デバッグなどで気になる数値の値を出力させるのが楽になる。
typedef pair<int,int> P; <と>を使わないのでタイピングが楽になる。
#define pf printf; printfと書くのが面倒で時間がかかるがpfなら早く楽。
define uli unsigned long int 全探索でビット演算をを使うときに複数回の宣言を早く行うことができる。
#define pr() printf() ;自身の想定通りの計算結果が出なかった際の式途中の変数の値を確認する時に、たくさんprintfと書く労力を減らすことが出来る。
#define SORT(v, n) bubble_sort(v, n)
SORTと書くことでコードが何をしているかわかりやすくなる。また複数回ソートを行う場合コードを簡略化出来る。また例えばバブルソートからクイックソートや他のソートアルゴリズムに変更したいときにマクロ定義を変更するだけでよくなる。
typedef unsigned int uint; 単純にかなりの文字数を省略できる上、stdint.hでの整数型(uintN_tのような形)に近い形であるため、読みやすくなる。
例えば、配列の要素の入力が1000個までの際に、ただ単にint a[1000];のようにして配列を宣言するのではなく、#define LIMIT 1000; int a[LIMIT]; などと定義することで、マジックナンバーが減り、他者から見たコードの可読性が向上する。また、同じ大きさの配列を複数用意する際、急遽配列の大きさを変える必要が出てきた場合、#defineで定義した値を変えるだけで全ての値が更新されるので便利である。
#define IVLA(i) (int *)malloc(sizeof(int) * i);
c90環境では可変長配列を作るときにメモリのアロケーションを行う必要があったのでかなり簡略化できると思った。(int型を考えている)