プログラミングに挑戦!

swift・C言語について

エスケープシーケンス〜C言語

エスケープシーケンス〜その3

前回2回にわたってエスケープシーケンスについて学んできた。今回は一応の区切りとしてエスケープシーケンスの学習を終わる。とは言っても、これで全てとは思ってないのでこれからも折に触れ学んでいきたい。

今回は文字制御について学んだ。文字色を変えたり背景色を変更したりすることについて学習した。以下に学んだことを書いてみる。

 

エスケープシーケンス〜文字制御①

文字制御と文字色

エスケープシーケンス〜文字制御②

文字制御〜背景色

これらを使ってターミナルでコードを入力してみた。以下にそれを書いておく。

エスケープシーケンスを使用したコードの一例

消去、カーソル移動、文字色の変更を入力してある。

\033[2J...画面消去

\033[r;nH...カーソルをr行n桁に移動する(上の場合1行1桁)

\033[35m... 文字色をマゼンダにする

結果は上手くいった

狙い通りの動きをしたが、2行目で自動的にデフォルトに戻っているのは不思議だ。

今回はここまで。

 

#C言語#エスケープシーケンス

 

エスケープシーケンス②~C言語

なぜエスケープシーケンスと言うのか

前回、エスケープシーケンスについて書いてきた。そもそもなぜエスケープシーケンスと言うのか。それはesc(エスケープ)から始まる文字列だからだ。
"033[2J"において、033は8進数の033のこと。16進数では0x1bとなる。これはASCIIコードのエスケープを示している。

ASCIIコード

ASCIIコード表でエスケープ(ESC)は8進数の"033"にあたる。
通常、特定の文字は特定の意味を持つが、エスケープ文字(例えば"\")を用いることでその文字を特定の意味から解放し別の意味として扱うことができる。

結局、エスケープシーケンスというのは、エスケープ文字を先頭に、特定の意味を持たせるための文字や数字の列が続く文字列のこと。

エスケープシーケンスの例

エスケープシーケンス〜特殊文字
エスケープシーケンス〜画面制御
エスケープシーケンス〜画面制御のサンプルコード

16進数も試してみた。x1b=033となる。画面消去と画面のI行目1桁への移動を書いている。

エスケープシーケンス〜画面制御のコンパイル
エスケープシーケンス〜画面制御 成功

もう少しエスケープシーケンスについて調べたい。

エスケープシーケンス〜C言語

エスケープシーケンスとは何か?

C言語の学習をしていると何だか分からない文字列の羅列に出会う。
例えば "\033[2J" というものがある。これは画面のクリアを示している。このような文字列こそがエスケープシーケンスだ。
そのほかにも"\n"というものがある。これは改行することを示している。そのほかにもあるので調べていきたい。

Hello Worldで試してみた

今まで学習してきたところで出てきたエスケープシーケンスをコードの中で見てみる。

図-1 HelloWorldのコード

まずは入門用のコードを書いてみる。
5行目の"\033[2J"は消去を表すエスケープシーケンスだ。
6行目の"\n"は改行を表すエスケープシーケンス。

コンパイルしてみると何とエラーが!
ダブルコーテーションが抜けていた。
図-1では修正してある。

結果は上手くできた。画面消去して一番上に持っていくエスケープシーケンスを取り入れていきたい。
次はエスケープシーケンスの一覧を作りたい。覚えるには手を動かすことが大切だと思う。

構造体〜c言語

構造体について

構造体とは「異なる型」のデータを一つのかたまりにすること。複数の型の変数をひとまとめにすることで、データが管理しやすくなる。テンプレートのシートを作って、そこにデータを記入することで管理しやすくなる。

構造体の概念

異なる型、例えばint型、char型、long型、double型などをひとまとめにして管理する方法。

構造体の宣言

構造体の宣言は次のように2段階で行う。また同時に行うこともできる。

①構造体テンプレートの宣言

どのような型や配列をまとめるかを宣言する

②構造体変数の宣言

構造体のテンプレートを持った変数を宣言する

構造体の一例

  • 構造体テンプレートの宣言は

struct 構造体テンプレート名 {
  型名
  型名
  型名 
  ・
  ・
  ・  
};

で行う。structは予約語で構造体を表す。(rank) はタグという。また型名を使った項目(int numberなど)はメンバという。

宣言と初期化を同時に行った例
  • 構造体変数の宣言は

struct 構造体テンプレート名 構造体変数名;
で行う。上記の場合は
struct rank list = {1, "asai", 64};
と書かれている。{}; 波カッコ内は初期化リスト。structは構造体であることを表している。rankは構造体テンプレート、listは構造体変数名である。

構造体メンバへのアクセス方法

printf("number=%d\n",list.number);
ここではprintf関数を使用している。
list.number とドット(ピリオド)を使用してアクセスする。

今回は、ここまで。

ポインタのまとめ〜C言語の初歩

ポインタのまとめ〜C言語

C言語を学習してきてポインタでつまずいた。どうにも分からなくなってしまったのだ。そこで何度も何度も読み込んで、ターミナルに打ち込んだ。そこで記号の意味を頭と手に覚えさせようとした。ある程度は納得できるようにはなった。まだ基本的なところなのだが。

ポインタを理解するための簡単なプログラム

1-1

 

5行目...ターミナル上でプログラムを実行するときに、その行よりも上を消去する

8行目...*pntでpntはポインタであることを宣言している

10行目...&numで&はnumのアドレスを示している12行目...%pはアドレス宣言子

15行目...pntはアドレスを表す

16行目...*pntはpntの中身を表す    

    

コンパイルすると以下のようになる

pntは&numと同じでnumのアドレスを示している。

*pntはnumの中身である100を示している。

アスタリスク(*)の3つの意味

  1. ポインタ宣言のアスタリスク(*)
  2. 乗算のアスタリスク(*)
  3. 中身を示すアスタリスク(*)

 

ポインタ宣言のアスタリスクは8行目で書いてある通り。単にpntがポインタであることを示している。

乗算のアスタリスクは計算式のなかで使われている。例えばa*bのように使われる。

中身を示すアスタリスクはpntの中身を示している。今回の場合は100を指している。

f:id:jimmy_ribs:20250317144533j:image

ポインタとは何なのか

  • ポインタはアドレスであると言える。そしてアドレスはアンパサンド(&)で表すことができる。1-1では&numがポインタ。
  • またポインタ宣言をするのにアスタリスク(*)を使用する。
  • そしてアスタリスク(*)には中身を指すこともある。

結局、ポインタというのはアドレスと言える。アドレス情報を扱う方法を学習していると考えている。

 

                    

ポインタの間接参照

ポインタの間接参照を使った演算

ポインタの間接参照



5行目... int型の変数 num を宣言している。初期値は10である。

6行目...ポインタ変数pを宣言している。変数numのアドレスを初期値としている。

 

8行目... printf 関数。("%d\n",  *p); で *p は6行目で示したように num を指しているので、10が出力される。

 

10行目... *p = *p +1; ここで *p に *p + 1を代入しているので8行目で示した値の10に1を加算した11となる。

13行目... printf 関数。("%d\n", *p); で10行目の演算結果を出力している。値は11となっている。これは num も同じである。

 

14行目... (*p)++; 10行目と同じ演算。書き方の違い。*p に1を加算している。結果は12になる。 num も同じ値。

15行目... printf 関数。("%d\n", *p); で14行目の演算結果を出力している。値は12。

16行目... printf 関数。("%d\n", num); numの出力。*p と同一になっていることの確認。

結果は12となり*p とnum が一致している。 

 

 *(アスタリスク) の三つの意味

  1. 乗算...掛け算を表す
  2. ポインタ宣言子...ポインタであることを表している
  3. 間接参照演算子... *p の指し示す先を表す

2.と3.の使い分けがややこしく感じる。

 

アスタリスクの使い分け

5行目... int 型の変数 b を宣言している

6行目...ポインタ変数 a を宣言し b のアドレスを渡している。

ポインタ宣言子 

8行目... *a に8を代入している。

間接参照演算子

ポインタ宣言子はポインタであることの宣言

間接参照演算子は *a (つまりb)を指し示している

 

ポインタ宣言子と間接参照演算子の区別が曖昧だったので、理解が遅れた。今でも何だか自信が無いのだが...

しばらくは、ポインタの学習になるのかと思う。

ポインタの使用〜その1

ポインタ宣言から使用まで

 

先回の学習から、ずいぶん日にちが経ってしまった。ポインタでつまずいてしまったのだ。そのため、ポインタだけを重点的に学習することにした。学習スピードが遅いのでブログ更新が遅くなると思う。諦めずに頑張りたい。

 

例1)ポインタ宣言の一例

ポインタ宣言から利用まで

変数aとポインタ変数bを使ってみる。

5行目...変数aを宣言

6行目...ポインタ変数bを宣言

8行目...変数aに2を代入

9行目...ポインタ変数bにaのアドレスを代入。このとき&をつけること。これでbはaを指し示すことになる。

 

11行目...printf関数である。%dでポインタbの値、すなわちaの値をあらわす。結果は2となる。

 

12行目...printf関数である。%pでaのアドレスを表す。アンパサンド(&)をつけること。

結果は0x16fdff268となる。

 

13行目...printf関数である。%pでポインタ変数bのアドレス、すなわちaのアドレスを表す。*はつけないこと。結果は0x16dff268となり、&aとbの表すアドレスが等しいことを示している。

 

14行目...printf関数である。%pでアドレスを表す。&bとすることで、bそのもののアドレスを表す。結果は0x16fdff260となる。

上記で見たように、12行目と13行目のアドレスは一致する。

 

例2)宣言と同時に初期化する例

宣言と同時に初期化する

宣言と同時に初期化する例を観察する。

5行目...変数aを宣言している。

6行目...ポインタ変数bの宣言と初期化をしている。bはaを指し示している。

 

8行目...変数aに2を代入している。

 

10行目...printf関数。%dで数値を表す。*bでaの値を示す。値は2となっている。

 

11行目...printf関数。%pでアドレスを表す。&aでaのアドレスを示している。

結果は0x16fdff258となっている。

12行目...printf関数。%pでアドレスを表す。bすなわちaを指し示している。*はつけない。

結果は0x16fdff258となり&aと等しくなっている。つまりb = &a;が成り立っている。

 

13行目...printf関数。%pでアドレスを表す。&bでbそのもののアドレスであることを示す。

 

例3)一連の流れ

 

次に一連の流れでの値をみてみる。

一連の流れ

5行目...変数bを宣言している。

6行目...ポインタ変数aの宣言と初期化を行なっている。aはbを指し示している。

 

8行目... *aに8を代入している。つまりbの値が8になるということ。

 

10行目...printf関数。%dで値を示している。*aなのでbの値を示している。つまり8である。

11行目...printf関数。%dで値を示している。bなので8である。

 

結果は両方とも8になっている。

 

少しずつポインタの使い方が分かってきた。(*)の使い方が難しいのでもう少し学習したい。