2008-11-23 43 views
6

Tôi nghĩ rằng nếu một con trỏ trỏ đến một mảng char được tăng lên thì nó sẽ trỏ đến phần tử tiếp theo trong mảng đó. Nhưng khi tôi thử điều này tôi thấy rằng tôi phải tăng nó hai lần. Đang thử tăng bằng sizeof (char) tôi thấy rằng việc thêm kích thước của một char là quá nhiều nên nó phải được chia cho hai.Tăng thêm con trỏ C

#include <stdio.h> 

int main(int argc, char * argv[]){ 
    char *pi; 
    int i; 
    pi = argv[1]; 
    printf("%d args.\n",argc-1); 
    printf("input: "); 
    for(i=0;i<argc-1;i++){ 
     printf("%c, ",*pi); 
     /*The line below increments pi by 1 char worth of bytes */ 
     //pi+=sizeof(pi)/2; 
     /* An alternative to the above line is putting pi++ twice - why? */ 
     pi++; 
     pi++; 
    } 
    printf("\n"); 
    return 0; 
} 

Tôi có làm gì sai không? hoặc tôi hiểu lầm phương pháp tăng con trỏ?

Trả lời

4

Nếu bạn có một con trỏ ptr loại T* và bạn thêm N, sau đó con trỏ sẽ được nâng cao bởi N * sizeof (*ptr) hoặc tương đương N * sizeof (T) byte. Bạn chỉ đơn giản là quên dereference pi. Vì vậy, những gì bạn nhận được với sizeof (pi) là kích thước của char*, nhưng không phải là sizeof của char. Dòng của bạn tương đương với pi+=sizeof(char*)/2; Con trỏ trên nền tảng của bạn rộng 4 byte. Do đó, bạn đã thực hiện pi+=2;. Viết pi+=2 nếu bạn muốn tăng 2 lần. Lưu ý rằng char có sizeof là 1 theo định nghĩa. Bạn không cần phải làm sizeof (char), luôn luôn là 1.

20

sizeof (char) được đảm bảo bằng 1, nhưng sizeof (char *) thì không.

Tuy nhiên, chức năng của bạn chỉ hoạt động do tai nạn.

Ví dụ, thử gọi nó với các thông số sau:

abc defg 

này sẽ mang lại:

2 args. 
input: a, c, 

đó là đồng bằng sai. Vấn đề là bạn đang tăng một con trỏ đến phần tử 1 của argv thay vì một con trỏ tới argv.

Hãy thử điều này:

#include <stdio.h> 

int main(int argc, char * argv[]){ 
    char **pi; 
    int i; 

    pi = argv + 1; 
    printf("%d args.\n",argc-1); 
    printf("input: "); 
    for(i=0;i<argc-1;i++){ 
     printf("%c, ",**pi); 
     pi++; 
    } 
    printf("\n"); 
    return 0; 
} 

này sẽ in ký tự đầu tiên của tất cả các đối số:

2 args. 
input: a, d, 
3

sizeof (pi) đang trở lại kích thước của (char *), đó là các loại pi (một con trỏ, có thể là hai, bốn hoặc tám byte). sizeof (char) sẽ trả về 1.

Tuy nhiên, một điều cần hiểu là bất cứ khi nào bạn tăng con trỏ lên một số (ví dụ: pi + = sizeof (char); pi ++; v.v.) bạn đang tăng con trỏ lên kích thước cơ sở anyways. Vì vậy:

int *ipointer = &int_array[0]; 
ipointer += 2; 

sẽ thực sự tăng ipointer bởi 2 lần sizeof int.

Một điều khác mà bạn có vẻ đang làm sai là chỉ pi tại đối số đầu tiên và sau đó lặp qua tất cả các đối số. Nếu bạn muốn lặp qua các đối số, hãy thử một cái gì đó như sau:

for (i = 1; i < argc; i++) { 
    pi = argv[i]; 
    // ... do something with pi 
} 
+0

Ví dụ mã đầu tiên của bạn không hợp lệ "& int_array" có loại "con trỏ tới mảng int" không tương thích với "con trỏ tới int", bạn cần sử dụng "& int_array [0]" hoặc chỉ "int_array" thay thế.Ngoài ra, sizeof (char) được định nghĩa * là 1 trong C, không có "có thể" về nó. –

+0

Cảm ơn, Robert! Bạn nói đúng, tất nhiên; Tôi đã sửa bài đăng. – Avi