char array (string)
inの異なる宣言を比較しようとしていC
ます。
主にこれらの組み合わせを比較した 2 つのポイントがあります (何度も書く代わりに名前を付けました)。
- ポイントの変更またはポイントの割り当て :ポインターが指すもののみを変更します。
char *a, *b;
a=b //we are doing this - 値の変更:ポインターが指しているデータを変更しています。
char *a;
*a='x' //we are doing this
以下は、さまざまな組み合わせのコードです。10個ほど疑問があります。それらはすべてどういうわけかリンクしているので、一緒に尋ねなければなりません。
すべての疑問はコードで説明されています。また、エラー メッセージも追加されます。
すべての質問に対する答えがわからない可能性があります。そのため、コード内の別のセクションにマークを付けました。また、各質問には番号が付けられています。
質問に対する答えがわかる場合は、適切な索引を付けて答えてください。
コードでは、間違っている可能性がある独自の観察と結論も行っています。だから私は結論:タグでそれらをマークしました。結論が間違っている場合は、共有/回答してください。
コード:
#include <stdio.h>
int main() {
char *p = "Something";//I cant change the data
char q[] = "Wierd"; // I can change to what q points to
// I. ______________________ char*p ___________________________
printf("\nI. ______________________ char*p ___________________________ \n\n");
printf("%s %s\n",p, q);
//*p = 'a';// got segmentation fault as I cant change the Value
p = q;//This is possible because I change the Point
//Now the type p is a char pointer which can't change Value (because I declared it like this) but can change the Point
//and it is now pointing to a memory which is of type a char array.I can change its Value but cant change its Point
//This means there are two different things on both sides of the assignment but gcc doesnot give any error (i.e. it is acceptable)
//That is for Pointer assignment restriction rules of the type of left side var was used and for Value change
//rules of the type of right side var was used
// (1)Why?
*p = 'x';
printf("%s %s\n",p, q);
//Again try to make Something Wierd
p = "Something";
q[0] = 'W';
// II. ______________________ char q[] ___________________________
printf("\nII. ______________________ char q[] ___________________________ \n\n");
printf("%s %s\n",p, q);
//q = p;// This is not possible because for q I cant change Point.
// This is the error comes
//error: incompatible types when assigning to type ‘char[6]’ from type ‘char *’
*q = 'x';//This works fine as this is possible to change Value for q
printf("%s %s\n",p, q);
//Again try to make Something Wierd
p = "Something";
q[0] = 'W';
//____________________________________________________________________/
const char * r = "What";//I cant change the data to what a points to (basic def and const act on same)
char const * s = "Point";//I cant change the data to what a points to (basic def and const act on same)
char * const t = "Pointers";//I cant change the data to what a points to because of basic def and const make c a const that now c can only point to single entity.
const char u[] = "Are";//I cant change the data to what a points to because of const and I can't change to what d points because of basic def of [].
char const v[] = "Trying";//I cant change the data to what a points to because of const and I can't change to what d points because of basic def of [].
//char w const [] = "To make";//This is not possible
//___________________________________________________________________/
// III. ______________________ const char * r ___________________________
printf("\nIII. ______________________ const char * r ___________________________ \n\n");
printf("%s\n",r);
//*r = 'x'; // This is not possible
//Error comes is:
//error: assignment of read-only location ‘*r’
//now the behaviour of r is same as p but instead of getting segmentation fault I got an error at compile time.
//Also the restriction const put here is same as of restriction present with p except(error checking).
//Conclusion : This means writing const here makes no difference in terms of Value and Point. What it was before is the same now.
r = s;
printf("%s %s\n",r ,s);
//*r = 'x';
r = t;
printf("%s %s\n",r ,t);
//*r = 'x';
r = u;
printf("%s %s\n",r ,u);
//*r = 'x';
r=v;
printf("%s %s\n",r ,v);
//*r = 'x';
r=p;
printf("%s %s\n",r ,p);
//*r = 'x';
r=q;
printf("%s %s\n",r ,q);
//*r = 'x';
//For above four cases
//Everything works for Point assignment
//Nothing Works for Value change (Everytime assignment to read-only location error, no segmentation fault)
//Everything Works for Point assignment - This means everything works for the
//rules of the type of varible on the left side for Pointer assignment. (Even for r=u,r=v, r=q).
//(2) WHY this is happening.(Actualy answer related to WHY(1))
//Nothing Works for Value change
//Now this is absurd. On the first look it seems that as the things happen at the time of p=q, here
//for r=u, r=v, r=q same things should had happened. But on the closer inspection you can get that u,v
//have restrictions on Value change because of const.
//But (3)Why no Value change is happening for r=q ?
// (4) Why fot r=p, r=q getting error due to const. not due to segmentation fault.
//Resetting Wierdness
r = "What";
// IV. ______________________ char const * s ___________________________
printf("\nIV. ______________________ char const * s ___________________________ \n\n");
printf("%s\n",s);
//*s = 'x'; // This is not possible
//Error comes is
//error: assignment of read-only location ‘*s’
//Behavious of s is exactly same as r
//Conclusion: Writing const after or before char makes no difference.
s = r;
printf("%s %s\n",s ,s);
//*s = 'x';
s = t;
printf("%s %s\n",s ,t);
//*s = 'x';
s = u;
printf("%s %s\n",s ,u);
//*s = 'x';
s=v;
printf("%s %s\n",s ,v);
//*s = 'x';
s=p;
printf("%s %s\n",s ,p);
//*s = 'x';
s=q;
printf("%s %s\n",s ,q);
//*s = 'x';
//For above four cases
//Everything happens same as with r.
//Resetting Wierdness
s = "Point";
// V. ______________________ char * const t ___________________________
printf("\nV. ______________________ char * const t ___________________________ \n\n");
printf("%s\n",t);
//*t = 'x';//This is not possible
//Error is
//Segmentation-fault
//This means that on Value change the error comes not due to const. It comes for the same reason of p.
//t = r;
printf("%s %s\n",t ,r);
//*t = 'x';
//t = s;
printf("%s %s\n",t ,s);
//*t = 'x';
//t = u;
printf("%s %s\n",t ,u);
//*t = 'x';
//t=v;
printf("%s %s\n",t ,v);
//*t = 'x';
//t=p;
printf("%s %s\n",t ,p);
//*t = 'x';
//t=q;
printf("%s %s\n",t ,q);
//*t = 'x';
//For above four cases
//Nothing Works for Point Assignment
//Nothing works for value change (Everytime segmentation fault, assignment to read-only location error)
//Nothing Works for Point Assignment
//This is understandable
//Nothing works for value change
// (5) Why this is happening. Why left hand side is always given precedence. Why this isn't happening p=q,
//because for value change t=q and p=q are exctly same both pn left side and right side of the assignment.
//Resetting Wierdness
//t = "Pointers"; //No need
// VI. ______________________ const char u[] ___________________________
printf("\nVI. ______________________ const char u[] ___________________________ \n\n");
printf("%s\n",u);
//*u = 'x';//This is not possible
//Error Comes is
//error: assignment of read-only location ‘*(const char *)&u’
//This error comes because of const.
//Conclusion: [] gives the Point restriction and const gives the Value Restriction
//u = r;
printf("%s %s\n",u ,r);
//*u = 'x';
//u = s;
printf("%s %s\n",u ,s);
//*u = 'x';
//u = t;
printf("%s %s\n",u ,t);
//*u = 'x';
//u=v;
printf("%s %s\n",u ,v);
//*u = 'x';
//u=p;
printf("%s %s\n",u ,p);
//*u = 'x';
//u=q;
printf("%s %s\n",u ,q);
//*u = 'x';
//For above four cases
//Nothing Works for Point Assignment
//Nothing works for value change (Everytime assignment to read-only location error, no segmentation fault)
//Nothing Works for Point Assignment
//Error Comes for each is:
//warning: assignment of read-only location ‘u’ [enabled by default]
//error: incompatible types when assigning to type ‘const char[4]’ from type ‘const char *’
//Left side rules are given precedence. (6)Why? (If already not solved in above answers)
//Nothing works for value change
//Left side rules are given precedence. (7)Why? (If already not solved in above answers)
//Resetting Wierdness
//u = "Are";
// VII. ______________________ char const v[] ___________________________
printf("\nVII. ______________________ char const v[] ___________________________ \n\n");
printf("%s\n",v);
//*v = 'x';//This is not possible
//Error Comes is
//error: assignment of read-only location ‘*(const char *)&v’
//This error comes because of const.
//Conclusion: Writing const after or before char makes no difference.
//v = r;
printf("%s %s\n",v ,r);
//*v = 'x';
//v = s;
printf("%s %s\n",v ,s);
//*v = 'x';
//v = t;
printf("%s %s\n",v ,t);
//*v = 'x';
//v=u;
printf("%s %s\n",v ,u);
//*v = 'x';
//v=p;
printf("%s %s\n",v ,p);
//*v = 'x';
//v=q;
printf("%s %s\n",v ,q);
//*v = 'x';
//For above four cases
//Everything works as same with u.
//Resetting Wierdness
//v = "Trying";
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (8) WHY `const char * a;` and `char const * a` works same?????
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//---------------Now doing more Possible combinations with p and q------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// VIII. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ char *p ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
printf("\nVIII. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ char *p ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n\n");
//p = r;
printf("%s %s\n",p ,r);
//*p = 'x';
//p = s;
printf("%s %s\n",p ,s);
//*p = 'x';
//p = t;
printf("%s %s\n",p ,t);
//*p = 'x';
//p=u;
printf("%s %s\n",p ,u);
//*p = 'x';
//p=v;
printf("%s %s\n",p ,v);
//*p = 'x';
//For above four cases
//Point Assignment
//Warning for p=r, p=s is
//warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
//Conclusion:Kind of understandable.
// NO Warning for p=t
//For left side type I can do Point assignment and for Right Side I can,t do.
// Left side rules are given precedence. (9)Why? (If already not solved in above answers)
//Warning for p=u, p=v is
//warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
//For left side type I can do Point assignment and for Right Side I can,t do.
// Left side rules are given precedence. (10)Why? (If already not solved in above answers)
//Value Change
//Segmentation fault for everything .
//Conclusion: Understndable if assume left hand side are given precedence except for p = q (showed in I.)
//Resetting Wierdness
p = "Something";
// IX. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ char q[] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
printf("\nIX. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ char q[] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n\n");
//q = r;
printf("%s %s\n",q ,r);
*q = 'x';
//q = s;
printf("%s %s\n",q ,s);
*q = 'x';
//q = t;
printf("%s %s\n",q ,t);
*q = 'x';
//q=u;
printf("%s %s\n",q ,u);
*q = 'x';
//q=v;
printf("%s %s\n",q ,v);
*q = 'x';
//For above four cases
//Point Assignment
//Error for each is:
//error: incompatible types when assigning to type ‘char[6]’ from type ‘const char *’
//Conclusion: Understandable, if assume L.H.S. is given precedence except for p = q (showed in I.)
//Value Change
//Possible for each
//Conclusion: Understndable if assume left hand side are given precedence except for p = q (showed in I.)
//Resetting Wierdness
*q = 'W'; //No need
return 0;
}
ダニエルの回答は完了です。しかし、さらに2つの単純な疑問:
1)p
オブジェクトが文字列リテラル(変更できない)の場合、つまり、右側のオブジェクトのプロパティですが、RHSのqの場合、同じものがありますが、動作が異なります. なぜ、このように一貫性のない設計を行うのか。
2) p の場合、文字列リテラルを変更すると、動作は未定義です。つまり、変更される場合と変更されない場合があります。改めてなぜこんなデザインに。実際、範囲外の配列アクセスの場合、以前に割り当てたことのないメモリにアクセスするため、これは理解できます。また、そのメモリの一部にアクセスする権限がない場合があるため、セグメンテーション違反が発生します。しかし、なぜ時々文字列リテラルを変更できるのでしょうか。なんでそうなの。この背後にある理由は何ですか。