我正在尝试比较char array (string)
in 的不同声明C
。
我主要比较了这些组合有两点(而不是一次又一次地写我命名它们):
- 点更改或点分配:我们只是更改指针指向的内容。
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;
}
丹尼尔的答案是完整的。但是还有两个更简单的疑问:
1)对于p
case 对象是一个字符串文字(无法修改),即它是右侧对象的属性,而对于 RHS 上的 q 我有相同的东西,但现在它的行为不同. 为什么会有这种不一致的设计。
2) 对于 p 如果我修改字符串文字,行为是未定义的,即有时它被修改,有时不被修改。再说为什么这样的设计。实际上,对于越界数组访问,这是可以理解的,因为您访问了以前未分配的内存,有时您无权访问那块内存,因此,分段错误。但是为什么有时我可以修改字符串文字。为什么这样。这背后的原因是什么。