2013-01-13 44 views
41
#include <iostream> 
using namespace std; 

void printarray (int arg[], int length) { 
    for (int n = 0; n < length; n++) { 
     cout << arg[n] << " "; 
     cout << "\n"; 
    } 
} 

int main() 
{ 
    int firstarray[] = {5, 10, 15}; 
    int secondarray[] = {2, 4, 6, 8, 10}; 
    printarray(firstarray, 3); 
    printarray(secondarray, 5); 

    return 0; 
} 

Mã này hoạt động, nhưng tôi muốn hiểu cách mảng được truyền.Truyền mảng sang hàm trong C++

Khi có cuộc gọi đến chức năng printarray từ chức năng chính, tên của mảng đang được chuyển. Tên của mảng đề cập đến địa chỉ của phần tử đầu tiên của mảng. Làm thế nào để điều này tương đương với int arg[]?

+0

Chỉ cần cụ thể, tên của mảng đề cập đến mảng. Nó có thể được chuyển đổi thành một con trỏ đến phần tử đầu tiên, đó là những gì xảy ra trong hầu hết các trường hợp. –

Trả lời

20

Các cú pháp

int[] 

int[X] // Where X is a compile-time positive integer 

Are chính xác giống như

int* 

Khi trong một danh sách tham số chức năng (tôi rời ra những cái tên không bắt buộc).

Ngoài ra, tên mảng phân rã thành con trỏ thành phần tử đầu tiên khi được chuyển đến hàm (và không được chuyển theo tham chiếu) sao cho cả số int firstarray[3]int secondarray[5] phân rã thành int* s. Nó cũng xảy ra rằng cả một dereference mảng và một dereference con trỏ với cú pháp subscript (cú pháp subscript là x[y]) mang lại một lvalue cho cùng một yếu tố khi bạn sử dụng cùng một chỉ mục.

Ba quy tắc này kết hợp để làm cho mã hợp pháp và hoạt động như thế nào bạn mong đợi; nó chỉ chuyển các con trỏ tới hàm, cùng với chiều dài của các mảng mà bạn không thể biết sau khi mảng bị phân rã thành con trỏ.

+8

Hoàn toàn sai. 'int []' và 'int [X]' là các kiểu mảng và chúng theo cách đó. Các mảng để phân rã con trỏ là một chuyển đổi tiềm ẩn của các biến với loại mảng để một con trỏ của phần tử đầu tiên của họ, khi đó là dự kiến. Điều gì xảy ra với khai báo hàm này là hoàn toàn khác nhau - kiểu tham số hàm được điều chỉnh thành một con trỏ tới phần tử đầu tiên của nó - và đây không phải là một mảng để phân rã con trỏ. Tôi không biết tại sao không ai nói với bạn điều đó. – AnArrayOfFunctions

+0

Vui lòng tự học và đọc [this] (https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/hwQWZ_uvXDI) – AnArrayOfFunctions

+0

Nửa đầu của câu trả lời này là sai. Tham số 'int [X]' không giống với 'int *'. – Navin

7

firstarraysecondarray được chuyển thành con trỏ thành int, khi được chuyển đến printarray().

printarray(int arg[], ...) tương đương với printarray(int *arg, ...)

Tuy nhiên, đây không phải là đặc trưng cho C++. C có cùng các quy tắc để truyền các tên mảng cho một hàm.

10

Tôi chỉ muốn thêm này, khi bạn truy cập vào vị trí của mảng như

arg[n]

cũng giống như

*(arg + n) hơn có nghĩa là một bù đắp của n bắt đầu từ de địa chỉ arg.

nên arg[] sẽ *arg

0

Câu hỏi đặt ra đã được trả lời, nhưng tôi nghĩ rằng tôi muốn thêm một câu trả lời với thuật ngữ chính xác hơn và tài liệu tham khảo để chuẩn C++.

Hai điều đang diễn ra ở đây, tham số mảng được điều chỉnh theo thông số con trỏđối số mảng được chuyển đổi thành đối số con trỏ. Đây là hai cơ chế khá khác nhau, đầu tiên là một điều chỉnh đối với loại thực tế của tham số, trong khi cái kia là một chuyển đổi tiêu chuẩn giới thiệu một con trỏ tạm thời đến phần tử đầu tiên.

Adjustments để khai báo hàm bạn:

dcl.fct#5:

Sau khi xác định kiểu của mỗi tham số, bất kỳ tham số có kiểu “mảng của T” (...) được điều chỉnh "Con trỏ đến T".

Vì vậy, int arg[] được điều chỉnh là int* arg.

chuyển đổi của các đối số chức năng của bạn:

conv.array#1

Một vế trái hoặc rvalue kiểu “mảng của NT” hoặc “mảng không rõ ràng buộc của T” có thể được chuyển đổi sang một prvalue của gõ "con trỏ đến T". Chuyển đổi vật chất tạm thời được áp dụng. Kết quả là một con trỏ đến phần tử đầu tiên của mảng.

Vì vậy, trong printarray(firstarray, 3);, vế trái firstarray kiểu "mảng của 3 int" được chuyển thành một prvalue (tạm thời) của kiểu "con trỏ đến int", trỏ đến phần tử đầu tiên.

Các vấn đề liên quan