<C言語> 初期C言語

1 C言語とは何ですか?

C 言語は汎用の面向过程コンピューター プログラミング言語です。1972 年頃にベル研究所のデニス・リッチーによって開発され、システム プログラミングやアプリケーション開発で広く使用される言語になりました。C 言語は、簡潔な構文、効率的な実行速度、および強力な基礎となる制御機能を備えているため、オペレーティング システム、組み込みシステム、ゲーム開発などの分野で広く使用されています。

1980 年代に、さまざまな開発者によって使用される C 言語文法の違いを避けるために、米国標準局は、C 言語の元の標準として知られる、C 言語の米国標準文法の完全なセットを策定しましたANSI C

C言語は面向过程コンピュータプログラミング言語であり、C++やJavaなどのオブジェクト指向プログラミング言語とは異なります。そのコンパイラには主に Clang、GCC、WIN-TC、SUBLIME、MSVC (VS)、Turbo C などが含まれます。

2 初めてのC言語プログラム

#include <stdio.h>
int main() {
    
    
    printf("Hello World\n");
    return 0;
}

説明:

  • #include <stdio.h>このコード行は、標準入出力関数用のヘッダー ファイルを含めるようコンパイラーに指示する前処理ディレクティブですstdio.hヘッダー ファイルには、関数プロトタイプと入出力操作の定数定義が含まれています。
  • プログラムのメイン関数main。C 言語プログラムのエントリ ポイントです。intは関数の戻り値の型、mainは関数の名前、その後の空の括弧は関数がパラメータを受け入れないことを示します。main 関数が存在する必要があり、存在できるのは 1 つだけです。
  • C 言語標準ライブラリの関数printf。指定されたフォーマット文字列を標準出力 (通常はコンソール) に出力するために使用されます。ここでは、文字列「Hello World」を引数としてprintf関数に渡しており、関数はその文字列をコンソールに出力します。
  • return 0これは関数の終了を示し、整数値 0 を関数の戻り値として呼び出し元に返します。C 言語では、戻り値 0 は通常、プログラムが正常に実行されたことを示します。
  • \nは、改行と呼ばれる特殊なエスケープ文字です。これは、出力内の改行操作を示すために、つまり出力カーソルを次の行の先頭に移動するために使用されます。

2.1 printf関数

printfC 言語標準ライブラリの関数で、出力テキストを標準出力 (通常はコンソール) にフォーマットするために使用されます。「」

関数プロトタイプ:

int printf(const char *format, ...);

printfこの関数の主な機能は、フォーマット文字列内のプレースホルダーに従って、対応するパラメーターを指定されたテキストにフォーマットし、それを標準出力に出力することです。関数の戻り値は、出力された文字数です。プレースホルダーは%、引数のタイプと出力の形式を指定する 1 つ以上の文字で始まり、その後に続きます。

一般的な書式設定プレースホルダーとその使用法は次のとおりです。

  • %d: 符号付き 10 進整数を出力します。
  • %u: 符号なし 10 進整数を出力します。
  • %f: 浮動小数点数を出力します。
  • %c: 単一文字を出力します。
  • %s: 出力文字列。
  • %p: ポインタアドレスを出力します。
  • %xまたは%X: 16 進整数を出力します。

書式文字列内のプレースホルダーを除き、通常の文字はそのまま出力されます。

この関数ではprintf、書式設定オプションを使用して、出力の精度、幅、およびパディングを設定できます。一般的に使用される書式設定オプションをいくつか示します。

1. 精度 (Precision): 浮動小数点数または文字列の出力精度を指定するために使用されます。

  • %.nf: 小数点以下の浮動小数点数の精度をn桁に設定します。
  • %.*f: 浮動小数点数の小数点以下の精度を変数で指定します。たとえば%.*f、n 後に整数パラメータを渡して精度の値を指定します。
float pi = 3.14159;
printf("%.2f", pi);  // 输出:3.14

