14 日間で C++ を学ぶ 2 日目 (関数とライブラリ)

ここに画像の説明を挿入します

1. 関数の定義と呼び出し

C++ では、関数はコードを編成および構造化するための重要なツールの 1 つです。これらを使用すると、コードの一部を再利用可能なモジュールにカプセル化できるため、コードが読みやすく、保守しやすくなります。

なぜ関数を使用するのでしょうか?

プログラミングにおける関数の役割を過小評価することはできません。これらにはいくつかの重要な用途があります。

  • モジュール式プログラミング:関数を使用すると、コードを小さな独立したユニットに分割できるため、コードの理解と管理が容易になります。

  • コードの再利用:一度書いたら何度でも使用できます。同じコードを繰り返し記述しなくても、プログラム内の異なる場所で同じ関数を呼び出すことができます。

  • 読みやすさの向上:コードを関数に分割することで、各関数にわかりやすい名前を付けることができ、コードが読みやすくなります。

関数を定義する

C++ では、通常、関数の定義には次の部分が含まれます。

// 函数声明(函数原型)
返回类型 函数名(参数列表);

// 函数定义
返回类型 函数名(参数列表) {
    
    
    // 函数体
    // 执行一些操作
    return 返回值; // 如果有返回值的话
}
  • 戻り値の型:関数は、戻り値の型で指定された型の値を返すことができます。関数が値を返さない場合は、voidキーワードを使用できます。

  • 関数名:関数の名前。関数の識別子です。

  • パラメータ リスト:関数は 0 個以上のパラメータを受け入れることができます。パラメータは括弧内にカンマで区切ってリストされます。

  • 関数本体:関数実行の実際のコード部分が含まれます。

  • 戻り値:関数に戻り値がある場合は、returnステートメントを使用して値を返します。

関数定義:

// 函数声明
int add(int a, int b);

// 函数定义
int add(int a, int b) {
    
    
    int result = a + b;
    return result;
}

関数の呼び出し

関数の呼び出しとは、関数内のコードを実行することを意味します。関数を呼び出すには、関数名と適切な引数リストを使用するだけです。

int main() {
    
    
    int num1 = 5;
    int num2 = 3;
    int sum = add(num1, num2); // 调用add函数
    cout << "Sum: " << sum << endl;
    return 0;
}

この例では、add関数が呼び出され、と のnum1合計が計算されnum2、結果がsum変数に格納されます。

2. パラメータの受け渡し

C++ では、パラメーターの受け渡しは、関数が外部とデータを交換するための重要な方法の 1 つです。値渡しや参照渡しなど、さまざまな方法で実装できます。

値渡しと参照渡し

値渡し

パラメーターが値によって関数に渡されると、関数はパラメーターのコピーを作成します。これは、関数内部のパラメーターに対する変更が外部の元のデータに影響を与えないことを意味します。

void modifyValue(int x) {
    
    
    x = 10; // 在函数内部修改副本
}

int main() {
    
    
    int value = 5;
    modifyValue(value);
    cout << "Value after function call: " << value << endl; // 仍然是5
    return 0;
}
参照渡し

パラメーターが参照によって渡される場合、関数は元のデータへの参照に基づいて動作します。つまり、パラメーターの変更は外部の元のデータに影響します。

void modifyValue(int &x) {
    
    
    x = 10; // 直接修改原始数据
}

int main() {
    
    
    int value = 5;
    modifyValue(value);
    cout << "Value after function call: " << value << endl; // 现在是10
    return 0;
}

関数パラメータのデフォルト値

関数パラメーターにはデフォルト値が提供されます。つまり、関数を呼び出すときに特定のパラメーターを省略でき、コンパイラーはデフォルト値を使用します。

void printMessage(string message = "Hello, World!") {
    
    
    cout << message << endl;
}

int main() {
    
    
    printMessage(); // 使用默认消息
    printMessage("Custom message"); // 使用自定义消息
    return 0;
}

