Sự khác biệt giữa:
char * const
và
const char *
Sự khác biệt giữa:
char * const
và
const char *
Câu trả lời:
Sự khác biệt là const char *một con trỏ đến a const char, trong khi char * constlà một con trỏ không đổi đến a char.
Đầu tiên, giá trị được trỏ đến không thể thay đổi nhưng con trỏ có thể. Thứ hai, giá trị được trỏ vào có thể thay đổi nhưng con trỏ không thể (tương tự như tham chiếu).
Cũng có một
const char * const
đó là một con trỏ liên tục đến một char không đổi (vì vậy không có gì có thể thay đổi).
Ghi chú:
Hai hình thức sau là tương đương:
const char *
và
char const *
Lý do chính xác cho điều này được mô tả trong tiêu chuẩn C ++, nhưng điều quan trọng cần lưu ý và tránh nhầm lẫn. Tôi biết một số tiêu chuẩn mã hóa thích:
char const
kết thúc
const char
(có hoặc không có con trỏ) sao cho vị trí của constphần tử giống như với con trỏ const.
const int *foo,*bar;sẽ tuyên bố cả hai foovà barđược int const *, nhưng int const *foo, *barsẽ tuyên bố foolà một int const *và barđược int *. Tôi nghĩ rằng typedef int * intptr; const intptr foo,bar;sẽ khai báo cả hai biến là int * const; Tôi không biết cách nào để sử dụng khai báo kết hợp để tạo hai biến loại đó mà không cần typedef.
I believe const int *foo,*bar; would declare both foo and bar to be int const *: Vâng. but int const *foo, *bar would declare foo to be a int const * and bar to be int *: Không! Nó sẽ giống hệt như trường hợp trước. (Xem ideone.com/RsaB7n nơi bạn gặp cùng một lỗi cho cả foo và bar). I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const: Đúng. I don't know any way to use a combined declaration to create two variables of that type without a typedef: Vâng , int *const foo, *const bar;. Cú pháp khai báo C ...
int const *foo, *volatile barlàm gì bar? Làm cho cả hai constvà volatile? Tôi nhớ rằng việc phân tách rõ ràng các tên biến khai báo của Pascal và các kiểu của chúng (một con trỏ tới một mảng các con trỏ tới các số nguyên sẽ là var foo: ^Array[3..4] of ^Integer: `. Đó sẽ là một số dấu ngoặc đơn được lồng vào nhau trong C, tôi nghĩ vậy
int const *foo, *volatile bar" phần loại là int const(dừng trước *) và người khai báo là *foo(biểu thức *foosẽ biểu thị một int const) và *volatile bar; đọc từ phải sang trái (quy tắc tốt cho vòng loại cv ), foolà con trỏ tới const int và barlà con trỏ dễ bay hơi cho const int (chính con trỏ dễ bay hơi, int nhọn được [truy cập là] const).
[3..4]cú pháp, vì vậy hãy lấy một mảng gồm 10 phần tử) : int *(*foo)[10];. Nó phản ánh (sử dụng trong tương lai) của nó như là một biểu thức: *(*foo)[i](với imột số nguyên trong phạm vi [0, 10)tức là [0, 9]) sẽ lần đầu tiên foonhận được tại mảng, sau đó truy cập vào phần tử tại chỉ mục i(vì hậu []tố liên kết chặt chẽ hơn tiền tố *), sau đó cuối cùng là phần tử này mang lại một int(xem ideone.com/jgjIjR ). Nhưng typedeflàm cho nó dễ dàng hơn (xem ideone.com/O3wb7d ).
Để tránh nhầm lẫn, luôn luôn nối thêm vòng loại const.
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
pkhông liên quan đến loại : (const int *const). Cho tốt hơn hoặc tồi tệ hơn (tệ hơn nếu bạn hỏi tôi) vòng loại const, cả trong C và C ++, có nghĩa là postfix: hàm cf const thành viên void foo(int a) const;. Khả năng khai báo const intlà ngoại lệ chứ không phải là quy tắc.
const luôn luôn sửa đổi thứ xuất hiện trước nó (ở bên trái của nó), NGOẠI TRỪ khi đó là điều đầu tiên trong một khai báo kiểu, trong đó nó sửa đổi điều xuất hiện sau nó (bên phải của nó).
Vì vậy, hai cái này giống nhau:
int const *i1;
const int *i2;
họ định nghĩa con trỏ tới a const int. Bạn có thể thay đổi vị trí i1và i2điểm, nhưng bạn không thể thay đổi giá trị mà chúng trỏ đến.
Điều này:
int *const i3 = (int*) 0x12345678;
xác định một constcon trỏ tới một số nguyên và khởi tạo nó để trỏ đến vị trí bộ nhớ 12345678. Bạn có thể thay đổi intgiá trị tại địa chỉ 12345678, nhưng bạn không thể thay đổi địa chỉ i3trỏ đến.
const * charlà mã C không hợp lệ và là vô nghĩa. Có lẽ bạn muốn hỏi sự khác biệt giữa a const char *và a char const *, hoặc có thể là sự khác biệt giữa a const char *và a char * const?
const char*là một con trỏ tới một ký tự không đổi
char* constlà một con trỏ không đổi cho một ký tự
const char* constlà một con trỏ không đổi đến một ký tự không đổi
Nguyên tắc nhỏ: đọc định nghĩa từ phải sang trái!
const int *foo;Có nghĩa là " foođiểm ( *) đến mức intkhông thể thay đổi ( const)".
Đối với lập trình viên, điều này có nghĩa là "Tôi sẽ không thay đổi giá trị của những gì footrỏ đến".
*foo = 123;hoặc foo[0] = 123;sẽ không hợp lệ.foo = &bar; được cho phép.int *const foo;Có nghĩa là " fookhông thể thay đổi ( const) và điểm ( *) thành một int".
Để các lập trình viên phương tiện này "Tôi sẽ không thay đổi địa chỉ bộ nhớ mà foođề cập đến".
*foo = 123;hoặc foo[0] = 123;được cho phép.foo = &bar; sẽ không hợp lệconst int *const foo;Có nghĩa là " fookhông thể thay đổi ( const) và điểm ( *) thành intkhông thể thay đổi ( const)".
Để các lập trình viên phương tiện này "Tôi sẽ không thay đổi giá trị của những gì foođiểm đến, cũng không phải tôi sẽ thay đổi địa chỉ đó foođề cập đến".
*foo = 123;hoặc foo[0] = 123;sẽ không hợp lệ.foo = &bar; sẽ không hợp lệconst char * x Ở đây X về cơ bản là một con trỏ ký tự đang trỏ đến một giá trị không đổi
char * const x được dùng để chỉ con trỏ ký tự không đổi, nhưng vị trí nó đang trỏ có thể thay đổi.
const char * const x được kết hợp thành 1 và 2, có nghĩa là nó là một con trỏ ký tự không đổi được trỏ đến giá trị không đổi.
const * char x sẽ gây ra lỗi trình biên dịch. nó không thể được tuyên bố.
char const * x bằng điểm 1.
quy tắc của ngón tay cái là nếu const có tên var thì con trỏ sẽ không đổi nhưng vị trí trỏ có thể thay đổi , con trỏ khác sẽ trỏ đến một vị trí không đổi và con trỏ có thể trỏ đến một vị trí khác nhưng nội dung vị trí trỏ không thể thay đổi .
Rất nhiều câu trả lời cung cấp các kỹ thuật cụ thể, quy tắc ngón tay cái, vv để hiểu trường hợp cụ thể này của khai báo biến. Nhưng có một kỹ thuật chung để hiểu bất kỳ tuyên bố nào:
Quy tắc theo chiều kim đồng hồ / xoắn ốc
A)
const char *a;
Theo quy tắc theo chiều kim đồng hồ / xoắn ốc alà con trỏ đến ký tự không đổi. Có nghĩa là ký tự không đổi nhưng con trỏ có thể thay đổi. tức a = "other string";là ổn nhưng a[2] = 'c';sẽ không biên dịch
B)
char * const a;
Theo quy tắc, alà con trỏ const cho một ký tự. tức là bạn có thể làm a[2] = 'c';nhưng bạn không thể làma = "other string";
Tôi đoán bạn có nghĩa là const char * và char * const.
Đầu tiên, const char *, là một con trỏ tới một ký tự không đổi. Các con trỏ chính nó là có thể thay đổi.
Thứ hai, char * const là một con trỏ không đổi cho một ký tự. Con trỏ không thể thay đổi, ký tự mà nó trỏ tới có thể.
Và sau đó là const char * const nơi con trỏ và ký tự không thể thay đổi.
Dưới đây là một lời giải thích chi tiết với mã
/*const char * p;
char * const p;
const char * const p;*/ // these are the three conditions,
// const char *p;const char * const p; pointer value cannot be changed
// char * const p; pointer address cannot be changed
// const char * const p; both cannot be changed.
#include<stdio.h>
/*int main()
{
const char * p; // value cannot be changed
char z;
//*p = 'c'; // this will not work
p = &z;
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
char * const p; // address cannot be changed
char z;
*p = 'c';
//p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
const char * const p; // both address and value cannot be changed
char z;
*p = 'c'; // this will not work
p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.
int main(void)
{
char ca1[10]= "aaaa"; // char array 1
char ca2[10]= "bbbb"; // char array 2
char *pca1= ca1;
char *pca2= ca2;
char const *ccs= pca1;
char * const csc= pca2;
ccs[1]='m'; // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
ccs= csc; // Good
csc[1]='n'; // Good
csc= ccs; // Bad - error: assignment of read-only variable ‘csc’
char const **ccss= &ccs; // Good
char const **ccss1= &csc; // Bad - warning: initialization from incompatible pointer type
char * const *cscs= &csc; // Good
char * const *cscs1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc= &pca1; // Good
char ** const cssc1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc2= &csc; // Bad - warning: initialization discards ‘const’
// qualifier from pointer target type
*ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
*ccss= ccs; // Good
*ccss= csc; // Good
ccss= ccss1; // Good
ccss= cscs; // Bad - warning: assignment from incompatible pointer type
*cscs[1]= 'y'; // Good
*cscs= ccs; // Bad - error: assignment of read-only location ‘*cscs’
*cscs= csc; // Bad - error: assignment of read-only location ‘*cscs’
cscs= cscs1; // Good
cscs= cssc; // Good
*cssc[1]= 'z'; // Good
*cssc= ccs; // Bad - warning: assignment discards ‘const’
// qualifier from pointer target type
*cssc= csc; // Good
*cssc= pca2; // Good
cssc= ccss; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cscs; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cssc1; // Bad - error: assignment of read-only variable ‘cssc’
}
Cú pháp:
datatype *const var;
char *const đến trong trường hợp này.
/*program to illustrate the behaviour of constant pointer */
#include<stdio.h>
int main(){
int a=10;
int *const ptr=&a;
*ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
printf("%d",*ptr);
return 0;
}
Cú pháp:
const datatype *varhoặc là datatype const *var
const char* đến trong trường hợp này.
/* program to illustrate the behavior of pointer to a constant*/
#include<stdio.h>
int main(){
int a=10,b=20;
int const *ptr=&a;
printf("%d\n",*ptr);
/* *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
ptr=&b;
printf("%d",*ptr);
/*we can point it to another object*/
return 0;
}
char * const và const char *?
const char * p; // giá trị không thể thay đổi
char * const p; // địa chỉ không thể thay đổi
const char * const p; // cả hai không thể thay đổi.
Công cụ constsửa đổi được áp dụng cho thuật ngữ ngay bên trái của nó. Ngoại lệ duy nhất này là khi không có gì ở bên trái của nó, sau đó nó áp dụng cho những gì ngay bên phải của nó.
Đây là tất cả các cách tương đương để nói "con trỏ không đổi đến hằng số char":
const char * constconst char const *char const * constchar const const *Hai quy tắc
If const is between char and *, it will affect the left one.If const is not between char and *, it will affect the nearest one.ví dụ
char const *. This is a pointer points to a constant char.char * const. This is a constant pointer points to a char.Tôi muốn chỉ ra rằng việc sử dụng int const *(hoặc const int *) không phải là về một con trỏ trỏ đến một const intbiến, mà là biến này constdành cho con trỏ cụ thể này.
Ví dụ:
int var = 10;
int const * _p = &var;
Các mã trên biên dịch hoàn toàn tốt. _pchỉ đến một constbiến, mặc dù varbản thân nó không phải là hằng số.
Tôi nhớ từ cuốn sách tiếng Séc về C: đọc phần khai báo rằng bạn bắt đầu với biến và rẽ trái. Vì vậy đối với
char * const a;
bạn có thể đọc là: " alà biến của kiểu con trỏ không đổi char",
char const * a;
bạn có thể đọc là: " alà một con trỏ tới biến hằng của kiểu char. Tôi hy vọng điều này có ích.
Tặng kem:
const char * const a;
Bạn sẽ đọc như alà con trỏ không đổi đến biến hằng của kiểu char.