int precision = 3;
printf("%.*f", precision, pi);  // 输出:3.142

2. 幅: 出力フィールドの幅を指定するために使用され、スペースまたは他の文字で埋めることができます。

  • %nd:整数の出力幅をn文字とし、足りない部分はスペースで埋めます。
  • %*d: 変数を通じて整数の出力幅を指定します。たとえば%*d、整数パラメータ n を後で渡して幅の値を指定します。
int num = 42;
printf("%6d", num);  // 输出:    42

int width = 8;
printf("%*d", width, num);  // 输出:      42

3. 充填文字 (パディング文字): 出力フィールドを埋める文字を指定するために使用されます。デフォルトはスペースです。

  • %nd: 整数の出力幅 n の前に埋め込み文字を追加します。たとえば%6d、出力の整数幅を 6 文字に設定し、デフォルトでスペースで埋め込みます。
  • %*cd: 変数を介して充填文字を指定します。たとえば%*cd、後で文字パラメータ c を渡して充填文字の値を指定します。
int num = 42;
printf("%06d", num);  // 输出:000042

char fillChar = '*';
printf("%*cd", 8, fillChar, num);  // 输出:******42

2.2 scanf関数

scanf標準入力 (通常はキーボード) から入力データを読み取るための C 言語標準ライブラリの関数です。

関数プロトタイプ:

int scanf(const char *format, ...);

戻り値:

scanfこの関数は、正常に読み取られたデータ項目の数を返します。エラーが発生した場合、または入力の終わりに達した場合は、負の数を返します。

scanf形式文字列内のプレースホルダーに従って、関数は標準入力から対応するデータを読み取り、指定された変数に格納します。

一般的な書式設定プレースホルダーとその使用法は次のとおりです。

  • %d: 符号付き 10 進整数を読み取ります。
  • %u: 符号なし 10 進整数を読み取ります。
  • %f: 浮動小数点数を読み取ります。
  • %c: 1 文字を読み取ります。
  • %s: 文字列を読み取ります。
  • %p: ポインタアドレスを読み取ります。
  • %xまたは%X: 16 進整数を読み取ります。

プレースホルダーを除き、書式設定された文字列内の通常の文字は入力データと照合されます。正常に照合するには、対応する文字を入力する必要があります。

scanfこの関数は、書式文字列と対応するパラメーターに従って入力を受け取ります。入力データが書式文字列内のプレースホルダーと一致しない場合、入力エラーまたは実行時エラーが発生する可能性があります。したがって、scanfこの関数を使用するときは、潜在的な問題を回避するために、形式文字列とパラメーターが正しく一致していることを確認する必要があります。

int main() {
    
    
    int num;
    printf("Enter a number: ");
    scanf("%d", &num);   //输入3
    printf("You entered: %d\n", num);  //打印: You entered 3  
    return 0;
}

3 つの基本的なデータ型

char     //字符数据类型
short    //短整型
int      //整形
long     //长整型
long long//更长的整形
float    //单精度浮点数
double   //双精度浮点数

//类型的使用:
char ch = 'w';
int weight = 120;
int salary = 20000;

データ型のサイズは、コンパイラとターゲット プラットフォームの実装によって異なります。コンパイラは、C 言語の標準仕様とターゲット プラットフォームの特性に従って、さまざまなデータ型のサイズを決定します。

printf("%zu\n", sizeof(char));       //1
printf("%zu\n", sizeof(short));      //2
printf("%zu\n", sizeof(int));        //4
printf("%zu\n", sizeof(long));       //4
printf("%zu\n", sizeof(long long));  //8
printf("%zu\n", sizeof(float));      //4
printf("%zu\n", sizeof(double));     //8
printf("%zu\n", sizeof(long double));//8/16

4つの変数、定数

人生における一部の値は一定です (例: 円周率、性別、ID 番号、血液型など)。

一部の値は可変です (例: 年齢、体重、給与)。

