❤恋するコンピュータサイエンス❤

コンピュータサイエンス、3DCGをもっと楽しく、もっと本質的に!c言語、c++の記事中心です

プログラミング上達の速度(理解の歩幅)

初心者


思考(理解)の歩幅

プログラミングの理解の歩幅プログラミングを学ぶ際、人それぞれ理解のスピードや進む歩幅は異なります。理解が早い人は、まるで階段を2、3段飛ばしで駆け上がるかのように、新しい知識や技術を素早く吸収していきます。一方理解の歩幅は階段を一歩ずつ上るように、ゆっくりとでも着実に学び進めていく方法もあります。
階段を上る歩幅が狭いと感じる人でも、その一歩一歩を大切にし、じっくりと考えながら学ぶことで、理解が早い人よりも深く、緻密な知識を習得することができるのです。
どのような歩幅であれ、それぞれのペースを大切にし、焦らず自分の道を進むことが大切です。

ポインタ理解のコツ③【レファレンス・デリファレンス】

Q,
ポインタのレファレンス(参照)・デリファレンス(脱参照)とは何か



A.

そもそも、ポインタが何故必要かといえばレファレンス・デリファレンス
するためといえる。下記用語の理解から始めよう


レファレンス(参照は、変数やデータ構造などが格納されているメモリのアドレスを参照すること、またはその参照自体を指します


デリファレンスは、ポインタが示すメモリのアドレスに格納されている実際の値を取得する操作を指します

解説)

レファレンスは「参照」、デリファレンスは「参照先の値を読む(または書く)」という操作です








int *str = "abc" は可能か?

Q.

int *str = "abc"

は可能か?

 

A.

駄目。

char *str = "abc"

としてchar ポインタ型で文字列は宣言しなければならない。

 

 

C言語ではint型の変数を直接使って文字列を格納することは許可されていません。その主な理由は以下の通りです:

データ型のサイズ: int型は通常、32ビット(4バイト)のデータを格納します。したがって、ASCII文字を表現するには十分な領域があります(ASCII文字は8ビットで表現できます)。しかし、複数の文字を連続して格納するためには、それぞれの文字の間に境界(boundary)が必要です。C言語では、これが自動的に行われるわけではないため、文字列をint型で表現すると、その境界が曖昧になってしまいます。

文字列の終端: C言語の文字列はヌル文字('')で終わります。このヌル文字は文字列の終端を示すための重要なマーカーです。しかし、int型の変数を使って文字列を格納しようとすると、この終端マーカーをどのように配置するかが問題となります。

互換性と標準化: C言語では、文字列はchar型の配列として表現されるという慣習があります。この慣習に従っていれば、他のCプログラムやライブラリとの互換性が保たれます。int型を使った独自の文字列表現を導入すると、そのコードは標準的なCプログラムと互換性がなくなる可能性があります。

以上のような理由から、C言語では文字列をint型の変数に直接格納することは許可されていません。

 

 

【C言語】文字列を数値に変換する方法(atoi)

そもそも何故このようなatoi関数が必要かというと、コマンドラインで入力した文字列を、10進法のint型にする事で、入力した文字列→整数として扱う為だ。

下記の例をみてみよう。

例えば0,10という数値をコマンドラインに入力した場合、

"0"  → 0

"10" → 10

という変換をするのがatoiとなる。

この時点で実装の方針がたつ人は文字はASCII コードの対応している数値によって変換されているという前提を理解している人だ。

"0"  → 48(ASCII)  

"10" → "1"と"0"に分解され、それぞれascii の数値に対応している。

 

つまり上記の48という数値を引き算すれば整数になるという算段だ

 

 

下記atoiの実装だが、下記のプログラムの本質は先に説明した通りである。

文字列を

 

static int  isspace(char c)
{
    return (c == '\t' || c == '\n' || c == '\v'
        || c == '\f' || c == '\r' || c == ' ');
}

