在 C++ 中将数组作为参数传递 [英] Passing an array as an argument in C++

查看:29
本文介绍了在 C++ 中将数组作为参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个合并排序函数,现在我只是在使用一个测试用例数组(没有输入 - 现在是静态的).我不知道如何将数组作为参数传递.这是我现在的代码:

I'm writing a merge sort function, and right now I am just using a test case array (there is no input - this is static, for now). I don't know how to pass an array as an argument. Here is my code right now:

//merge sort first attempt

#include <iostream>

#include <algorithm>

#include <vector>

int mergeSort(int[]);
int main() {
    int originalarray[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };
    mergeSort(originalarray[]);
}

int mergeSort(int[] originalarray) {
    int num = (sizeof(originalarray) / sizeof(int));
    std::vector < int > original(num);

    if (num > 2) {
        return num;
    }

    // Fill the array using the elements of originalarray
    // This is just for demonstration, normally original will be a parameter,
    // so you won't be filling it up with anything.
    std::copy(originalarray, originalarray + num, original.begin());

    // Create farray and sarray of the appropriate size
    std::vector < int > farray(num / 2);
    std::vector < int > sarray(num - farray.size());

    // Fill those using elements from original
    std::copy(original.begin(), original.begin() + farray.size(), farray.begin());
    std::copy(original.begin() + farray.size(), original.end(), sarray.begin());

    mergeSort(farray);
    mergeSort(sarray);
}

请注意,这个 mergeSort 函数不起作用,因为我还没有想出如何合并它们(这是我的任务).我想在处理之前对我的两个向量进行排序,但我无法编译它,因为我需要将数组作为参数传递.我不明白指针,所以如果这是解决方案,我的借口是无知.我现在正在学习编程,以 C++ 作为第一语言,并且只对语言的特性有基本的了解.感谢您的帮助.