関数のオーバーロード

関数のオーバーロードを使用すると、同じスコープ内で同じ名前で異なるパラメーター リストを持つ複数の関数を定義できます。コンパイラは、関数呼び出しのパラメータに基づいて正しい関数を選択します。

int add(int a, int b) {
    
    
    return a + b;
}

double add(double a, double b) {
    
    
    return a + b;
}

パラメーターを渡すさまざまな方法とデフォルト値の影響:

void modify(int x) {
    
    
    x = 10;
}

void modify(double &y) {
    
    
    y = 3.14;
}

int main() {
    
    
    int num = 5;
    double pi = 3.14159265359;

    modify(num); // 传值,num不变
    modify(pi);  // 传引用,pi被修改

    cout << "Modified num: " << num << endl;
    cout << "Modified pi: " << pi << endl;

    return 0;
}

この例では、modify関数に値および参照によってパラメーターが渡されるため、動作が異なります。

3. 関数の戻り値

関数の戻り値は、関数の実行後に呼び出し元に提供される結果です。C++ では、関数の戻り値の型を指定し、returnステートメントを使用して関数から値を返すことができます。

戻り値の型

すべての C++ 関数には戻り値の型があり、関数によって返されるデータ型を指定します。戻り値の型は関数の宣言と定義の両方で指定する必要があります。

int add(int a, int b) {
    
     // 返回值类型为int
    return a + b;
}

double divide(double x, double y) {
    
     // 返回值类型为double
    return x / y;
}

return ステートメント

returnステートメントは関数から値を返すために使用されます。関数内のどこにでも出現できますが、実行されると関数はすぐに終了し、呼び出し元に制御を返します。

int multiply(int a, int b) {
    
    
    int result = a * b;
    return result; // 返回计算结果
}

関数の戻り値を使用します。

int main() {
    
    
    int sum = add(5, 3); // 调用add函数并接收返回值
    double quotient = divide(10.0, 2.0); // 调用divide函数并接收返回值

    cout << "Sum: " << sum << endl;
    cout << "Quotient: " << quotient << endl;

    return 0;
}

上の例では、addおよびdivide関数は整数と浮動小数点数を返し、それらはそれぞれsumおよびquotient変数に格納されます。

式での戻り値の使用

関数の戻り値は、式の一部として直接使用できます。これにより、関数呼び出しが非常に柔軟になり、数式やその他の計算に使用できます。

int main() {
    
    
    int result = multiply(add(2, 3), 4); // 使用函数返回值进行嵌套调用和计算

    cout << "Result: " << result << endl;

    return 0;
}

この例では、add(2, 3)の戻り値がmultiplyさらなる計算のために関数に渡されます。

4. 標準 C++ ライブラリの紹介

強力なプログラミング言語である C++ には、多くの便利な関数とデータ構造を提供する豊富な標準ライブラリがあります。

ヘッダー ファイルをインクルードする

C++ 標準ライブラリの関数を使用するには、まず対応するヘッダー ファイルをインクルードする必要があります。ヘッダー ファイルには、ライブラリ内のクラス、関数、オブジェクトの宣言が含まれており、これらのライブラリを使用するための鍵となります。

#include <iostream>  // 包含iostream头文件,用于输入输出操作
#include <string>    // 包含string头文件,用于字符串操作
#include <vector>    // 包含vector头文件,用于动态数组操作

使用例

ライブラリの使用例:

入出力にiostreamを使用する
#include <iostream>

int main() {
    
    
    // 输出文本到控制台
    std::cout << "Hello, World!" << std::endl;

    // 从用户输入读取数据
    int num;
    std::cout << "Enter a number: ";
    std::cin >> num;

    // 输出读取到的数据
    std::cout << "You entered: " << num << std::endl;

    return 0;
}
文字列操作に文字列を使用する
#include <string>

