int * i; hoặc int * i; hoặc int * i; [đóng cửa]


30

Phương pháp yêu thích của bạn để khai báo một con trỏ là gì?

int* i;

hoặc là

int *i;

hoặc là

int * i;

hoặc là

int*i;

Hãy giải thích tại sao.

xem thêm: http://www.stroustrup.com/bs_faq2.html#whitespace


19
Tôi muốn tập trung vào 3000 dòng khác ...

29
int*i;- khoảng trắng không mọc trên cây, bạn biết đấy ...
Shog9

Đây thực chất là cùng một câu hỏi; đây là câu trả lời của tôi .
Keith Thompson

Câu trả lời:


75

Nếu bạn viết:

int* i, j, k;

bạn đánh lừa một cách sai lầm rằng tất cả i, j và k là con trỏ tới int.

Vì vậy, tôi cho rằng nó vượt trội hơn khi sáp nhập * vào tên biến.


35
Và tôi đề nghị int * i;là một người không phải là đối thủ chỉ vì nó trông giống như nhân lên trong nháy mắt.
John K

1
+1 vì tôi đã không xem xét kịch bản này trước đây.
Pops

4
"bạn đánh lừa một cách sai lầm rằng tất cả i, j và k là con trỏ tới int." Trừ khi bạn viết C #, nơi int*được xem là một loại và int* i, jkhai báo hai con trỏ. Câu hỏi có thể được coi là không đầy đủ - nó phụ thuộc vào ngôn ngữ bạn đang sử dụng kiểu nào là hợp lý. Trong CI làm theo int *x, trong C # tôi làm khác.
Joren

1
@Joren: Xin lỗi, không phải là lập trình viên C #, tôi chỉ đơn giản giả định bằng cách xem đoạn mã trong câu hỏi là C hoặc C ++.
Randall Schulz

Tôi nghĩ hoàn toàn hợp lý khi cho rằng C hoặc C ++ của nó trừ khi C # được đề cập cụ thể. Người ta không thấy con trỏ trong C # rất thường xuyên.
thay thế

62

Tôi thích int* ibởi vì icó kiểu "con trỏ tới một int" và tôi cảm thấy điều này làm cho nó đồng nhất với hệ thống kiểu. Tất nhiên, hành vi nổi tiếng xuất hiện, khi cố gắng xác định nhiều con trỏ trên một dòng (cụ thể là dấu hoa thị cần được đặt trước mỗi tên biến để khai báo một con trỏ), nhưng tôi chỉ đơn giản là không khai báo con trỏ theo cách này. Ngoài ra, tôi nghĩ rằng đó là một khiếm khuyết nghiêm trọng trong các ngôn ngữ kiểu C.


8
Tôi cũng theo quy ước này. Cho cùng một lý do.
gablin

5
Cá nhân, nếu tôi khai báo nhiều con trỏ trong mã của mình, tôi coi nó như một mùi mã. Tôi không cần nhiều con trỏ; và thông thường, tôi không. Vì vậy, vấn đề nhiều khai báo trên một dòng không bao giờ xuất hiện trong bất kỳ mã nào tôi viết: Một khai báo trên mỗi dòng.
greyfade

5
Vấn đề với điều này là loại không phải là "con trỏ tới int". C (và C ++) không có loại con trỏ. Nó là một con trỏ tới một khối bộ nhớ, trong đó có kiểu int.
Billy ONeal

10
Tôi sẽ tranh luận rằng *icó một loại int.
Tim Goodman

5
@Billy: Nếu vậy, tôi chưa bao giờ thấy sự nhầm lẫn đó trong 12 năm cố gắng hiểu, phân tích và giải thích tiêu chuẩn. "Con trỏ tới một int" là một loại hoàn toàn hợp lệ trong C và C ++.

23

Đối với C, nơi chúng tôi không tập trung mạnh vào các loại, tôi thích:

int *i;

Bởi vì nó có một điểm nhấn trên int, không phải con trỏ. Là gì int? *ilà số nguyên


