2013-08-21 25 views
5

Đối với chương trình được đưa ra dưới đây, tại sao các giá trị khác nhau đầu tiên cho argv&argv? Số printf thứ hai in cùng giá trị cho a&a. Cơ chế mà các biến đối số được truyền cho chương trình được lưu trữ là gì?Đầu ra khác nhau giữa các chuỗi argv và mảng thông thường

#include<stdio.h> 
    int main(int argc, char * argv[]){ 
    char * a[10]; 
    printf("%d %d\n\n",argv,&argv); 
    printf("%d %d",a,&a); 
    return 0; 
} 

cơ chế lưu trữ đối số dòng lệnh để một mảng của chuỗi

+1

printf ("% d% d", a, &a); tại đây & a và sẽ trỏ đến cùng một địa chỉ ... do đó bạn không cần phải in cả hai và sử dụng% p thay vì% d để in địa chỉ. – sunny1304

+0

Tôi nghĩ thats bởi vì con trỏ argv được khởi tạo nhưng con trỏ của bạn không phải là nó có cùng địa chỉ – Saxtheowl

Trả lời

5

Vấn đề là gì không phải là về argv là đặc biệt, nhưng về chức năng lập luận đi qua. Hãy thử chương trình này:

#include<stdio.h> 

void foo(int a[]) 
{ 
    int b[10]; 
    printf("foo :%p %p\n",a,&a); 
    printf("foo :%p %p\n",b,&b); 
} 

int main(int argc, char* argv[]) 
{ 
    int a[10]; 
    printf("main:%p %p\n", a, &a); 
    foo(a); 
    return 0; 
} 

Sản lượng trong máy của tôi:

main:0x7fffb4ded680 0x7fffb4ded680 
foo :0x7fffb4ded680 0x7fffb4ded628 
foo :0x7fffb4ded630 0x7fffb4ded630 

Dòng đầu tiên và thứ ba là không đáng ngạc nhiên vì đối với một mảng arr, arr&arr có cùng giá trị. Dòng thứ hai cần được giải thích.

Như bạn có thể thấy, khi a được truyền trong hàm foo, giá trị của a là không thay đổi, nhưng địa chỉ &a được thay đổi kể từ khi chức năng C luôn vượt qua đối số theo giá trị, sẽ có một bản sao cục bộ của các đối số bên trong hàm.

Điều này giống với argv vì đó chỉ là một đối số trong hàm main.


EDIT: Đối với những người không đồng ý với tôi, câu trả lời của tôi không phải là chống lại các câu trả lời khác. Ngược lại, họ hoàn thành lẫn nhau. argv là một con trỏ chính xác bởi vì nó là một mảng được truyền như đối số hàm và nó "phân rã" thành một con trỏ. Một lần nữa, argv không phải là đặc biệt, nó hoạt động không khác với các mảng khác được chuyển làm đối số hàm, đó là toàn bộ điểm của mã ví dụ của tôi.

+0

Mã ví dụ đẹp! Tôi chỉ nghĩ rằng 'argv' trong chính có một số nơi đặc biệt trước khi tôi nhìn thấy câu trả lời của bạn! –

+0

Đây không thực sự là câu trả lời. Đối với bất kỳ biến 'a' nào của kiểu mảng,' & a' và 'a' là con trỏ sẽ * luôn * có cùng địa chỉ. Đây là kết quả của cách các kiểu mảng trong C hoạt động. Sự khác biệt là 'argv' không thuộc loại mảng. – newacct

+0

@newacct Vậy tại sao 'argv' là một con trỏ? Chính xác bởi vì nó được chuyển thành đối số hàm và "bị phân rã" thành một con trỏ. –

4

Sự khác biệt giữa argva trong ví dụ của bạn sau từ đoạn 6.7.6.3 quảng cáo 7 của C-tiêu chuẩn:

Một tuyên bố của một tham số là '' mảng của loại '' sẽ được điều chỉnh để '' con trỏ đủ điều kiện để nhập '', trong đó các loại vòng loại (nếu có) là các giá trị được chỉ định trong [và] của dẫn xuất loại mảng. Nếu từ khóa static cũng xuất hiện bên trong [và] của kiểu dẫn xuất mảng, thì đối với mỗi cuộc gọi đến hàm, giá trị của đối số thực tế tương ứng sẽ cung cấp quyền truy cập vào phần tử đầu tiên của một mảng có ít nhất là nhiều phần tử như được chỉ định bởi biểu thức kích thước.

Như một hệ quả argv là một con trỏ trong đó có địa chỉ riêng của mình, trong khi a là một mảng và a điểm đến địa chỉ của phần tử đầu tiên của mảng, mà là giống như địa chỉ của mảng.

+0

+1 đây là câu trả lời thực sự – newacct

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