static int  is_over_flow(long num, int n, int is_minus)
{
    long    ov_div;
    long    ov_mod;

    ov_div = LONG_MAX / 10;
    ov_mod = *1
        str++;
    if (*str == '-' || *str == '+')
    {
        if (*str++ == '-')
            sign = -1;
    }
    while (ft_isdigit(*str))
    {
        if (is_over_flow(res, *str - '0', sign == -1))
        {
            if (sign == 1)
                return ((int)LONG_MAX);
            else
                return ((int)LONG_MIN);
        }
        res = res * 10 + *str++ - '0';
    }
    return (res * sign);
}

long をキャストしてint にしている。

*1:LONG_MAX % 10) + is_minus) % 10;

    if (num > ov_div)
        return (1);
    if (num == ov_div && ov_mod < n)
        return (1);
    return (0);
}

int ft_atoi(const char *str)
{
    long    res;
    long    sign;

    res = 0;
    sign = 1;
    while (isspace(*str

write 関数の基礎

char n = 48;
write(1, &n ,1);

Q.
上記何が表示されるか答えよ

 

A.

`0`が表示される。

文字をWRITE関数で出力する場合、その文字は ASCII コードに基づいた整数値として表現されます。48はASCII コードで、0に対応している為。

42 Tokyo Picsine 28日目(ピシン)【ついに最終日!!】



ついに来てしまった。

最終日。

泣いても笑っても最終日だ。

それにしても、不思議であり驚異的ですらある。

0と1だけの信号処理をするだけで、素数、文字列、さらには画像まで全てが表せてしまう。

考えてみると不思議で、掘っても掘っても新しい発見がある。

 

フランス語でpicsine とは泳ぐという意味らしいが、

この4週間水の中を犬かきするように泳いでいた、いやズブズブに溺れていたのかもしれない。
動物のように知識にがっつきむさぼり食べたような、28日間だった

プログラミングの本質に少しだけ触れたような気がする。

正直なところ、何度もリタイアしようかと思った、新しい概念や難しいアルゴリズムに直面すると、頭がパンクしそうになることもあった。しかし、ちょっとだけ階段を上ると違った景色が見え、プログラミングの地平線が少しずつ拡大していくような錯覚があったのが、最後まで走りきれた要因かもしれない

ただ、どうしてもなじめなかったのはバグ修正作だ。思い込んでいたロジックがうまく機能しなかったり、予期せぬエラーに苦しんだりすると絶望的になった。しかし、デバッグの過程で自分のコードを徹底的に見直すことで、より堅牢なプログラムを作り上げることができ時の喜びもあった。

まとめると、
この42picineという旅でプログラミングの真髄に少し触れたような気がした。

EOF とはなにか?

 

Q.

EOFとは何か?

 

 

A

EOFとは "End of File" の略で、ファイルの終わりを示すマーカーまたは特殊な状態を意味します。これは、ファイルの読み取りを行っているプログラムが、これ以上読み取るデータがないことを認識するために使用されます。

C言語では、readfreadなどのファイル読み取り関数がファイルの終わりに達すると、EOFを返すことがあります。このEOFは通常、-1として表されます。

なお、EOFはファイルの終端に達したことだけでなく、エラーが発生した場合にも返されることがあります。そのため、ファイルの終わりに達したのか、それともエラーが発生したのかを判断するためには、通常は追加のエラーチェックを行う必要があります。

また、ファイルを文字単位で読み取る場合の getcfgetc 関数でも、ファイルの終わりに達した場合にはEOFが返されます。これらの関数の場合、EOFは通常、整数値の-1として表されます。

以下は、典型的な入力ループの例です:

c
Copy code
int c;
while *1 != EOF) {
    // 文字の処理
}
この例では、getchar()から返される値がEOFでない限り、ループが継続されます。EOFが返されると、ループが終了します。

ただし、EOFの値が必ずしも-1であるとは限りません。具体的な値は処理系やプラットフォームに依存しますので、プログラム中でEOFの値を直接比較する代わりに、<stdio.h>ヘッダーで提供されるEOFの定義を使用することをおすすめします。

*1:c = getchar(