关于 function 的基础教程参考:C++ 入门教程之四 -- Functions

当 function 的传入参数为数组时,如果我们想要得到数组元素个数可能会这样写:

void testFunc(int arr[]) {
    int count = sizeof(arr)/sizeof(arr[0]);
}

int main()
{
    int arr[] = {1, 3, 6, 8};
    cout << testFunc(arr) << endl;

    return 0;
}

sizeof function 可以返回数据占用内存空间的大小。所以用整个 arr 大小除以第一个元素大小可以得到数组元素个数。

但是测试会发现以上得到的 count 值并不是 arr 数组元素个数 4 而是 2。这是因为当 function 传入数组数据时,会自动将其转换为 pointer 指针类型。这时候使用 sizeof() 得到的不是 arr 数据所在地址的内存大小,而是这个指向 arr 数组的指针所占用内存大小。

我们做个实验:

int main()
{
    int *arrP = new int[4];
    cout << sizeof(arrP) << endl;
    cout << sizeof(arrP[0]) << endl;
    return 0;
}

//output:
//8
//4

以上建立了一个指针指向 4 个元素的数组,然后分别查看其整个指针和某个元素指针的内存大小,得到的结果是 8 和 4。所以他们两个相除结果为 2。

因为指针指向的是数组第一个元素,如果我们要通过指针给数组元素赋值,可以使用 *(pointer + n) 的方式完成,例如:

int *arrP = new int[4];
*arrP = 1;
*(arrP+1) = 2;

*(arrP+1) 就是第 2 个数组元素。

可以用指针查询数组中某个元素的内存大小,数组名 arr 表示数组所在地址(不需要加地址转换符&):

int main()
{
    int arr[] = {1, 3, 6, 8};
    int *arrP = arr;

    cout << sizeof(*arrP) << endl;
    cout << sizeof(*(arrP+1)) << endl;

    return 0;
}

//output:
//4
//4

由于 arr 数组名表示此数组第一个元素所在地址的指针,所以我们可以直接使用此名称来用指针的方式地区元素数据:

int main()
{
    int arr[] = {1, 3, 6, 8};
    cout << *arr << endl;
    cout << *(arr+1) << endl;

    return 0;
}

//output:
//1
//3

那么如何在 function 使用数组作为传入数据时如何能够直接使用它的数据而不是指针类型呢?可以使用以下方法:

template <size_t N>
int testFunc(int (&arr)[N]) {
    int count = sizeof(arr) / sizeof(arr[0]);
    return count;
}

int main()
{
    int arr[] = {1, 3, 6, 8};
    int count = testFunc(arr);

    cout << count << endl;
    return 0;
}

//OUTPUT:
//4

创建一个 function template,size_t 类型表示任意数据类型的元素占用内存大小,此处将其作为 generic data type 用来定义实际传入的数组所占用内存容量的 template,然后以传入数据的实际地址的模式将数组的元素都顺序都传入 function。这样传入数据就是实际数据地址而不是指针。

关于 function 的传入数据实际地址是使用指针形式 * 还是 & 形式,在前面我介绍过,形式如下:

void test1(int *a) {
    *a = 3;
}

void test2(int &a) {
    a = 2;
}

int main()
{
    int a = 1;
    int *p = &a;

    test1(p);
    cout << a << endl;

    test2(a);
    cout << a << endl;

    return 0;
}

//OUTPUT:
//3
//2

function 中使用在指针类型的传入数据时需要传入一个指针,当定义为 & 时可以直接传入数据名称。两种方法都是 by reference 会影响到对应内存地址的数据内容。可参考教程:C++ 入门教程之四 -- Functions

参考链接:
https://stackoverflow.com/questions/4839626/element-count-of-an-array-in-c
https://www.tutorialspoint.com/cplusplus/cpp_pointer_to_an_array.htm

标签: none

添加新评论