23.指针变量作为函数参数

23.指针-指针和函数-指针变量作为函数参数


23.1 知识点

知识回顾 按值传递

当我们在使用函数时,C++会把实参的副本传递给形参,这意味着函数内部的形参和外部的实参是两个独立的变量。它们只是初始值相同,对形参的修改只会影响副本,不会改变原始的实参。形参和实参本质上是两个不同的变量,只是变量中存储的值是相同的。

void swap(int a, int b)
{
    int tmp = a;
    a = b;
    b = tmp;
    // 形参交换结果
    cout << "形参交换结果" << endl;
    cout << "形参 a = " << a << endl;
    cout << "形参 b = " << b << endl; // 10
}

int a = 10;
int b = 20;
swap(a, b);
cout << "实参 a = " << a << endl; // 10
cout << "实参 b = " << b << endl; // 20
// 形参交换结果
// 形参 a = 20
// 形参 b = 10
// 实参 a = 10
// 实参 b = 20

指针变量作为函数参数

当指针变量作为函数参数时,实参传递给函数体后同样会生成指针变量副本。但是,由于副本与原指针指向同一个门牌号,因此如果修改指针变量指向房间中的内容,原指针中指向房间中的内容也会改变。也就是说,如果你想要在函数内部利用形参改变实参的值,那么可以利用指针来传递参数,达到目的。

void swap(int* aPtr, int* bPtr)
{
    int tmp = *aPtr;
    *aPtr = *bPtr;
    *bPtr = tmp;
    // 形参交换结果
    cout << "形参交换结果" << endl;
    cout << "形参 *aPtr = " << *aPtr << endl;
    cout << "形参 *bPtr = " << *bPtr << endl;
}

int* pA = &a;
int* pB = &b;
swap(pA, pB);
cout << "实参 a = " << a << endl; // 20
cout << "实参 b = " << b << endl; // 10
// 形参交换结果
// 形参 *aPtr = 20
// 形参 *bPtr = 10
// 实参 a = 20
// 实参 b = 10
swap(&a, &b);
cout << "实参 a = " << a << endl; // 20
cout << "实参 b = " << b << endl; // 10
// 形参交换结果
// 形参 *aPtr = 10
// 形参 *bPtr = 20
// 实参 a = 10
// 实参 b = 20


23.2 知识点代码

Lesson23_指针_指针和函数_指针变量作为函数参数.cpp

#include <iostream>
using namespace std;

void swap(int a, int b);
void swap(int* aPtr, int* bPtr);

int main()
{
    std::cout << "指针变量作为函数参数\n";

    #pragma region 知识回顾 按值传递

    int a = 10;
    int b = 20;
    swap(a, b);
    cout << "实参 a = " << a << endl;//10
    cout << "实参 b = " << b << endl;//20
    //形参交换结果
    //形参 a = 20
    //形参 b = 10
    //实参 a = 10
    //实参 b = 20

    #pragma endregion

    #pragma region 知识点 指针变量作为函数参数

    int* pA = &a;
    int* pB = &b;
    swap(pA, pB);
    cout << "实参 a = " << a << endl;//20
    cout << "实参 b = " << b << endl;//10
    //形参交换结果
    //形参* aPtr = 20
    //形参 * bPtr = 10
    //实参 a = 20
    //实参 b = 10

    swap(&a, &b);
    cout << "实参 a = " << a << endl;//20
    cout << "实参 b = " << b << endl;//10
    //形参交换结果
    //形参* aPtr = 10
    //形参 * bPtr = 20
    //实参 a = 10
    //实参 b = 20

    #pragma endregion
}

#pragma region 知识回顾 按值传递

//当我们在使用函数时
//C++会把实参的副本传递给形参,这意味着函数内部的形参和外部的实参是两个独立的变量
//它们只是初始值相同,对形参的修改只会影响副本,不会改变原始的实参
//形参和实参本质上是两个不同的变量,只是变量中存储的值是相同的

void swap(int a, int b)
{
    int tmp = a;
    a = b;
    b = tmp;
    //形参交换结果
    cout << "形参交换结果" << endl;
    cout << "形参 a = " << a << endl;
    cout << "形参 b = " << b << endl;//10
}

#pragma endregion

#pragma region 知识点 指针变量作为函数参数

//当指针变量作为函数参数时
//实参传递给函数体后同样会生成指针变量副本
//但是!!!
//由于副本与原指针指向同一个门牌号
//因此如果修改指针变量指向房间中的内容
//原指针中指向房间中内容也会改变
//也就说,如果你想要在函数内部利用形参改变实参的值
//那么可以利用指针来传递参数,达到目的
void swap(int* aPtr, int* bPtr)
{
    int tmp = *aPtr;
    *aPtr = *bPtr;
    *bPtr = tmp;
    //形参交换结果
    cout << "形参交换结果" << endl;
    cout << "形参 *aPtr = " << *aPtr << endl;
    cout << "形参 *bPtr = " << *bPtr << endl;
} 