2
Điểm tốt. Với con trỏ, bạn có thể nghĩ bắt đầu như là một phần của tên. Ví dụ: nếu bạn có int i = 5, để lấy giá trị i, bạn sử dụng tên i. Tương tự như vậy, nếu bạn có int *i; *i = 5, sau đó để có được giá trị, bạn sử dụng *i.
mipadi

Tôi đọc int * i là: * i là một int. Vì vậy, tôi là một con trỏ đến int. Khai báo biến trong C sử dụng biểu thức kiểu, int và * chỉ là toán tử. int * i phân tích cú pháp là int (* (i)) và được hiểu là tôi có kiểu con trỏ đến số nguyên. char * p [] phân tích cú pháp dưới dạng char (* ([] (p))) (vì [] có độ ưu tiên cao hơn *) và có nghĩa là: p có kiểu mảng của con trỏ-to char.
Giorgio

Vì lý do này, tôi nghĩ rằng họ đã chọn viết * bên cạnh biến, bởi vì * là một toán tử được áp dụng cho nó.
Giorgio

7

Tôi đã ưa thích int* itrong nhiều năm. Tuy nhiên, có một lập luận mạnh mẽ int *ivì khi sử dụng kiểu cũ, bạn vẫn phải nhớ quy tắc nhiều khai báo:

int* a, *b; // not int* a, b;

Bởi vì bạn phải nhớ quy tắc này, bạn sẽ không đạt được bất kỳ đơn giản nào nhưng tôi cũng không nói nó phức tạp hơn. Tránh nhiều khai báo trên một dòng chỉ là một cách khác để nói rằng bạn nhớ quy tắc này. Sự khác biệt giữa hai phong cách là moot.

Tuy nhiên, ngay cả khi tôi sử dụng nó, tôi cảm thấy hơi ngớ ngẩn khi giả vờ cú pháp khai báo C hoạt động khác với nó, bằng cách đặt dấu hoa thị bên cạnh loại chứ không phải là biến mà nó bị ràng buộc về mặt cú pháp.

Tôi không mua loại đó nhấn mạnh loại con trỏ (for i) trong khi loại kia nhấn mạnh loại int (for *i), nhưng đó có thể là sau 15 năm sử dụng C và C ++, đó chỉ khi tôi nhìn vào nó, không có phải suy nghĩ về nó⁠ Một vài điều mà hầu hết những người mới bắt đầu hỏi câu hỏi này chưa thể làm được.

Ngoài ra, ngay cả khi được ưu tiên, tôi cũng không thấy khó xử khi đọc / viết mã theo kiểu khác. Kiên định, bla bla blah.

Không cần phải đề cập đến int * i.


6

Tôi thích cái đầu tiên. Nó là tự nhiên như là một con trỏ là một phần của loại.

Khi tôi sử dụng C #, nó xử lý các loại theo cách trực quan hơn C, do đó không có vấn đề gì khi khai báo một số con trỏ trong cùng một câu lệnh:

int* a, b, c; // three pointers


4

Nếu bạn muốn khai báo nhiều biến nhưng không muốn lặp lại dấu hoa thị:

template <typename T>
struct pointer_to
{
    typedef T* type;
};

pointer_to<int>::type p1, p2, p3;

(Như bạn có thể thấy bên trong mẫu struct, tôi thích int* ikiểu này.)

Và đây là một giải pháp tổng quát hơn:

template <typename T>
struct identity
{
    typedef T type;
};

identity<int*>::type p1, p2, p3;

Cái này hoạt động với bất kỳ "loại có vấn đề" nào, ví dụ như mảng và tham chiếu:

identity<int[10]>::type a1, a2, a3;

identity<int&>::type r1(*p1), r2(*p2), r3(*p3);

omg, c ++ luôn hiển thị một cái gì đó mới đối với tôi :). Cảm ơn!
Tamás Szelei

1
OMG, C ++ thật kinh khủng! typedef int* int_ptrsẽ thực hiện các mẹo. Chắc chắn, tôi phải khai báo một typedef mới cho các loại con trỏ khác nhau, nhưng trong thực tế sẽ có bao nhiêu? Tám nhiều nhất?
benzado

