2009-06-28 43 views
7

Tôi đang viết một chương trình C nhỏ để làm một số crunching số, và nó cần phải vượt qua xung quanh mảng giữa các chức năng. Các chức năng nên chấp nhận và trả về con trỏ, phải không?Có phải con trỏ và mảng nào khác trong C?

Ví dụ, điều này (tôi biết nó có thể không phải là điều hiệu quả nhất):

int* reverse(int* l, int len) { 
    int* reversed = malloc(sizeof(*reversed)*len); 
    int i, j; 
    for (i = 0, j = len-1; i < len; i++, j--) { 
     reversed[j] = l[i]; 
    } 
    return reversed; 
} 

Am Tôi sử dụng con trỏ phải không?

+1

dụ vẻ của bạn khỏe. Chủ đề rộng hơn về sự khác biệt giữa mảng và con trỏ đã được giải quyết ở đây trước đây, chẳng hạn như tại http://stackoverflow.com/questions/660752/pointer-vs-array-in-c-non-trivial-difference. –

+0

(Điều này sẽ không đủ điều kiện như một câu trả lời) Các đại số mảng và con trỏ chỉ khác nhau trong sizeof (array_name) trả về số lượng các phần tử array_name, không phải là kích thước của mảng theo byte. – jpinto3912

Trả lời

14

đoạn mã của bạn là chính xác. Tuy nhiên, con trỏ và mảng trong C thực sự khác nhau. Đặt đơn giản là "con trỏ để gõ T" không giống như "mảng kiểu T".

Vui lòng xem C Faq thảo luận các con trỏ & mảng để hiểu rõ hơn về điều này.

+2

Được bình chọn cho C Faq - chi tiết hơn câu trả lời của bạn sẽ nhận được trên SO. –

+1

+1 cho C FAQ –

1

Từ góc độ thấp, một mảng là một đoạn bộ nhớ liên tục được truy cập bởi địa chỉ đầu đoạn đó và phần bù, do đó từ mức trừu tượng đó, nó là một con trỏ. Tuy nhiên, từ góc độ ngôn ngữ C, một kiểu mảng khác với kiểu con trỏ. Về cơ bản một mảng có thể được gán cho một giá trị con trỏ nhưng nó không cùng loại.

Đối với mục đích của chức năng của bạn, bạn đang làm OK.

+3

tuyên bố táo bạo của bạn cầu xin giải thích. –

+0

nevermind, Crashworks đã giải thích nó là –

0

mảng trong C được đại diện và thao túng bởi một con trỏ đến phần tử đầu tiên, ví dụ

int arr[50]; 
int * ptr1 = arr; 
int * ptr2 = &arr[0]; 

trong ví dụ này, ptr1 == ptr2 vì địa chỉ của phần tử đầu tiên của mảng và con trỏ cơ sở cho mảng giống nhau.

để dụ cơ bản của bạn là đúng, mặc dù tôi nghi ngờ rằng malloc có lẽ nên được:

int* reversed = malloc(sizeof(int)*len); 

+0

Đó chỉ là trường hợp tôi muốn thay đổi nó thành cái gì đó khác (ví dụ: 'long') nên tôi sẽ không phải thay đổi hai thứ. – Javier

+1

Không, malloc của anh ấy tốt (và thích hợp hơn với bạn) từ C99. – smcameron

+0

@ [smcameron]: @reyjavikvi]: một kỹ thuật thú vị (tôi không nhận thấy tiền tố * lần đầu tiên, xin lỗi về điều đó!). Tôi đã học C vào năm 1982 và đã không sử dụng nó rất nhiều kể từ năm 1994, vì vậy tôi chưa bao giờ đọc thông số C99 (phải bỏ lỡ bản ghi nhớ đó! ;-)) –

1

Về lý thuyết pedantic, mảng và con trỏ những thứ khác nhau, từ một mảng chỉ định một khu vực bộ nhớ và do đó kích thước của một mảng là một phần của loại của nó. Vì vậy, người ta nói rằng một tên mảng phân rã thành con trỏ khi được sử dụng trong ngữ cảnh đó. There's a detailed explanation in the C-FAQ.

Trong thực tế, chúng giống nhau kể từ khi chính thức a[i] giống như *(a+i) và do đó trình biên dịch kết thúc xử lý tên mảng và con trỏ theo cùng một cách. Sự khác biệt duy nhất đáng lo ngại là:

void foo() 
{ 
    int a[5]; // allocates five words of space on the stack 
    int *b; // allocates *one* word of space on the stack (to hold the pointer) 
} 

Đoạn mã của bạn là tốt. Chỉ cần cẩn thận để giải phóng bộ nhớ mà chức năng của bạn malloc() s trong bất cứ ai gọi nó.

2

Một liên kết đến C-FAQ: Mảng và con trỏ đã được trao đã có, nhưng đó cũng là một lời giải thích thấu đáo trong C for Smarties: Arrays and Pointers. Bạn có thể muốn đọc trang "Phân tích biểu thức" trước tiên.

Một vài điều về ví dụ của bạn mà nên được sửa chữa:

  1. Sử dụng int thay vì đúng size_t để lưu trữ kích thước đối tượng.
  2. Không kiểm tra giá trị trả lại của malloc().

Một cách để "sửa chữa" Vấn đề thứ hai này là để cho người gọi quyết định nơi sản lượng được lưu trữ (có lẽ người gọi không muốn hoặc cần một mảng mới được phân bổ):

int *reverse(int *out, int *l, size_t len) { 
    size_t i, j; 
    for (i = 0, j = len - 1; i < len; ++i, --j) { 
    out[j] = l[i]; 
    } 
    return out; 
} 
Các vấn đề liên quan