Head First C学習ログ、第2章ポインタでデータを入力


1.scanf
scanfの呼び出しフォーマットは、scanf(「<フォーマット説明文字列>」、<変数アドレス>);
2番目のパラメータは必ずアドレスです.
1.1文字列を入力:
    char name[40];
    printf("Enter your name:
");     scanf("%39s",name);

フォーマット文字列%39 sは、最大39文字(+'0')を受け取り、2番目のパラメータnameは、配列名をポインタとして使用し、アドレスを関数に転送することで、scanf()が変数の内容を更新できることを示します.
1.2入力数字
     int age;
    printf("Enter your age:");
    scanf("%d",&age);
    printf("age:%d
",age);

フォーマット文字列が%dの場合、受け入れられる2番目のパラメータはint*ポインタです.
配列境界問題:読み取り文字列の長さを制限することを忘れた場合、ユーザーはプログラム空間をはるかに超えたデータを入力することができ、余分なデータはコンピュータがまだ割り当てられていないメモリに書き込まれます.バッファオーバーフローは、プログラムエラーを引き起こす可能性があります.
2.fgetsで入力
fgetsはscanfと同じようにcharポインタを受け入れます.違いは、最大の長さを与えなければなりません.
     char food[5];
     printf("Enter favorite food:");
     fgets(food,sizeof(food),stdin);

1番目のパラメータは、バッファへのポインタを受け取り、2番目のパラメータは、受信文字列の最大長(’0’を含む)であり、3番目のパラメータは入力であり、stdinは標準入力ストリームからのものを表す.
1番目のパラメータが配列ではなくポインタである場合は、その長さを明示的に指定する必要があります.
scanfは複数のフィールドを入力できますが、fgetsはできません.
scanfはスペースに遭遇すると停止し、fgetsはスペースを受け入れることができます.
3.文字列のフォント値は更新できません.
次のように宣言します.
     char *cards = “JQK”;
コンピュータはメモリの定数セグメントに「JQK」を作成し、cardsポインタ(スタック内)をこの定数セグメントのアドレスに指します.定数セグメントのデータは変更できません.
文字列を変更する場合は、次のようにコピーします.
メモリの非読み取り専用セグメントに文字列のコピーが作成されている場合は、その文字を変更できます.
     char cards[] = “JQK”;(配列を文字列で初期化)
cardsの配列を宣言し、文字列の文字面値に設定すると、cards配列は新しいコピーになります.cardsは文字列の文字面値を指すポインタではなく、新しい配列です.
3.1 char cards[]の意味:
通常の変数宣言の場合、cardsは配列であり、すぐに値を割り当てる必要があります.
関数パラメータとして宣言すると、cardsはchar*cardsと等価なポインタです.
これにより、フォント値の変更エラーを回避するためには、ポインタを文字列フォント値に設定するには、constキーワードが使用されていることを確認する必要があります.
const char *cards = “some string”;
これにより、コンパイラがコードが文字列を変更しようとしていることを発見すると、コンパイルエラーがプロンプトされます.