変数は、変数データを保存および操作するために使用される識別子です。プログラムでは、変数を宣言してメモリ空間を確保し、変数名を通じてメモリに格納された値を参照したり変更したりすることができます。変数の値はプログラムの実行中に変更される可能性があります。

定数は変更できない固定値です。プログラムでは、定数を使用して、数値、文字、文字列などの不変の値を表すことができます。定数の値は定義時に決定され、変更することはできません。

  • 変数は、プログラムの実行中に値が変化する可能性のある可変データを保存および操作するために使用されます。
  • 定数は、定義時に値が決定され、それ以降は変更できない変更不可能な固定値を表すために使用されます。

4.1 変数の定義方法

int age = 150;
float weight = 45.5f;
char ch = 'w';

4.2 変数の命名

  • 文字 (大文字と小文字の両方)、数字、アンダースコア (_) のみで構成できます。
  • 数字で始めることはできません。
  • 長さは 63 文字を超えることはできません。
  • 変数名では大文字と小文字が区別されます。
  • 変数名にはキーワードを使用できません。

4.3 変数の分類

  • ローカル変数
  • グローバル変数
#include <stdio.h>
int global = 2019;//全局变量
int main() {
    
    
    int local = 2018;//局部变量
    //下面定义的global会不会有问题?
    int global = 2020;              //局部变量
    printf("global = %d\n", global);//global = 2020
    return 0;
}

実際、上記のローカル変数グローバル変数の定義には何も問題はありません。

ローカル変数がグローバル変数と同じ名前の場合、ローカル変数が優先されます。

変数の使用:

#include <stdio.h>
int main() {
    
    
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);  //键盘输入: 3 5
    sum = num1 + num2;
    printf("sum = %d\n", sum);  //sum = 8
    return 0;
}

4.4 変数のスコープとライフサイクル

C言語では、変数のスコープ(scope)とライフタイム(lifetime)は、プログラム内での変数の可視性や存在時間を記述する概念です。

スコープ(Scope)とは、プログラム内で目に見える変数の範囲を指します。変数のアクセス可能性はスコープごとに異なります。C 言語にはいくつかのスコープがあります。

  • ブロック スコープ: 変数はコード ブロック内で宣言され (中括弧で囲まれています{})、そのブロック内で表示されます。ブロックを離れると、変数はそのスコープから外れます。

    int main() {
          
          
        int x = 10;
        {
          
          
            int y = 20;
            printf("%d\n", x);  // 可以访问外部块中的变量
            printf("%d\n", y);  // 可以访问内部块中的变量
        }
        printf("%d\n", x);  // 可以继续访问外部块中的变量
        // printf("%d\n", y);  // 错误!超出了变量 y 的作用域
        return 0;
    }
    
  • 関数スコープ: 変数は関数内で宣言され、関数全体で参照できます。関数パラメータと関数内で宣言された変数には関数スコープがあります。

    int sum(int a, int b) {
          
          
        int result = a + b;
        return result;
    }
    
    int main() {
          
          
        int x = 10;
        int y = 20;
        int total = sum(x, y);
        printf("%d\n", total);
        // printf("%d\n", result);  // 错误!超出了变量 result 的作用域
        return 0;
    }
    
  • ファイル スコープ (グローバル スコープ) (ファイル スコープ) : 変数はソース ファイル全体で宣言され、ファイル内の任意の関数からアクセスできます。関数の外で宣言された変数にはファイル スコープがあります。

    int globalVar = 10;
    
    void function1() {
          
          
        printf("%d\n", globalVar);  // 可以访问文件作用域的变量
    }
    
    void function2() {
          
          
        printf("%d\n", globalVar);  // 可以访问文件作用域的变量
    }
    
    int main() {
          
          
        printf("%d\n", globalVar);  // 可以访问文件作用域的变量
        function1();
        function2();
        return 0;
    }
    