#pragma endregion

23.3 练习题

有一个函数,可以传入一个一维数组。我们传入一个{1,2,3,4,5},请在该函数内部将其中的3改成99

注意:请在函数中写出三种修改值的方式

//以下两种声明都可以 因为一维度数组作为参数传递时就是传入指针
//void changeValue(int array[], int size, int oldValue, int newValue)
void changeValue(int* array, int size, int oldValue, int newValue)
{
    //之所以要存在一个容量参数 是因为数组名到函数内部 就变成一个指针了
    //容量就不能够获取到了 始终 sizeof(形参数组名) 是8
    cout << sizeof(array) << endl; //8 因为指针变量的长度是8
    int* p = array;
    for (int i = 0; i < size; i++)
    {
        if (array[i] == oldValue)
        {
            //三种不同的打印方式
            //array[i] = newValue;
            *(array + i) = newValue;
            //*p = newValue;
        }
        ++p;
    }
}

int array[] = { 1,2,3,4,5 };
changeValue(array, 5, 3, 99);
for (int i = 0; i < sizeof(array) / 4; i++)
{
    cout << array[i] << endl;
}
//1 2 99 4 5

有一个函数,可以传入一个二维数组,请声明这个函数,并在该函数中遍历打印传入的二维数组

//以下两种声明都可以 因为二维度数组作为参数传递时就是传入数组指针  
//数组指针必须指明列数 所以假如传二维数组也得传列数  
//void printArray(int array[][4], int rows)
void printArray(int(*arrray)[4], int rows)
{
    cout << sizeof(arrray) << endl; //8 因为指针变量的长度是8

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            cout << arrray[i][j] << endl;
            //cout << *(*(p + i) + j) << endl;
        }
    }
}

int array2[2][4] = { 1,2,3,4,
                     5,6,7,8 };
printArray(array2, 2); // 1 2 3 4 5 6 7 8

23.4 练习题代码

Lesson23_练习题.cpp

#include <iostream>
using namespace std;

//void changeValue(int array[], int size, int oldValue, int newValue);
void changeValue(int* array, int size, int oldValue, int newValue);

//void printArray(int array[][4], int rows);
void printArray(int(*p)[4], int rows);

int main()
{
    std::cout << "指针变量作为函数参数 练习题\n";

    #pragma region 练习题一

    int array[] = { 1,2,3,4,5 };
    changeValue(array, 5, 3, 99);
    for (int i = 0; i < sizeof(array) / 4; i++)
    {
        cout << array[i] << endl;
    }
    //1 2 99 4 5

    #pragma endregion

    #pragma region 练习题一

    int array2[2][4] = { 1,2,3,4,
                         5,6,7,8 };
    printArray(array2, 2);// 1 2 3 4 5 6 7 8

    #pragma endregion
}
#pragma region 练习题一

//有一个函数,可以传入一个一维数组
//我们传入一个{ 1,2,3,4,5 },请在该函数内部将其中的3改成99
//注意:请在函数中写出三种修改值的方式

//以下两种声明都可以 因为一维度数组作为参数传递时就是传入指针
//void changeValue(int array[], int size, int oldValue, int newValue)
void changeValue(int* array, int size, int oldValue, int newValue)
{
    //之所以要存在一个容量参数 是因为数组名到函数内部 就变成一个指针了
    //容量就不能够获取到了 始终 sizeof(形参数组名) 是8
    cout << sizeof(array) << endl;//8 因为指针变量的长度是8
    int* p = array;
    for (int i = 0; i < size; i++)
    {
        if (array[i] == oldValue)
        {
            //三种不同的打印方式
            //array[i] = newValue;
            *(array + i) = newValue;
            //*p = newValue;
        }
        ++p;
    }
}

#pragma endregion

#pragma region 练习题二

//有一个函数,可以传入一个二维数组
//请声明这个函数,并在该函数中遍历打印传入的二维数组

//以下两种声明都可以 因为二维度数组作为参数传递时就是传入数组指针 
//数组指针必须指明列数 所以假如传二维数组也得传列数
//void printArray(int array[][4], int rows)
void printArray(int(*arrray)[4], int rows)
{
    cout << sizeof(arrray) << endl;//8 因为指针变量的长度是8

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            cout << arrray[i][j] << endl;
            //cout << *(*(p + i) + j) << endl;
        }
    }
}

#pragma endregion


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