と、勝手に呼んでみた。「魔法の C プログラミング演習書」。C 言語初心者の自分には、すごく面白い。よい意味で、懇切丁寧に説明されていない。なので、イヤでも手を動かさなければならない。
- 作者: 倉光君郎
- 出版社/メーカー: コロナ社
- 発売日: 2016/12/09
- メディア: 単行本
- この商品を含むブログ (2件) を見る
柴田氏の「新・明解 C 言語」シリーズとは、真逆のコンセプトのように思う。柴田氏の著書は、図が多く、解説も丁寧で、非常にわかりやすい(実際、お世話になっている)。まさに、正統派。
ちなみに、MMGames 氏の「苦しんで覚えるC言語(通称、苦 C)」が、とても面白かった。ムダを省いた、凝縮された情報により、短時間で C 言語の基本が身につくようになっている。自分は、この「苦 C」で入門した。「苦しんで覚える」とあるが、むしろ、楽しく読めた。
あ、入社 1 年目のときに「K&R」と「UNIXネットワークプログラミング入門」は読んでた。なので、本当の入門は、このときかもしれない。もっとも、はるか昔なので、ほとんど覚えていないが。
で、「難しい」って言いたくないけど、C 言語って、難しいのね。
環境は、相変わらず、Windows 10 上の、Visual Studio Community 2017。空のプロジェクトを作成して、拡張子が c のファイルを追加すると、それっぽくなる。「C やってるな」って感じに。
で、[Ctrl]+[F5] で実行する。何も設定せずにプログラムを実行すると、コマンドプロンプトが起動するものの、実行完了時に終了してしまい、標準出力などが観られない。そこで、プロジェクトのプロパティから「リンカー > システム」で、サブシステムを「コンソール (/SUBSYSTEM:CONSOLE)」にしてあげるとよい。
リアルタイムにコンパイルエラーを教えてもらえるし、デバッグも簡単に出来るし、統合開発環境バンザイである。
2017/04/30 早速追記「4.3 void ポインタ」
こんなことができるんだ。
自分の環境では、テキストの「char temp[len];」の部分が、コンパイルできなかったので、変更した。
#include <stdio.h> #include <stdlib.h> void swap(void *a, void *b, size_t len) { void *tmp; tmp = calloc(1, len); if (tmp == NULL) return; memcpy(tmp, a, len); memcpy(a, b, len); memcpy(b, tmp, len); free(tmp); return; } void test_swap_double(void) { double x = 123.45, y = 67.89; swap(&x, &y, sizeof(x)); printf("x = %6.2f, y = %6.2f\r\n", x, y); }
2017/06/10 追記「4.4 関数ポインタ」
関数ポインタは、本当にいけてる。さくっと書いてみる(問題読み間違えてたから修正した)。
#include <stdio.h> void print(char chrs[], int size) { for (int i = 0; i < size; i++) { printf("%c ", chrs[i]); } printf("\r\n"); } int digit2X(char chr) { if ('0' <= chr && chr <= '9') { return 'X'; } else { return chr; } } void apply(char chrs[], int (*func)(int)) { for (int i = 0; i < strlen(chrs); i++) { chrs[i] = func(chrs[i]); } } void main(void) { char chrs[] = { 'A', '1', 'B', '2', 'C', '3' }; int size = 6; print(chrs, size); int (*func)(int) = digit2X; apply(chrs, func); print(chrs, size); return; }
2017/07/08 追記「5.2 不変性」
まぁこれは、こんなもんだろうね。キャストすると、不変性が「引き剥がされて」しまうあたりが、C っぽい。
#include<stdio.h> typedef struct { int x, y; } point; void print_point(point const *p) { printf("ADDRESS: %p, ", p); printf("VALUE X: %d, ", p->x); printf("VALUE Y: %d\n", p->y); return; } void main() { point const P = {13, 17}; point const *Q = &P; print_point(Q); /* * Q->x = 12; Q->y = 16; ⇒ コンパイルエラー * 「式は変更可能な左辺値である必要があります」 */ return; }