ライフタイムとは、変数が存在する時間範囲を指します。変数の有効期間は、そのスコープと宣言方法によって異なります。C 言語には次の変数のライフサイクルがあります。

  • 自動変数 (Automatic Variables) : 関数内で宣言された変数は自動変数です。それらのライフサイクルは変数定義で始まり、それらが含まれるコード ブロックの終わりで終了します。変数はコード ブロックが入力されるたびに再作成され、コード ブロックが終了すると破棄されます。
void function() {
    
    
    int x = 10;  // 自动变量,生命周期与函数调用关联
    printf("%d\n", x);
}

int main() {
    
    
    function();  // 调用函数
    // printf("%d\n", x);  // 错误!变量 x 不在作用域内
    return 0;
}

静的変数 (静的変数) :関数内でキーワードを使用してstatic宣言された変数は静的変数です。それらの存続期間は、プログラムの実行開始時に始まり、プログラムの終了時に終了します。静的変数はプログラムの実行中に存在し、初期化されるのは 1 回だけです。

void function() {
    
    
    static int count = 0;  // 静态变量,生命周期与程序运行关联
    count++;
    printf("%d\n", count);
}

int main() {
    
    
    function();  // 调用函数,输出:1
    function();  // 调用函数,输出:2
    function();  // 调用函数,输出:3
    return 0;
}

グローバル変数: 関数の外で宣言された変数はグローバル変数です。それらの存続期間は、プログラムの実行開始時に始まり、プログラムの終了時に終了します。グローバル変数はプログラムの実行全体にわたって存在し、初期化されるのは 1 回だけです。

int globalVar;  // 全局变量

void function() {
    
    
    globalVar = 10;
}

int main() {
    
    
    function();  // 调用函数
    printf("%d\n", globalVar);  // 输出:10
    return 0;
}

4.5 定数

C言語では定数と変数の定義形式が異なります。

C 言語の定数は次のカテゴリに分類されます。

  • リテラル定数
  • const変更された定数変数
  • #define定義された識別子定数
  • 列挙定数
#include <stdio.h>
//举例
enum Sex {
    
    
    MALE,
    FEMALE,
    SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量


int main() {
    
    
    //字面常量演示
    3.14;//字面常量
    1000;//字面常量

    //const 修饰的常变量
    const float pai = 3.14f;//这里的pai是const修饰的常变量
    //pai = 5.14;             //被const修饰后,是不能直接修改的!

    //#define的标识符常量 演示
#define MAX 100
    printf("max = %d\n", MAX);// max = 100

    //枚举常量演示
    printf("%d\n", MALE);  //0
    printf("%d\n", FEMALE);//1
    printf("%d\n", SECRET);//2
    //注:枚举常量的默认是从0开始,依次向下递增1的
    return 0;
}

上記の例は修正定数変数paiと呼ばれるもので、 C言語における修正定数変数は文法レベルで変数を制限するだけで直接変更することはできませんが、本質的には変数であることに変わりはないため、定数変数と呼ばれます。constconstpaipai

5文字列+エスケープ文字+コメント

5.1 文字列

"hello bit.\n"

この二重引用符 (Double Quote) で囲まれた文字列を文字列リテラル (String Literal)、または単に文字列と呼びます。

注: 文字列の末尾は \0 エスケープ文字です。\0 は文字列の長さを計算する際の終了マークであり、文字列の内容としてカウントされません。

#include <stdio.h>
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{
    
    
    char arr1[] = "bit";
    char arr2[] = {
    
    'b', 'i', 't'};
    char arr3[] = {
    
    'b', 'i', 't''\0'};
    printf("%s\n", arr1);  //bit
    printf("%s\n", arr2);  //烫烫
    printf("%s\n", arr3);  //bit
    return 0;
}
  1. arr1文字列として初期化された文字配列です。これには文字「b」、「i」、「t」およびヌル文字「\0」が含まれており、ヌル文字は配列の最後に自動的に追加されます。したがって、printf("%s\n", arr1)出力されるのは完全な文字列「bit」です。
  2. arr2文字リストで初期化された文字配列です。文字「b」、「i」、「t」が含まれていますが、末尾にヌル文字「\0」は追加されません。%sこの形式では NULL で終わる文字列が必要なため、最初の NULL 文字が見つかるまでメモリprintf("%s\n", arr2)にアクセスし続けます。arr2この後のメモリ内容は未定義であるため、印刷結果は不定になります。
  3. arr3文字リストで初期化された文字配列で、末尾に null 文字 '\0' が明示的に追加されます。したがって、printf("%s\n", arr3)出力されるのは完全な文字列「bit」です。

C 言語の文字列は、文字列の終わりを示すヌル文字「\0」で終わる文字配列です。文字列が NULL で終了していない場合、文字列処理関数 ( printf、など)strcpystrlen文字列を正しく処理せず、予期しない結果やエラーが発生する可能性があります。したがって、文字列を操作するときは、文字列がヌル文字「\0」で終了していることを確認することが非常に重要です。

5.2 エスケープ文字

ディレクトリを画面に印刷したい場合c:\code\test.c

どのようにコードを書けばよいのでしょうか?

#include <stdio.h>
int main() {
    
    
    printf("c:\code\test.c\n");
    return 0;
}
//输出结果:c:code  est.c

ここでエスケープ文字について触れなければなりません。エスケープ文字は、その名前が示すように、意味を変更するためのものです。

いくつかのエスケープ文字を見てみましょう。