int main() {
    
    
    std::string greeting = "Hello, ";
    std::string name = "John";

    // 字符串拼接
    std::string message = greeting + name;

    // 获取字符串长度
    int length = message.length();

    // 输出结果
    std::cout << message << " (Length: " << length << ")" << std::endl;

    return 0;
}
ベクトルを使用して動的配列を作成する
#include <vector>

int main() {
    
    
    std::vector<int> numbers;

    // 向vector添加元素
    numbers.push_back(1);
    numbers.push_back(2);
    numbers.push_back(3);

    // 遍历并输出vector的元素
    for (int i = 0; i < numbers.size(); ++i) {
    
    
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

5. ヘッダー ファイルと名前空間

C++ プログラミングでは、ヘッダー ファイルと名前空間は非常に重要な概念です。ヘッダー ファイルは宣言と定義を含めるために使用され、名前空間は名前の競合を避けるために使用されます。

ヘッダーファイルの役割

通常、ヘッダー ファイルには、関数、クラス、変数の宣言に加えて、必要な関数のプロトタイプと定数の定義が含まれています。ヘッダー ファイルの目的は、これらの宣言をグループ化して、複数のソース ファイル間で共有できるようにすることです。これにより、モジュール式プログラミングが容易になり、コードの保守性が向上します。

カスタムヘッダーファイルを作成する

.hカスタム ヘッダー ファイルを作成するには、拡張子または を付けて新しいテキスト ファイルを作成し.hpp、その中に必要な宣言を含めます。たとえば、次のようなmyheader.h名前のヘッダー ファイルの例を示します。

#ifndef MYHEADER_H
#define MYHEADER_H

// 在这里添加声明

#endif

名前空間の概念

名前空間は、名前の競合を防ぐためにグローバル スコープをさまざまな部分に分割するメカニズムです。これにより、関連する関数、クラス、変数を名前空間に編成して、他のコードとの名前の競合を回避できます。

名前空間を使用する

ネームスペースを使用するには、namespaceキーワードを使用してネームスペースを定義し、その中に関連する宣言を配置します。例えば:

// 定义一个名为mynamespace的命名空间
namespace mynamespace {
    
    
    int myVariable;
    void myFunction();
}
// 使用mynamespace中的变量和函数
mynamespace::myVariable = 42;
mynamespace::myFunction();

名前空間の使用を簡素化する

ネームスペースの使用を簡素化するために、usingキーワードを使用してネームスペース内の特定のメンバーを宣言できます。例えば:

// 使用mynamespace中的myVariable
using mynamespace::myVariable;

int main() {
    
    
    myVariable = 42; // 不需要指定命名空间
    return 0;
}

6.事例分析

関数のオーバーロード:

#include <iostream>

// 函数重载:处理整数
int add(int a, int b) {
    
    
    return a + b;
}

// 函数重载:处理双精度浮点数
double add(double a, double b) {
    
    
    return a + b;
}

int main() {
    
    
    int intResult = add(5, 7);
    double doubleResult = add(3.5, 2.7);

    std::cout << "Integer Result: " << intResult << std::endl;
    std::cout << "Double Result: " << doubleResult << std::endl;

    return 0;
}

操作結果:
ここに画像の説明を挿入します

再帰関数:

#include <iostream>

int fibonacci(int n) {
    
    
    if (n <= 1) {
    
    
        return n;
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
    
    
    int n = 10;
    for (int i = 0; i < n; ++i) {
    
    
        std::cout << fibonacci(i) << " ";
    }

    return 0;
}

操作結果:
ここに画像の説明を挿入します

ラムダ式:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    
    
    std::vector<int> numbers = {
    
    5, 2, 8, 1, 3};

    // 使用Lambda表达式对向量进行排序
    std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
    
    
        return a < b;
    });

    // 使用Lambda表达式筛选出偶数
    auto isEven = [](int x) {
    
     return x % 2 == 0; };
    std::vector<int> evenNumbers;

    std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(evenNumbers), isEven);

    // 输出排序后的向量
    std::cout << "Sorted Numbers: ";
    for (int num : numbers) {
    
    
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 输出筛选后的偶数
    std::cout << "Even Numbers: ";
    for (int num : evenNumbers) {
    
    
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

操作結果:
ここに画像の説明を挿入します

文字列処理:

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    
    
    std::string str = "Hello, World!";
    
    // 反转字符串
    std::reverse(str.begin(), str.end());
    std::cout << "Reversed String: " << str << std::endl;

    // 查找子字符串
    std::string subStr = "World";
    size_t found = str.find(subStr);
    if (found != std::string::npos) {
    
    
        std::cout << "Substring found at position: " << found << std::endl;
    } else {
    
    
        std::cout << "Substring not found." << std::endl;
    }

    // 将字符串拆分为单词
    std::string sentence = "This is a sample sentence";
    size_t startPos = 0;
    while (startPos < sentence.length()) {
    
    
        size_t spacePos = sentence.find(' ', startPos);
        if (spacePos == std::string::npos) {
    
    
            spacePos = sentence.length();
        }
        std::string word = sentence.substr(startPos, spacePos - startPos);
        std::cout << "Word: " << word << std::endl;
        startPos = spacePos + 1;
    }

    return 0;
}

操作結果:
ここに画像の説明を挿入します

コンテナの操作:

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

int main() {
    
    
    // 使用std::vector进行容器操作
    std::vector<int> numbers = {
    
    5, 2, 8, 1, 3};

    // 添加元素
    numbers.push_back(7);

    // 删除元素
    numbers.erase(std::remove(numbers.begin(), numbers.end(), 3), numbers.end());

    // 对容器排序
    std::sort(numbers.begin(), numbers.end());

    // 输出容器元素
    std::cout << "Vector Elements: ";
    for (int num : numbers) {
    
    
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 使用std::map进行容器操作
    std::map<std::string, int> scores;

    // 添加键值对
    scores["Alice"] = 95;
    scores["Bob"] = 87;
    scores["Charlie"] = 92;

    // 查找元素
    std::string name = "Bob";
    if (scores.find(name) != scores.end()) {
    
    
        std::cout << name << "'s Score: " << scores[name] << std::endl;
    } else {
    
    
        std::cout << "Name not found." << std::endl;
    }

    return 0;
}

操作結果:
ここに画像の説明を挿入します

マルチスレッドと同時実行性:

#include <iostream>
#include <thread>
#include <vector>

// 用于计算部分数组总和的函数
void partialSum(const std::vector<int>& arr, size_t start, size_t end, int& result) {
    
    
    result = 0;
    for (size_t i = start; i < end; ++i) {
    
    
        result += arr[i];
    }
}

int main() {
    
    
    const int numThreads = 4; // 使用4个线程
    const int arrSize = 1000;
    std::vector<int> numbers(arrSize, 1); // 创建一个包含1000个1的数组

    std::vector<std::thread> threads(numThreads);
    std::vector<int> partialResults(numThreads);

    // 创建并启动线程
    for (int i = 0; i < numThreads; ++i) {
    
    
        size_t start = i * (arrSize / numThreads);
        size_t end = (i == numThreads - 1) ? arrSize : (i + 1) * (arrSize / numThreads);
        threads[i] = std::thread(partialSum, std::ref(numbers), start, end, std::ref(partialResults[i]));
    }

    // 等待所有线程完成
    for (int i = 0; i < numThreads; ++i) {
    
    
        threads[i].join();
    }

    // 计算总和
    int totalSum = 0;
    for (int i = 0; i < numThreads; ++i) {
    
    
        totalSum += partialResults[i];
    }

    std::cout << "Total Sum: " << totalSum << std::endl;

    return 0;
}

操作結果:
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/m0_53918860/article/details/133529207