Note that this mergeSort function is not functional, as I have not figured out how to merge them yet (that's my assignment). I would like to get my two vectors sorted before I deal with that, and I can't compile this because of my need to pass an array as an argument. I don't understand pointers, so if that is the solution, my excuse is ignorance. I'm learning programming right now, with C++ as a first language, and only have a basic grasp of the language's features. Thanks for the help.

推荐答案

稍微扩展一下,请记住 C++ 数组正是 C 数组.所以你所拥有的只是一块声称(不保证)是一个数组的内存的地址.

Jut to extend this a bit, remember that C++ arrays are exactly C arrays. So all you have is the address of a piece of memory that purports (with no guarantees) to be an array of somethings.

好的,我们再扩展一点.

Okay, we'll expand a little more.

C(因此也是 C++)并没有真正的数组";像这样.它只有地址和指针.因此,当您将某个东西创建为数组"时,真正发生的事情是您告诉编译器某个变量表示一个地址.

C (and therefore C++) doesn't really have "arrays" as such. All it has are addresses, pointers. So when you make something an "array", what really happens is you tell the compiler that some variable represents an address.

在 C 中区分声明定义很有用.在声明中,您只是给某物一个名称和一个类型;在定义中,您实际上分配了空间.

It's useful to make a distinction in C between a declaration and a definition. In a declaration, you're simply giving something a name and a type; in a definition, you actually allocate space.

所以,如果我们从定义一个数组开始

So, if we start off by definiing an array like

int ar[100];

这意味着我们告诉编译器我们想要 100 个 int 的空间,我们希望它全部分配在一个块中,我们将使用名称 ar 为它.sizeof 运算符给出了类型或对象使用的字节数,因此我们的数组 ar 将占用 100×sizeof(int)字节.在大多数机器上,这将是 400 字节,但它因机器而异.

that means we're telling the compiler we want space for 100 int's, we want it to all be allocated in one chunk, and we're going to use the name ar for it. The sizeof operator gives the number of bytes used by a type or an object, so our array ar will take up 100×sizeof(int) bytes. On most machines, that will be 400 bytes, but it varies from machine to machine.

如果我们定义一个变量

int * ar_p;   // using '_p' as a reminder this is a pointer

我们正在为包含地址的变量定义空间.它的大小将是 sizeof(int*),通常是 4 或 8,但在某些机器上可能是 2 到 16,而在某些机器上,您不太可能很快遇到.

we're defining space for a variable that will contain an address. Its size will be sizeof(int*), which will usually be either 4 or 8, but on some machines could be anything from 2 to 16 on some machines you're unlikely to run into soon.

数组的名称ar.编译器将该名称转换为地址,因此我们可以使用

The name of the array is ar. The compiler converts that name into an address, so we can save that address with

ar_p = ar ;     // THIS WORKS

现在,为了方便起见,我们假设我们的数组 ar 恰好从内存中的位置 1000 开始.

Now, let's say for convenience that our array ar happened to be starting at location 1000 in memory.

那个名字ar没有分配给它任何空间;它就像一个常数,一个数字.所以,你不能撤销那个分配

That name ar does not have any space allocated to it; it's like a constant, a number. So, you can't reverse that assignment

ar = ar_p ;     // THIS WON'T WORK

出于同样的原因你不能说

for the same reason you couldn't say

1000 = ar_p ;   // THIS WON'T WORK EITHER

即,您不能更改 1000 的值.(在 FORTRAN 的早期版本中,由于复杂的原因,这个技巧会起作用.这是一个错误.直到您尝试调试程序,其中2"的值为 3.)

ie, you can't change the value of 1000. (Back in early versions of FORTRAN, this trick would work, for complicated reasons. It was a mistake. You've never lived until you've tried to debug a program in which the value of "2" is 3.)

C 中的数组总是从零开始的,即第一个索引总是零.任何其他索引只是使用索引计算的地址.所以,ar[0] 只是地址 1000 加上 0 字节的偏移量,或 1000.ar[1] 是 1000 加上 大小的 1 倍int,所以 next int 结束.事实上,这在 C 中总是正确的.

Arrays in C are always zero-based, that is, the first index is always zero. Any other indices are just addresses computed using the index. So, ar[0] is just the address 1000 plus 0 bytes of offset, or 1000. ar[1] is 1000 plus 1 times the size of an int, so the next int over. And in fact, this is always true in C.

这称为数组引用.

当我们使用语法*ar_p 时,我们告诉编译器从ar_p 中包含的地址获取事物.`.

When we use the syntax *ar_p we're telling the compiler to get the thing AT the address contained in ar_p. `.

这称为解除对指针的引用.

如果我们说

ar_p = ar;

那么 *ar_par[0] 指的是同一个东西.

then *ar_p and ar[0] refer to the same thing.

当我们说ar[0]时,我们告诉编译器我们想要ar地址0字节处的东西.ar[1] 是地址一 int,或 4 个字节,来自 ar.所以,*(ar_p+3)ar[3] 指的是同一个东西.(我们需要括号,因为我们要先把地址加3,然后再看内容.*ar_p+3 会先得到ap_p指向的内容,然后将 3 添加到那些中.

When we say ar[0] we're telling the compiler we want the thing at the address 0 bytes from ar. ar[1] is the address one int, or 4 bytes, from ar. So, *(ar_p+3) refers to the same thing as ar[3]. (We need the parentheses because we want to add 3 to the address first and then look at the contents. *ar_p+3 would get the contents pointed to by ap_p first, and then add 3 to those.

问题是,C 不知道,也不知道数组到底有多大.如果我来执行 ar[365],编译器会很高兴地生成代码以查看单元格 1000+(365×sizeof(int)).如果它在您的数组中,那很好,但如果它只是随机内存,那也很好.C 不在乎.

The thing is, C doesn't know, or much care, how big the array really is. If I come along and do ar[365], the compiler will happily generate code to look in the cell 1000+(365×sizeof(int)). If that's in your array, fine, but if it's just random memory, that's fine too. C doesn't care.

(记住 C 来自电话公司.我们不在乎;我们没有必要.我们是电话公司.")

(Remember C comes from the phone company. "We don't care; we don't have to. We're the Phone Company.")

所以,现在,我们知道了一些规则,我已经移到这里了.阅读≡"因为相当于"或与"相同.

So, now, we know some rules, which I've moved down here. Read "≡" as "is equivalent to" or "is the same as".

你可以依赖什么:

  • foo(TYPE t[])foo(TYPE * t)

由于 C 不知道指针和数组之间的区别,因此您可以声明任何一个.定义函数的时候可以写

Since C doesn't know a difference between pointers and arrays, you can declare either one. When you define a function, you can write

void foo(int[] ar){

void foo(int* ar){

并获得完全相同的效果.

and get exactly the same effect.

  • t[i]*(t+i)

这是上面.任何你可能会写 ar[i] 的地方,你都可以用 *(ar+i) 替换它.(实际上有一个奇怪的附带案例打破了这一点,但作为初学者,您不会遇到它.)

This was above. Anywhere you might write ar[i], you can replace it with *(ar+i). (There's actually a weird side case that breaks this, but you won't run into it as a beginner.)

  • where TYPE *t, (t+i) 将等于 t 处的地址加上 i*sizeof(TYPE)
  • where TYPE *t, (t+i) will equal the address at t plus i*sizeof(TYPE)

上面也解释了这一点.当您对数组进行索引时,例如 ar[42],这意味着您想要从起始地址开始的第 42 位.因此,如果您使用 int,那么无论 int 有多宽,您都需要移动 42 倍,也就是说 sizeof(int).

Explained this above as well. When you index into an array, like ar[42], it means you want the 42nd whatever over from the start address. So, if you're using int, then you need to move over 42 times however wide an int is, which is to say sizeof(int).

现在,这就是所有的 C,而且由于 C++ 被定义为一种"C,它也适用于 C++.除了

Now, that's all C, and since C++ is defined as a "kind of" C, it all holds for C++ as well. EXCEPT

  • 除非 TYPE 是用户定义的类型,它重载了 operator[]operator*.
  • unless TYPE is a user defined type that overloads operator[] and operator*.

在 C++ 中,您可以决定定义一个新类型,其行为与任何其他类型一样,但您可以更改语言执行特定操作的方式.因此,程序员可以决定重载"程序.-- 即,用他们自己设计的东西替换 -- 数组引用和指针取消引用运算符的默认行为.作为初学者,您不应该很快面对,但您应该意识到这一点.

in C++, you can decide you want to define a new type that acts just like any other type, but you can change the way the language does specific things. So, a programmer can decide to "overload" -- ie, replace -- the default behavior of the array reference and pointer dereference operators with something of their own devising. As a beginner, you shouldn't be confronted with that soon, but you should be aware of it.

这篇关于在 C++ 中将数组作为参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