  • \n: 改行 (改行)
  • \t:タブ文字(タブ)
  • \":ダブルクォーテーション(二重引用符)
  • \': シングルクォーテーション(一重引用符)
  • \\:バックスラッシュ(バックスラッシュ)
  • \b: バックスペース
  • \r: キャリッジリターン
  • \f:フォームフィード(フォームフィード)
  • \v:垂直タブ(垂直タブ)
  • \a:ベルマーク(警告)
  • \0: ヌル文字
  • \?:クエスチョンマーク(疑問符)
  • \ooo: 8 進数文字 ( はooo8 進数を表し、範囲は\000です\377)
  • \xhh: 16 進数文字 ( はhh16 進数を表し、範囲は\x00です\xFF)

未知のエスケープ文字シーケンスが文字列リテラルで使用されている場合、または範囲外の 8 進数または 16 進数が文字リテラルで使用されている場合、コンパイラはエラーを報告するか、定義された動作を生成する可能性があることに注意してください。したがって、エスケープ文字を使用する場合は、その正しい構文と意味を必ず理解してください。

#include <stdio.h>
int main()
{
    
    
    //问题1:在屏幕上打印一个单引号',怎么做?
    //问题2:在屏幕上打印一个字符串,字符串的内容是一个双引号“,怎么做?
    printf("%c\n", '\'');
    printf("%s\n", "\"");
    return 0;
}

ペンでの質問:

//程序输出什么?
#include <stdio.h>
int main()
{
    
    
    printf("%d\n", strlen("abcdef"));  //6
    // \62被解析成一个转义字符
    printf("%d\n", strlen("c:\test\628\test.c"));  //14
    return 0;
}

5.3 注意事項

  1. コード内の不要なコードは直接削除またはコメントアウト可能
  2. コード内の一部のコードは理解するのが難しいため、コメントテキストを追加できます

例えば:

#include <stdio.h>
int Add(int x, int y) {
    
    
    return x + y;
}
/*C语言风格注释
int Sub(int x, int y)
{
    return x-y;
}
*/
int main() {
    
    
    //C++注释风格
    //int a = 10;
    //调用Add函数,完成加法
    printf("%d\n", Add(1, 2));
    return 0;
}

コメントには 2 つの種類があります。

