ความแตกต่างระหว่าง:
char * const
และ
const char *
ความแตกต่างระหว่าง:
char * const
และ
const char *
คำตอบ:
แตกต่างก็คือconst char *
เป็นตัวชี้ไปที่const char
ในขณะที่เป็นตัวชี้คงที่ไปยังchar * const
char
ประการแรกค่าที่ชี้ไปไม่สามารถเปลี่ยนแปลงได้ แต่ตัวชี้สามารถเป็นได้ ประการที่สองค่าที่ชี้ไปสามารถเปลี่ยนได้ แต่ตัวชี้ไม่สามารถ (คล้ายกับข้อมูลอ้างอิง)
นอกจากนี้ยังมี
const char * const
ซึ่งเป็นตัวชี้ค่าคงที่เป็นค่าคงที่ (ดังนั้นจึงไม่มีสิ่งใดเปลี่ยนแปลงได้)
บันทึก:
สองรูปแบบต่อไปนี้เทียบเท่า:
const char *
และ
char const *
เหตุผลที่แน่นอนสำหรับสิ่งนี้มีการอธิบายไว้ในมาตรฐาน C ++ แต่สิ่งสำคัญคือต้องทราบและหลีกเลี่ยงความสับสน ฉันรู้มาตรฐานการเข้ารหัสที่ต้องการ:
char const
เกิน
const char
(มีหรือไม่มีตัวชี้) เพื่อให้ตำแหน่งขององค์ประกอบที่เป็นเช่นเดียวกับตัวชี้const
const
const int *foo,*bar;
จะประกาศทั้งสองfoo
และbar
จะต้องมีint const *
แต่int const *foo, *bar
จะประกาศfoo
ให้เป็นint const *
และจะเป็นbar
int *
ฉันคิดว่าtypedef int * intptr; const intptr foo,bar;
จะประกาศตัวแปรทั้งสองให้เป็นint * const
; ฉันไม่ทราบวิธีการใช้การประกาศรวมกันเพื่อสร้างตัวแปรสองประเภทโดยไม่มีการพิมพ์
I believe const int *foo,*bar; would declare both foo and bar to be int const *
: ใช่ but int const *foo, *bar would declare foo to be a int const * and bar to be int *
: ไม่! มันจะเหมือนกับกรณีก่อน ๆ (ดูideone.com/RsaB7nที่คุณได้รับข้อผิดพลาดเดียวกันทั้ง foo และ bar) I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const
: ใช่ I don't know any way to use a combined declaration to create two variables of that type without a typedef
: อืint *const foo, *const bar;
ม ไวยากรณ์ของตัวประกาศ C ...
int const *foo, *volatile bar
ทำเพื่อbar
? ทำให้มันทั้งสองconst
และvolatile
? ฉันคิดถึงการแยกชื่อตัวแปรและประเภทของปาสคาลอย่างชัดเจน (ตัวชี้ไปยังอาร์เรย์ของพอยน์เตอร์กับจำนวนเต็มจะเป็นvar foo: ^Array[3..4] of ^Integer
`` นั่นเป็นสิ่งที่ซ้อนทับกันตลกใน C ฉันคิดว่า
int const *foo, *volatile bar
" ส่วนประเภทคือint const
(หยุดก่อน*
) และผู้ประกาศคือ*foo
(นิพจน์*foo
จะแสดงถึงint const
) และ*volatile bar
; การอ่านจากขวาไปซ้าย (กฎที่ดีสำหรับcv-qualifiers ) foo
เป็นตัวชี้ไปยังconst int และbar
เป็นตัวชี้ที่ระเหยไปที่const int (ตัวชี้คือความผันผวนตัวชี้ int คือ [เข้าถึงเป็น] const)
[3..4]
ไวยากรณ์จึงขอใช้อาร์เรย์ของ 10 int *(*foo)[10];
องค์ประกอบเป็นพิเศษ): มันสะท้อน (ในอนาคต) ใช้เป็นนิพจน์: *(*foo)[i]
(ด้วยi
จำนวนเต็มในช่วง[0, 10)
ie [0, 9]
) จะfoo
พิจารณาถึงอาร์เรย์เป็นอันดับแรกจากนั้นเข้าถึงองค์ประกอบที่ดัชนีi
(เนื่องจาก postfix []
ผูกแน่นกว่าคำนำหน้า*
) จากนั้นจึงยกเลิกองค์ประกอบนี้ในที่สุด ให้ผลint
(ดูideone.com/jgjIjR ) แต่typedef
ทำให้ง่ายขึ้น (ดูideone.com/O3wb7d )
เพื่อหลีกเลี่ยงความสับสนให้ผนวก const qualifier เสมอ
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;
p
(const int *const)
สำหรับ postfix ดีขึ้นหรือแย่ (ที่เลวร้ายยิ่งถ้าคุณถามฉัน) รอบคัดเลือก const ทั้งใน C และ C ++ จะหมายถึงการเป็น: CF void foo(int a) const;
ฟังก์ชันสมาชิก ความเป็นไปได้ที่จะประกาศconst int
เป็นข้อยกเว้นมากกว่ากฎ
const
ปรับเปลี่ยนสิ่งที่อยู่ข้างหน้ามันเสมอ (ทางด้านซ้ายของมัน) ยกเว้นเมื่อเป็นสิ่งแรกในการประกาศประเภทซึ่งจะแก้ไขสิ่งที่เกิดขึ้นหลังจากนั้น (ทางด้านขวาของมัน)
ดังนั้นทั้งสองจึงเหมือนกัน:
int const *i1;
const int *i2;
const int
พวกเขากำหนดตัวชี้ไปยัง คุณสามารถเปลี่ยนตำแหน่งi1
และi2
จุด แต่ไม่สามารถเปลี่ยนค่าที่ชี้ไปได้
นี้:
int *const i3 = (int*) 0x12345678;
กำหนดconst
ตัวชี้เป็นจำนวนเต็มและกำหนดค่าเริ่มต้นให้ชี้ไปที่ตำแหน่งหน่วยความจำ 12345678 คุณสามารถเปลี่ยนint
ค่าตามที่อยู่ 12345678 แต่คุณไม่สามารถเปลี่ยนที่อยู่ที่i3
ชี้ไป
const * char
เป็นรหัส C ที่ไม่ถูกต้องและไม่มีความหมาย บางทีคุณตั้งใจถามความแตกต่างระหว่าง a const char *
กับ a char const *
หรืออาจจะเป็นความแตกต่างระหว่าง a const char *
กับ a char * const
?
const char*
เป็นตัวชี้ไปยังตัวอักษรคงที่
char* const
เป็นตัวชี้คงที่ไปยังตัวละคร
const char* const
เป็นตัวชี้คงที่ไปยังตัวอักษรคงที่
Rule of thumb:อ่านคำนิยามจากขวาไปซ้าย!
const int *foo;
หมายถึง " foo
points ( *
) ถึงint
ที่ไม่สามารถเปลี่ยน ( const
)"
สำหรับโปรแกรมเมอร์นี่หมายความว่า "ฉันจะไม่เปลี่ยนค่าของสิ่งที่foo
ชี้ไป
*foo = 123;
หรือfoo[0] = 123;
จะไม่ถูกต้องfoo = &bar;
ได้รับอนุญาต.int *const foo;
หมายถึง " foo
ไม่สามารถเปลี่ยน ( const
) และคะแนน ( *
) เป็นint
"
สำหรับโปรแกรมเมอร์หมายความว่า "ฉันจะไม่เปลี่ยนที่อยู่หน่วยความจำที่foo
อ้างถึง"
*foo = 123;
หรือfoo[0] = 123;
ได้รับอนุญาตfoo = &bar;
จะไม่ถูกต้องconst int *const foo;
หมายถึง " foo
ไม่สามารถเปลี่ยน ( const
) และคะแนน ( *
) เป็นint
สิ่งที่ไม่สามารถเปลี่ยน ( const
)"
สำหรับโปรแกรมเมอร์นี่หมายความว่า "ฉันจะไม่เปลี่ยนค่าของสิ่งที่foo
ชี้ไปและฉันจะไม่เปลี่ยนที่อยู่ที่foo
อ้างถึง"
*foo = 123;
หรือfoo[0] = 123;
จะไม่ถูกต้องfoo = &bar;
จะไม่ถูกต้องconst char * xนี่ X เป็นตัวชี้อักขระซึ่งชี้ไปที่ค่าคงที่
ถ่าน * const xหมายถึงตัวชี้อักขระซึ่งเป็นค่าคงที่ แต่ตำแหน่งที่ชี้สามารถเปลี่ยนแปลงได้
const char * const xเป็นการรวมกันของ 1 และ 2 หมายความว่ามันเป็นตัวชี้อักขระคงที่ซึ่งชี้ไปที่ค่าคงที่
const * char xจะทำให้เกิดข้อผิดพลาดของคอมไพเลอร์ ไม่สามารถประกาศได้
ถ่าน const * xเท่ากับจุด 1
กฎของหัวแม่มือคือถ้าconstเป็นชื่อ var แล้วตัวชี้จะคงที่ แต่ตำแหน่งชี้สามารถเปลี่ยนแปลงได้ตัวชี้อื่นจะชี้ไปที่ตำแหน่งคงที่และตัวชี้สามารถชี้ไปที่ตำแหน่งอื่น แต่เนื้อหาตำแหน่งของจุดเปลี่ยนไม่สามารถเปลี่ยนแปลงได้
ข้อแรกคือข้อผิดพลาดทางไวยากรณ์ บางทีคุณอาจหมายถึงความแตกต่างระหว่าง
const char * mychar
และ
char * const mychar
ในกรณีนั้นตัวแรกคือตัวชี้ไปยังข้อมูลที่ไม่สามารถเปลี่ยนแปลงได้และตัวที่สองคือตัวชี้ที่จะชี้ไปยังที่อยู่เดียวกันเสมอ
กฎง่ายๆอีกข้อหนึ่งคือการตรวจสอบว่าconst คือ :
คำตอบมากมายให้เทคนิคที่เฉพาะเจาะจงกฎของหัวแม่มือและอื่น ๆ เพื่อทำความเข้าใจกับอินสแตนซ์เฉพาะของการประกาศตัวแปร แต่มีเทคนิคทั่วไปในการทำความเข้าใจการประกาศใด ๆ :
กฎตามเข็มนาฬิกา / เกลียว
A)
const char *a;
ตามกฎตามเข็มนาฬิกา / เกลียวa
เป็นตัวชี้ไปยังตัวละครที่มีค่าคงที่ ซึ่งหมายความว่าตัวละครมีค่าคงที่ แต่ตัวชี้สามารถเปลี่ยนได้ ie a = "other string";
คือดี แต่a[2] = 'c';
จะล้มเหลวในการรวบรวม
B)
char * const a;
ตามกฎแล้วa
ตัวชี้ const จะเป็นตัวอักษร เช่นคุณสามารถทำได้a[2] = 'c';
แต่คุณไม่สามารถทำได้a = "other string";
ฉันคิดว่าคุณหมายถึง const char * และ char * const
ตัวแรก const char * เป็นตัวชี้ไปยังอักขระคงที่ ตัวชี้นั้นไม่แน่นอน
ตัวที่สองอักขระ char * const เป็นตัวชี้ค่าคงที่ของอักขระ ตัวชี้ไม่สามารถเปลี่ยนแปลงได้อักขระที่ชี้ไปสามารถ
แล้วก็มี const char * const ที่ตัวชี้และตัวอักษรไม่สามารถเปลี่ยนแปลงได้
นี่คือคำอธิบายโดยละเอียดเกี่ยวกับรหัส
/*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’
}
ไวยากรณ์:
datatype *const var;
char *const
มาภายใต้กรณีนี้
/*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;
}
ไวยากรณ์:
const datatype *var
หรือ datatype const *var
const char*
มาภายใต้กรณีนี้
/* 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;
}
ถ่าน * const และ const ถ่าน *?
const char * p;
// ค่าไม่สามารถเปลี่ยนแปลงได้
char * const p;
// ที่อยู่ไม่สามารถเปลี่ยนแปลงได้
const char * const p;
// ทั้งสองไม่สามารถเปลี่ยนแปลงได้
โมดิconst
ฟายเออร์จะใช้กับคำศัพท์ทางซ้ายทันที ข้อยกเว้นเพียงอย่างเดียวคือเมื่อไม่มีสิ่งใดเหลืออยู่แล้วมันจะใช้กับสิ่งที่อยู่ทางขวาทันที
ทั้งหมดนี้เป็นวิธีที่เท่าเทียมกันในการพูดว่า "ตัวชี้คงที่เป็นค่าคงที่char
":
const char * const
const char const *
char const * const
char const const *
กฎสองข้อ
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.
เช่น
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
ฉันต้องการชี้ให้เห็นว่าการใช้int const *
(หรือ const int *
) ไม่เกี่ยวกับตัวชี้ที่ชี้ไปที่const int
ตัวแปร แต่ตัวแปรนี้ใช้const
สำหรับตัวชี้เฉพาะนี้
ตัวอย่างเช่น:
int var = 10;
int const * _p = &var;
โค้ดข้างต้นรวบรวมได้อย่างสมบูรณ์แบบ _p
ชี้ไปที่const
ตัวแปรแม้ว่าvar
ตัวเองจะไม่คงที่
ฉันจำได้จากหนังสือภาษาเช็กเกี่ยวกับ C: อ่านคำประกาศที่คุณเริ่มต้นด้วยตัวแปรแล้วไปทางซ้าย ดังนั้นสำหรับ
char * const a;
คุณสามารถอ่านเป็น: " a
เป็นตัวแปรของตัวชี้คงที่ประเภทถึงchar
",
char const * a;
คุณสามารถอ่านเป็น: " a
เป็นตัวชี้ไปยังตัวแปรประเภท char ฉันหวังว่านี่จะช่วยได้
โบนัส:
const char * const a;
คุณจะอ่านตามที่a
เป็นตัวชี้คงที่ตัวแปรคงที่ของประเภทถ่าน