1
@benzado Trong thực tế, bạn không cần typedef hoặc bất kỳ thủ thuật ưa thích nào tôi đã trình bày, vì không có người tỉnh táo nào khai báo nhiều biến trong một dòng. Mặc dù vậy, vẫn thú vị.
dòng chảy

2
Tôi biết, tôi đã nói nhiều hơn về xu hướng các chương trình C ++ sử dụng các tính năng ngôn ngữ chỉ vì chúng có thể.
benzado

@benzado: !!! Tôi đã thấy điều này rất thường xuyên!
Giorgio

2

Tôi sẽ đi int* i;vì phần đầu biểu thị loại biến (con trỏ đến int), trong khi phần thứ hai biểu thị tên ( i). Nó sẽ không có ý nghĩa với tôi rằng loại intvà tên là *i. Ngoài ra, int * i;trông hơi giống như nhân với tôi.


Cú pháp khai báo C không nhất quán trong vấn đề này, vì thông tin loại có thể dễ dàng xuất hiện sau mã định danh: mảng là ví dụ rõ ràng nhất.

@Roger: Tôi biết, nhưng câu hỏi này cụ thể là về một khai báo biến duy nhất, và không có gì khác.
Allon Guralnek

Tôi nghĩ rằng đó là đọc một chút về nó. :) Cách tôi hiểu câu hỏi, đó là hỏi về phong cách bạn sử dụng ở mọi nơi.

@Roger: Có lẽ bạn đúng, nhưng mục đích của tôi là trả lời câu hỏi của OP: "Phương pháp ưa thích của bạn để khai báo một con trỏ là gì?". Rõ ràng, mọi người đều có thể tự do xem xét vấn đề được trình bày trong câu hỏi, và nó thậm chí còn được khuyến khích ở đây. Là một người không phát triển trong C / C ++, tôi cảm thấy làm như vậy sẽ đi quá xa lĩnh vực chuyên môn của tôi.
Allon Guralnek

2

Trong khai báo tôi sử dụng int * i;, bạn đọc nó như là i is a pointer to an integer.

Con trỏ đóng góp cho cả loại và biến vì vậy nó phải ở giữa.

Đó là một điều tốt để tránh khai báo nhiều điều trên cùng một dòng: int * i, j;


1

Tôi thực sự sử dụng cả ba quy ước trong hoàn cảnh cụ thể. Thoạt nhìn tôi có vẻ không nhất quán, nhưng ...

  • int * khi định danh không có mặt, để củng cố một cách trực quan rằng tên không có mặt.
  • int* intptrtrên typedefs và các khai báo tương tự để củng cố trực quan rằng đó là một phần của loại. Tương tự với khai báo con trỏ hàm:(int* (*foo)(int))
  • int *identifierclass &identifiertrên các tham số chức năng để củng cố một cách trực quan rằng tham số đó có khả năng là một tham số "ra".
  • const int * const * constBất cứ khi nào tôi sử dụng vòng loại cv .
  • int * foo; trên tờ khai địa phương.

Tôi đoán tôi hơi thiên về trực quan.


1

Không có loại con trỏ trong C! Vì vậy, "int *" có nghĩa là không có gì. Dấu hoa thị luôn bị ràng buộc với phần tử được viết bên phải của nó, nó thuộc về phần tử bên phải. "* i" là một số nguyên. Và vì * i là một int, nên theo sau tôi là một con trỏ tới int. Đó là logic đằng sau nó và đó là lý do tại sao "int * i" là giải pháp khả thi duy nhất. Mọi thứ khác chỉ là ảo ảnh (được trình biên dịch tự động sửa trong hầu hết các trường hợp). Trong C ++ và C # có gì đó khác biệt. Nhưng đối với C chỉ có một cuốn kinh thánh: "Dennis M. Ritchie: Ngôn ngữ lập trình C". Dennis (RIP!) Đã viết nó: "int * i". Không cần phải hỏi điều này.


6
"Không có loại con trỏ nào trong C" - Bạn lấy ý tưởng đó từ đâu? int*là một loại con trỏ.
Keith Thompson

-2

Tôi sử dụng int *ibởi vì nó dễ dàng hơn để thấy rằng nó là một con trỏ, mặc dù tôi không nghĩ nó thực sự quan trọng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.