c

比較演算の結果の値

C の比較演算の結果で,true の場合は 1 で false の場合は 0 っていうのが常識的な 挙動のような気がするけど,未規定とかじゃなくてちゃんと決まっているのか, 前から気になっていたのでちゃんと調べた。 素直に検索しても出なかったけど,ちゃんと規格(に近いもの)を見に行ったら 簡単に書いてあるのが見つかって,どうやら true が 1 で false が 0 になるってのは 決まってるっぽい。 つまり,以下のコードは環境に依存せずに 2 を出力する。 #include <stdio.h> int main(void) { int num = (0 == 0) + (0 == 0); printf ("%d\n", num); return 0; } あと,結果の型は int。 参考 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

C で Hello, world!

なんじゃこりゃ %:include <stdio.h> int main(void) <% char str<::> = "Hello, world!"; printf("%s\n", str); return 0; %> これが $ gcc main.c コンパイルすると $ ./a.out Hello, world 動いてしまう。 <:, :>, <%, %>, %:, %:%: の6つのトークンは, [, ], {, }, #, ## と同じように解釈されるらしい。 なんじゃそりゃ。 参照 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

new と malloc(3) を混在させていいのか

という議論が ここ にあったけど(2007 年……古い……!),malloc(3) で取ってきたメモリを delete(もしくは delete[])に渡してはいけないとか,new で取ってきた メモリを free(3) に渡してはいけないのに malloc(3) を読んだり new したり しても問題ないってのはなんか奇妙な話な気がしてきた。 (普通に C++ 書いていれば malloc には用がないけど)。 なぜかというと,どちらのメモリも malloc(3) が管理していないと, 同じ領域が別の用途で使われてしまうということになるので。 で,new で取ってきたのも malloc が管理しているんだったら, delete しても free(3) に渡されるだけだから, デストラクタとかがなければ問題にならない気がする。 と思って gdb でアタッチして試し

for と while

どうでもいいけど for 文と while 文だったら for 文を優先して使うことが多い気がする。 繰り返し系は最初に for 文の方で書いてみて,変数の初期化の部分と更新の部分が空欄になったら while に変えるみたいな。どうでもいいけど。 while 文は途中で continue とかすると変数の更新を忘れがちなので, 文法に組み込まれている for 文の方が都合が良いという理由はありそうな気がするけど 自分でもよくわからない。

PAM で遊んでみた

PAM で遊んでみた。PAM ってのは Pluggable Authentication Manager の略らしく, Linux のユーザー認証のしくみで,これの設定次第でユーザーが自由に認証の方法を変更できる。 例えばパスワード認証の代わりに指紋認証を使いたいみたいな場合もこの PAM のモジュールで実現できるはず。 当たり前だが,設定次第で認証システムを破綻(?)させることも可能で,常にログインできる PAM モジュールを使ってパスワードなしでログイン可能にしてしまったり,逆に絶対にログインできない PAM モジュールで全ユーザーを締め出したりもできてしまう。てなわけでまあ割とヤバイ部分で遊んだ。 PAM のモジュールを書くのはとても簡単な部類で,常にログインできるやつとかだと下みたいなコードで できたり

プログラミング演習の愚痴

for 文のことを書いていたらなんか昨日の割と頭に来たやつを思い出してしまったので。 大学でプログラミング演習ってのがあって,まあ学部1年の演習なんでプログラミングの経験がある人にとっては 簡単すぎる内容ばかりなんですが,まあそれは仕方ないと思って諦めてます。 で,他の大学はどうか知らないんですが,このプログラミング演習は最初に5問くらい問題を与えられて, 解けたらティーチングアシスタント(TA)にチェックしてもらう,終わったら帰っていい, みたいなシステムになっていて,たぶんプログラミングの経験がある人はすぐ終わって すぐ帰ってるんじゃないかと。気にしてないので知らんけど。 で,昨日の問題に再帰で書けってのがあ

for 文について

こんな話,Web に無限に記事が転がっててソースコードも無限にある気がするので, ここで僕が書いても完全に無駄な気がするけど,書いてみることにした。 C とかそのシンタックスの影響を受けた言語では共通のシンタックスとして,for 文ってのがある。 どういうシンタックスかというと,こんなこと今更書いても無駄な気がするけど, for (初期化; 継続条件; カウンタを更新) { なんか実行したい処理(); ... } みたいな感じで,ミニマルな例としては, for (int i = 0; i < 5; ++i) puts("Hello, world!"); みたいなものになると思う。 ところでこれ,ループカウンタを使わない場合でも便利な場合があるってのが今回書きたいことで, なんか怪しい入門の本とか記事みたいなのでは触

C言語使っていると「すげえ」ってなるC++の機能

今まで C 言語ばっかり使ってきて、C++ を使ったときに驚いた機能です。 比較的新しい言語仕様もあるっぽいので、処理系によってはサポートしていないかもしれません。 auto auto キーワードを使うと型推論してくれます。 例えば、 #include <iostream> auto plus(auto a, auto b) { return a + b; } int main() { std::cout << plus(1.2, 3.4) << std::endl; return 0; } こういうのが $ ./a.out 4.6 コンパイルも通ってちゃんと動きます。 で、こういう auto を float と宣言すればいいだけ、みたいなやつだけじゃなく、 以下のような変なやつも #include <iostream>#include <complex> auto plus(auto a, auto b) { return a + b; } int main() { std::cout << plus(1.2, 3.4) << std::endl; std::cout << plus(std::complex<int>(1, 3), std::complex<int>(5, 7)) << std::endl; return 0; } $ ./a.out 4.6 (6,10) ちゃんとコンパイルが通って動きます。怖い怖い!! (大袈裟) ラムダ式 C 言語ではある処理単位を引数として渡したい場合、 グローバルに

Ubuntu で freeglut を使う

環境は Ubuntu 18.04.3 LTS x86_64 です. 必要なパッケージを入れる $ sudo apt install freeglut3-dev 試す なんか適当に #include <stdlib.h>#include <GL/glut.h>#include <GL/gl.h>#include <GL/glu.h> static void display(void) { glClear(GL_COLOR_BUFFER_BIT); glFlush(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(256,256); glutCreateWindow("Hello"); glClearColor(1, 0, 0, 1); glutDisplayFunc(display); glutMainLoop(); return 0; } 256x256 のウィンドウを赤く塗りつぶすだけです. で,コンパイル $ gcc main.c -lglut -lGLU -lGL -lm できました. 適当に Makefile にしておく ライブラリが多くて毎回指定するのは面倒なので, Makefile 必須っぽいです. LDFLAGS = -lglut -lGLU -GL -lm .PHONY: all all: main.o $(CC) main.o $(LDFLAGS) Man よこせ $ sudo apt install opengl-4-man-doc で入るみたいです.でも見た感じ, gl で始まる関数しかないっぽい. まあパッケージ名から想像がつくけど. glut とか glu とかの man の入手の仕方を教えてください. さいごに Windows でやる方がめんどくさいな,という印象ですね.まあ NuGet を使えば一発で入ることは入るんですが. でもあれはプロジェク