  • C スタイルのコメント/*xxxxxx*/
    • 欠点: コメントをネストできない
  • C++ スタイルのコメント//xxxxxxxx
    • 1行または複数行にコメントを付けることができます

6. よくあるキーワード

auto  break   case  char  const   continue  default  do   double else  enum   
extern float  for   goto  if   int   long  register    return   short  signed
sizeof   static struct  switch  typedef union  unsigned   void  volatile  while

C 言語には豊富なキーワードが用意されており、言語自体があらかじめ設定しており、ユーザーが自分でキーワードを作成することはできません。

6.1 キーワード typedef

typedef は、名前が示すとおり、型定義であり、ここでは型の名前変更として理解する必要があります。

例えば:

//将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
typedef unsigned int uint_32;
int main() {
    
    
    //观察num1和num2,这两个变量的类型是一样的
    unsigned int num1 = 0;
    uint_32 num2 = 0;
    return 0;
}

6.2 キーワード静的

C 言語の場合: static は変数と関数を変更するために使用されます。

  1. ローカル変数を装飾する - 静的ローカル変数と呼ばれます
  2. グローバル変数を装飾する - 静的グローバル変数と呼ばれます
  3. デコレータ関数 - 静的関数と呼ばれます

ローカル変数を変更する

例 1:

#include <stdio.h>
void test() {
    
    
    int i = 0;
    i++;
    printf("%d ", i);
}

int main() {
    
    
    int i = 0;
    for (i = 0; i < 10; i++) {
    
    
        test();
    }
    return 0;
}

出力結果:

1 1 1 1 1 1 1 1 1 1

静的を追加します。

#include <stdio.h>
void test() {
    
    
    //static修饰局部变量
    static int i = 0;
    i++;
    printf("%d ", i);
}

int main() {
    
    
    int i = 0;
    for (i = 0; i < 10; i++) {
    
    
        test();
    }
    return 0;
}

出力結果:

1 2 3 4 5 6 7 8 9 10

コード 1 とコード 2 の効果を比較して、ローカル変数の静的変更の重要性を理解してください。

結論は:

ローカル変数の静的変更により変数のライフサイクルが変更されます

静的ローカル変数がスコープ外に存在するようにすると、プログラムが終了するまでライフサイクルは終了しません。

グローバル変数を修飾する

例:

//代码1
//add.c
int g_val = 2018;
//test.c
int main() {
    
    
    printf("%d\n", g_val);
    return 0;
}

//代码2
//add.c
static int g_val = 2018;
//test.c
int main() {
    
    
    printf("%d\n", g_val);
    return 0;
}

コード 1 は正常ですが、コード 2 はコンパイル時に接続エラーが発生します。

結論は:

グローバル変数は static によって変更されるため、このグローバル変数はこのソース ファイル内でのみ使用でき、他のソース ファイルでは使用できません。

修飾子関数

例:

//代码1
//add.c
int Add(int x, int y) {
    
    
    return x + y;
}
//test.c
int main() {
    
    
    printf("%d\n", Add(2, 3));
    return 0;
}
//代码2
//add.c
static int Add(int x, int y) {
    
    
    return x + y;
}
//test.c
int main() {
    
    
    printf("%d\n", Add(2, 3));
    return 0;
}

コード 1 は正常ですが、コード 2 はコンパイル時に接続エラーが発生します。

結論は:

関数は静的に変更されるため、この関数はこのソース ファイル内でのみ使用でき、他のソース ファイルでは使用できません。

7. #define は定数とマクロを定義します

//define定义标识符常量
#define MAX 1000
//define定义宏
#define ADD(x, y) ((x) + (y))
#include <stdio.h>
int main() {
    
    
    int sum = ADD(2, 3);
    printf("sum = %d\n", sum);//sum = 5

    sum = 10 * ADD(2, 3);
    printf("sum = %d\n", sum);//sum = 50

    return 0;
}

おすすめ

転載: blog.csdn.net/ikun66666/article/details/131296316