在 C++ 中,通常有两种传递数组的方法。一种确实使用模板并且是 C++ 特定的,另一种不使用模板并且可以在 C 和 C++ 程序中使用。以下是模板版本的示例:
#include <cstddef> // for std::size_t
#include <iostream> // for std::cout
#include <algorithm> // for std::copy
#include <iterator> // for std::ostream_iterator
template <std::size_t length>
static void accept_array(const int (&array)[length])
{
std::cout << "Got array of " << length << " elements:\t";
std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
std::cout << " and that's all.\n";
}
int main()
{
int arr[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
accept_array(arr);
}
这是非模板方式的示例:
#include <cstddef> // for std::size_t
#include <iostream> // for std::cout
#include <algorithm> // for std::copy
#include <iterator> // for std::ostream_iterator
static void accept_array(const int *array, std::size_t length)
{
std::cout << "Got array of " << length << " elements:\t";
std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
std::cout << " and that's all.\n";
}
int main()
{
int arr[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
accept_array(arr, 10);
}
请注意,在这两种情况下,数组本身都会衰减为指针。换句话说,它在两种情况下都被传递给accept_array()
函数。const int *array
唯一的区别是在模板版本中,编译器会帮助您自动确定数组的大小。
但是请注意,编译器并不总是知道数组的长度(数组下标)。例如,代码可能更复杂并涉及动态分配,在这种情况下,编译器唯一知道的是它是一个指向一个或多个元素的指针,但它不知道有多少元素(如果有的话) :-))。这是一个使用模板版本不方便的示例(即使坚持不懈的程序员仍然可以通过潜在的不安全类型转换来使用它):
#include <cstddef> // for std::size_t
#include <iostream> // for std::cout
#include <algorithm> // for std::copy
#include <iterator> // for std::ostream_iterator
static void accept_array(const int *array, std::size_t length)
{
std::cout << "Got array of " << length << " elements:\t";
std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
std::cout << " and that's all.\n";
}
int main()
{
int *a1 = new int[5];
for (int i = 0; i < 5; ++i)
a1[i] = i+1;
accept_array(a1, 5); // In here, we know we have just allocated 5 elements.
// But compiler doesn't really know it. So calling a
// template version just like that won't work. We must
// know how the length of the array...
delete [] a1; // Never forget to free what you have allocated :)
}
因此,对于动态数组,您始终必须知道长度。但是,有时当程序员不想携带数组的长度时,他们可以引入一个用于确定数组结尾的约定(以避免访问无效的内存/元素)。例如,程序员可能会说,无论数组有多长,最后一个元素将始终为 0。并且在构建代码时考虑到了这一点(这有点危险,需要格外小心,并且可能不允许存储某些数组中的值——如果没有其他代码认为它是数组结束指示符而不是正常值,你不能在数组中有 0 值)。大多数情况下,这种方法用于指针数组,程序员同意 nil 指针是结束的指示符。但是字符串是这种方法的一个很好的例子\0
是字符串结束指示符。例如:
#include <iostream>
static unsigned int my_strlen(const char *value)
{
// How long is our string? We don't really know unless we
// go through its characters and count them until we see '\0'.
// WARNING: Please do not use this function in your code as it is
// extremely inefficient and serves an example purpose:
unsigned int result = 0;
while (value[result] != '\0')
++result;
return result;
}
int main()
{
const char str[] = "Hello, world!";
std::cout << "The length of '" << str << "' is " << my_strlen(str)
<< " bytes.\nThe size of the array where the data is stored is "
<< sizeof(str)/sizeof(str[0]) << " bytes.\n";
}
此外,模板版本在某些情况下可能非常有用。例如,您可以使用编译时断言来确保数组长度足够或数组不会太大。您也可以将两种方法混合在一起。这是一个完整的示例供您参考:
#include <cstddef>
#include <iostream>
#include <algorithm>
#include <iterator>
static void accept_array(const int *array, std::size_t length)
{
std::cout << "Got array of " << length << " elements:\t";
std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
std::cout << " and that's all.\n";
}
template <std::size_t length>
static void accept_array(const int (&array)[length])
{
// Generally, we can just call a non-template version.
// However, in this case "length" is a compile-time expression
// and we can benefit from that. For example, by not letting users
// compile if array length is more than 10 elements:
static_assert(length <= 10, "Array is way too large"); // Beware: C++11 feature.
accept_array(array, length);
}
int main()
{
int *a1 = new int[5];
for (int i = 0; i < 5; ++i)
a1[i] = i+1;
accept_array(a1, 5);
delete [] a1;
int a2[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
accept_array(a2);
accept_array(a2, sizeof(a2)/sizeof(a2[0]));
// The below code would fail to compile:
// int a3[11] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
// accept_array(a3);
}
哦,我差点忘了给你看一个矩阵的例子。它的工作原理完全相同。为了保持简短,我不会做模板版本,因为您的程序不知道编译时矩阵的长度,而是使用运行时用户的输入。以下是我将如何编写您的代码:
#include <cstdlib>
#include <iostream>
#include <cmath>
static void grab_matrix(int **matrix, int nS)
{
std::cout << "Enter the elements of first matrix ("
<< nS << " by " << nS << "): " << std::flush;
for (int c = 0; c < nS; ++c)
for (int d = 0 ; d < nS; ++d)
std::cin >> matrix[c][d];
std::cout << "Thank you! You have entered the following:\n";
for (int c = 0; c < nS; ++c) {
for (int d = 0 ; d < nS ; d++ )
std::cout << matrix[c][d] << "\t";
std::cout << '\n';
}
std::cout << std::flush;
}
static void det(int **matrix, int nS)
{
std::cout << "Calculations:\n" << std::flush;
double d = 0;
for (int i = 0; i < nS; ++i) {
double a = 0;
double b = 0;
for (int c = 0; c < nS; ++c) {
int z = (i + c) % nS;
a *= matrix[c][z];
b *= matrix[c][(nS - 1) - (i + c) % nS];
std::cout << c << ", " << z << '\n';
}
d += a - b;
}
std::cout << d << std::endl;
}
int main()
{
std::cout << "Enter the number of rows and columns of matrix: "
<< std::flush;
int nS = 0;
std::cin >> nS;
if (nS <= 0) {
std::cerr << "Sorry, that's not a good number. Try again later!\n";
return EXIT_FAILURE;
}
int **matrix = new int*[nS];
for (int i = 0; i < nS; ++i)
matrix[i] = new int[nS];
grab_matrix(matrix, nS);
det(matrix, nS);
for (int i = 0; i < nS; ++i)
delete [] matrix[i];
delete [] matrix;
}
希望能帮助到你。祝你好运!