June 25th, 2021
プログラミング完全初学者向けというより、 他のプログラミング言語を何かしら習得している事を前提に進めていきます。m(._.)m
ほうほう、これは学んでおきたい 🦉
以下の環境で開発を進めてみました。
// printf関数を利用するために最初に呼び出しておく header ファイル。
// 他にも色々なライブラリが標準で備わっている。
#include <stdio.h>
// main関数はプログラムのエントリポイント
// この中に処理を書いていく。
int main()
{
printf("こんにちは。私の名前は%sです。 \n年齢は%d歳", "Cゲンガー", 23);
return 0; // プログラム正常終了の合図
}
こんにちは。私の名前はCゲンガーです。
年齢は23歳です。
第一引数に記載されたformat specifier(フォーマット指定子)を元に第二引数以降の値が挿入される。
上記のコードでは
%s
に Cゲンガー
が割り当てられ、%d
に 23
が割り当てられるっと。これは、プログラムが正常に終了したことを表すものです。
以下のような2つのコードがあるとして、コンパイル後にターミナルでコマンドを打ってみました。
#include <stdio.h>
int main() {
printf("Hello World ! ")
return 0;
}
% ls
hello.c hello
% ./hello && echo "Hi !"
出力結果
Hello World ! Hi!
#include <stdio.h>
int main() {
printf("Hello World ! ")
return 1;
}
% ls
hello.c hello
% ./hello && echo "Hi !"
出力結果
Hello World !
&& は コマンド1 && コマンド2
のような時、
コマンド1が成功した時に、コマンド2を実行する。
なので、プログラムが正常に終了したことを表すためには基本的には return 0;
を最後に書く必要があります。
が、C99という1999年に策定されたC言語の規格以降では return 0;
の記述が無くても動作します。
書式 | 説明 |
---|---|
%d | 整数値10進数 |
%f | 実数値10進数(単精度実数) |
%lf | 実数値10進数 (倍精度実数) |
%c | 文字。ASCII(アスキー)コードで表示された文字を表示する。シングルクォートで囲う。 |
%s | 文字列を表示する。ダブルクォートで囲う。 |
詳しくは以下を参照
データ型 | 意味 | 説明 | サイズ |
---|---|---|---|
char | 整数型(文字列) | 1byteの符号付整数。ASCIIコードという文字コードに使用 | 8bit |
int | 整数型 | 2または4byteの整数(コンパイラに依存する) | 16bit |
float | 浮動小数点型 | 4byteの単精度浮動小数点実数 | 32bit |
double | 浮動小数点型 | 8byteの倍精度浮動小数点実数 | 64bit |
符号付整数型
0と正負の数を表現できる整数型。 先頭が値の正負を表す符号ビットがある。(0が正/1が負)
単精度浮動小数点実数
有効桁数の少ない小数点を格納できる型
倍精度不動小数点実数
有効桁数の多い小数点を格納できる型
通常の文字列では表せない文字や機能を表現したもの
特殊文字 | 意味 |
---|---|
\a | 警告音 |
\b | バックスペース |
\n | 改行 |
\t | タブ |
\\ | 文字としての\ |
\? | 文字としての? |
\" | ダブルクォーテーション |
\' | シングルクォーテーション |
\0 | null文字 |
変数宣言する際には型を指定して変数は最初に全て定義しておかないといけない。 と言われていますがC99からブロックの途中でも変数宣言ができるようになってます。
#include <stdio.h>
int main()
{
int a = 10;
int b;
b = 5; // 初期化は後からでもOK
add = a + b;
sub = a - b;
printf("%d + %d = %d\n", a, b, add);
printf("%d - %d = %d\n", a, b, sub);
}
10 + 5 = 15
10 - 5 = 5
#include <stdio.h>
int main() {
int d[5]; // size5の配列変数の宣言 ( 配列の5番目という意味ではない! )
int i;
// 配列の番号を指定し、値を格納している。
// このように後から初期化することが可能です。
d[0] = 1;
d[1] = 2;
d[2] = 3;
for (i = 0; i < 3; i++) {
printf("%d ", d[i]);
}
printf("\n");
}
1 2 3
配列のsize宣言なしで初期化することも可能です。
その場合は、自動的にsizeが決まります。
#include <stdio.h>
int main() {
int n[] = { 1, 2, 3, 4, 5 };
int i;
for(i = 0; i < 5; i++) {
printf("n[%d] は %d\n", i, n[i]);
}
}
n[0] は 1
n[1] は 2
n[2] は 3
n[3] は 4
n[4] は 5
文字の配列の場合は数値と扱い方が少し異なります。
文字の配列の場合は配列の最後の要素に '\0' が格納されます。
そしてこの文字の配列こそが、文字列になります。
とりあえず、見ていきすしょう。🤔
#include <stdio.h>
int main() {
// 文字の配列では、どこで終わりにするかを '\0' で表す必要がある。
char string1[4] = { 'a', 'b', 'c', '\0' };
// 0 ~ 11には右辺の各文字が格納されており、
// 12個目の文字には要素の終わりを表す '\0' が格納されている.
char string2[] = "Hello World!";
// 最大6文字まで入る文字列(= 最後に'\0'が入るので5文字指定できる)
char string3[6];
printf("string1 は %s\n", string1);
printf("string2 は %s\n", string2);
}
string1 は abc
string2 は Hello World!
出力結果の abc と Hello World! から分かるように文字の配列が文字列として標準出力されました。
C言語において文字列というのは文字の配列のことだったのです。。。🤔
変数が初期化された後の行でbreak pointを指定。(赤丸のやつ)
VScodeのコマンドパレットから Task: Run build task
を実行して確認してみました。
実際にあった。
文字列は文字の配列であり、その最後には \0
というものが格納されているというのがポイントでした ! 🤯
scanfはキーボードからの入力を受け取り、変数にその入力を格納する関数。
scanf は引数に以下の2つの値を指定する必要があります。
メモリのアドレスを取得するにはアンパサンド &
を利用します。(Cでは配列名自体がポインタとなるので、配列の場合は&は不要になる。)
#include <stdio.h>
int main() {
// 変数定義
// この時、ageのメモリアドレスが決まる。
int age;
printf("君おいくつ?");
scanf("%d", &age);
printf("%d 歳っ!🤓\n", age);
}
しかし注意が必要なのは、値の格納先が配列の場合は &
は不要なケースがあります。
それが配列です。
#include <stdio.h>
int main() {
char input[100];
printf("あなたの名前は?\n");
// 配列名は先頭要素を示す様に暗黙的に型変換されています。
scanf("%s", input);
printf("%sです!\n", input);
}
Cゲンガー // 入力した値
Cゲンガーです!
各要素の値を設定する場合は明示的にアドレスを指定する必要があるので、アンパサンド & が必要となります。
#include <stdio.h>
int main() {
char input[2];
printf("一文字入力雨してください\n");
// 配列の1番目の要素に文字を格納する。
scanf("%c", &input[0]);
printf("入力した文字は。。。%cです!\n", input[0]);
}
C // ← 入力した値
入力した文字は。。。Cです!
#include <stdio.h>
int main() {
int a = 11;
int b = 5;
int c;
c = a + b;
printf("addtion: %d \n", c);
c = a - b;
printf("subtraction: %d \n", c);
c = a * b;
printf("multiplication: %d \n", c);
c = a / b;
printf("division: %d \n", c);
c = a % b;
printf("modulus division: %d \n", c);
return 0;
}
addtion: 16
subtraction: 6
multiplication: 55
division: 2
modulus division: 1
演算子の優先順位に基づいて数値式を評価していきます。 +と-は、*、/、%と同様に、同じ優先順位です。 式の左から右の順に *, /, % が実行され、次に + と - が同じく左から右の順に評価されていきます。 演算の順序を変えるには、どの演算を先に実行するかを括弧( )で囲みます。 たとえば、「2 + 3 * 2」の結果は 8、「(2 + 3) * 2」の結果は「10」です。 この辺は説明しなくても算数と一緒ですし、他のプログラミング言語触ってたら知ってるはずですね〜。
ただ実際に以下の様な場合は結合法則が不規則になる可能性があります。(計算結果は同じ)
a * b * c
// 以下のどちらで評価されるか分かりませんが、計算結果は同じです。
// (a * b) * c
// a * (b * c)
int型とfloat型で計算した時には、計算結果はfloat型に変換されます。
#include <stdio.h>
int main() {
float tax_rate = 1.1;
int price = 100;
float billing_price;
billing_price = tax_rate * price;
printf("Billing Price: %f", billing_price);
return 0;
}
Billing Price: 110.000000
強制的に型変換するには type cast
します。
(変換したい型) 対象(値、変数、式など)
以下は、int型をfloat型に型変換した例です。
#include <stdio.h>
int main() {
int a = 10;
int b = 3;
float average;
average = (float) 10 / 3;
printf("%f", average);
// 3.333333
return 0;
}
int型の変数xに対しての各処理です。
int x = 3;
x += 1; // x の値は 4
x -= 1; // x の値は 2
x *= 2; // x の値は 6
x /= 2; // x の値は 1
x %= 2; // x の値は 1
x += 3 * 2; // x の値は 9
int x = 3;
- ++x(またはx++); // x の値は 4
- --x(またはx--); // x の値は 2
increment, decrementを先頭に付けるか、末尾に付けるかで実は意味が変わってきます。
++x
xに1プラスして、xの値を返す。
x++
xの値を返して、xに1プラスする。
--x
xに1マイナスして、xの値を返す。
x--
xの値を返して、xに1マイナスする。
例)
#include <stdio.h>
int main() {
int a = 1, b = 3;
// 5が表示されて、
// その後に、aが2になる。
printf("%d\n", a++);
// bが4になって、
// その後、bが表示される。
printf("%d\n", ++b);
return 0;
}
左から右に実行されているのに注意しなきゃいけないですね!🤯
ちなみに、increment, decrementの演算子がある他の言語でもこの様な挙動をします。(JavaとかJavaScriptとか) そもそも、increment, decrementがないプログラミング言語もあります。(Rubyとか)
『printf 書式 値』で出力することができました。
printf("%d", 100)
printf関数にはオプションがあります。
数値の出力幅を5に指定しています。 数値の桁数が指定した幅数より小さい時には左に空欄が挿入されます。
例)
#include <stdio.h>
int main() {
printf("%5d\n", 1);
// 1
// ↑ 4つ分spaceが入っている。
printf("%5d\n", 55555);
//55555
// ↑ スペース無し。(指定幅以上の数値の場合はspaceは無視される。)
printf("%2d\n", 7);
// 7
// ↑ 1つ分spaceが入っている。
}
浮動小数点数の小数点以下の桁数を設定します。(省略時は小数点以下6桁)
桁数を表すには .10進数整数
を指定します。
例)
// %.2 は小数点以下の桁数は 2 なので 1.11
// 1.11 で 4つ分の長さ
// widthが10なので、6つ分spaceが足されます。
printf("%10.2f\n", 1.1111111111);
// 1.11
// ↑ 6つ分spaceが入っている。
// %.2 は小数点以下の桁数は 2 なので 1.11
// 1.11 で 4つ分の幅
// 既に指定幅 3 以上あるのでspaceは無視。
printf("%3.2f\n", 1.1111111111);
//1.11
printf関数のオプションは他にもいくつかありますので興味があれば調べてみましょう〜
ということで一応まとめてみました。