char const array可能的组合结果和效果

时间:2012-10-04 20:53:13

标签: c arrays pointers char const

我正在尝试比较char array (string)C的不同声明。

我有两点主要比较这些组合(而不是一次又一次地写我命名):

  1. 点更改或点分配:我们只是更改指针指向的内容 char *a, *b;
    a=b //we are doing this
  2. 值更改:我们正在更改指针所指向的数据 char *a;
    *a='x' //we are doing this
  3. 以下是具有不同组合的代码。我有大约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;
    }
    

    Daniel的答案已经完成。但更简单的两个疑问是:
    1)对于p,case对象是一个字符串文字(一个不可修改),即它是右手边对象的属性,而对于RHS上的q我有相同的东西,但现在它表现不同。为什么这种不一致的设计。
    2)对于p,如果我修改字符串文字,则行为未定义,即有时它被修改,有时不修改。为什么这样的设计。实际上,对于out of bound数组访问,这是可以理解的,因为你访问之前没有分配的内存,有时你没有权限访问那段内存所以,分段错误。但有时为什么我可以修改字符串文字。为什么这样。这背后的原因是什么。

1 个答案:

答案 0 :(得分:5)

char *p = "Something";//I cant change the data
char q[] = "Wierd"; // I can change to what q points to

pchar*指向10个char的数组的第一个元素(不要忘记0终结符),不允许修改(尝试修改字符串文字是未定义的行为;大多数实现将字符串文字存储在只读内存中,然后这样的尝试会导致段错误,但是修改字符串文字的尝试可能会修改数组而不是崩溃)。您可以自由更改p,当它更改为指向可修改的对象时,您可以通过*p修改该对象。

q是一个包含六个char s(再次为0-terminator)的数组。您无法为q分配任何值,但您可以修改数组的内容。

p = q;

p指向数组q的第一个元素。在该上下文中,q被隐式转换为指向其第一个元素&q[0]的指针,因此p = &q[0];实际发生的是p。现在*p = 'x'; 指向可修改的对象,因此

char
允许

并更改q中的第一个p = "Something"; q[0] = 'W';

p

char再次指向您不允许修改的q数组的第一个元素,并将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 *’

char hello[] = "Hello"; char world[] = "World";

错误消息有点误导,您无法分配数组。即使使用hello = world; produces the same error (since in that context,,尽管两个数组都具有相同的类型,但您无法分配,*q = 'x';//This works fine as this is possible to change Value for q world`将转换为指向其第一个元素的指针,但错误消息并没有错误。

*q

是的,q[0]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) 相同,因此在许多情况下你可以使用像指针这样的数组(反之亦然)。但总的来说,数组和指针是不同类型的东西。

const char *

char const *char的意思完全相同,指向不可修改的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. (通常是数组中的第一个)。

t

t是一个常量指针,您无法更改指向的位置,但根据类型,您可以修改它指向的对象。但是,在这种情况下,char指向字符串文字的第一个t,因此不允许您将对象t更改为(但这不是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 []. 类型的后果。

u

同样,两者的含义相同,vconst char//char w const [] = "To make";//This is not possible 的数组,由于它们的类型,不允许更改这些数组的内容。

//*r = 'x'; // This is not possible
//Error comes is:
//error: assignment of read-only location ‘*r’

是的,这是无效的语法,你不能在数组名和括号之间有一个类型限定符。

r

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

结论是错误的,如果您将q更改为指向可修改的对象,例如r,您仍然无法通过p更改它,该类型禁止它。但您可以通过*r = 'x';修改它。对于字符串文字的指针,通常不同之处在于*p = 'x';是编译失败而p是分段错误,但对于一般情况,通过p进行修改是有效的(通常是& #34;工作&#34;如果const char arr[10]指向r = s; 的元素,但这又是未定义的行为,它通常不会导致崩溃,与字符串文字的对比)。

r

好的,没问题。您可以更改指向的r对象,即您更改r,但不要更改指向的对象r = t;

t

也没问题。如果t指向可修改的对象,则可以通过r修改对象,但不能通过t修改对象。但是当t指向一个字符串文字时,你不能通过任何一个修改对象//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)) 指向,但同样,一个是编译错误,另一个可能是段错误。

const

const char *r;读为&#34;只读&#34;。拥有char意味着您有一个指向const的指针,编译器将不允许您使用它来修改指向对象,您只能使用它来读取对象。它指向的对象是否被声明为const并不重要,r声明中的r仅限制//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. 可以使用的内容for,而不是通过其他指针对指向对象可以做什么。

*r = 'x';

我不确定我理解你的&#34;为什么(3)&#34;,但如果我理解正确,你希望r = q;能够在r后工作,从那以后const指向可修改的对象。然后答案就是我上面写的,r声明中的r限定符限制了您可以通过const执行的操作,它独立于r指向对象的状态。这也回答了(4),*r = whatever;的类型禁止作业//Conclusion: Writing const after or before char makes no difference.

const

然而,*之前或之后const char *r;是否出现,会有所不同。 char * const x = q;声明一个不能用于修改指针的指针,const char * const y = q;声明一个指向同一位置的指针;您可以使用它来修改指向对象(如果允许的话)。并且//*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 = 'x';

您无法t因为t碰巧指向字符串文字。如果您初始化q以指向//t = r; ,则可以允许这样做。

t

由于您宣布t无法修改,因此无法更改,因此您无法更改指向的位置。

//(5)为什么会这样。为什么左手边始终优先。为什么这不会发生p = q,     //因为对于值的改变,t = q和p = q在赋值的左侧和右侧都是非常相同的。

我不确定问题是什么。您声明constt,这意味着您无法分配到const int i = 100;。对于i = 120;,它将是相同的,您将不被允许在您的程序中编写//*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

//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.

右。

const char*

不仅仅是&#34;有点&#34;。您正在为char*分配char *p。指向的对象可能是不可修改的,但尝试通过p修改它是正式有效的,如果指向的对象是可修改的,使用const修改它甚至是合法的。但是,如果指向的对象不可修改,则使用p限定符声明字符串文字,尝试通过const修改它是未定义的行为。因此丢弃// 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) 限定符是一件危险的事情,编译器就会发出警告。然而,它可能是完全合法的,所以它只是一个警告,而不是一个错误。您可以通过使用显式强制转换告诉编译器您知道自己在做什么(无论您是否这样做)。

char * const

您正在为char*分配t,此处没有任何遗失。分配const的值不会更改它,*之后的t仅表示您无法更改//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) 指向的地址。

p = r;

//Value Change //Segmentation fault for everything . //Conclusion: Understndable if assume left hand side are given precedence except for p = q (showed in I.) 相同。

char[]

分段错误只是因为你让指针指向字符串文字。如果您指向*ptr = 'x';,则分配const char将工作或不编译,具体取决于指针是声明指向char还是仅指向const char。如果你引入了几个const char*数组,那么赋值当然也不会为char*编译,但它会为const编译(带有关于丢弃char *p = "Something";的警告运行程序调用未定义的行为(它可能不会崩溃并修改数组内容,但任何事情都可能发生)。


关于其他问题:

  

1)对于p case对象是一个字符串文字(一个可以修改),即它是右手边对象的属性,而对于RHS上的q,我有相同的东西,但现在它表现不同。为什么这种不一致的设计。

我不确定你的想法有什么不同。在char *p = q;p中,指向对象的属性确定char[N]的用途是有效的。两者中的任何一个都不能通过其类型进行修改(对于某些N都是char *p;),但字符串文字是不可修改的,作为标准定义的特殊情况。

声明p(此处未进行初始化,但有一个不存在或不重要)将char q[] = "Wierd"; 声明为可用于修改指向的指针。但是,这种修改指向对象的尝试是否有效,取决于指向对象的属性。

q

将字符串文字的内容复制到数组q(包括0终结符),因此p初始化为字符串文字的可修改副本。让char指向数组q中的某些p会使p指向可修改的对象,并且此类修改有效。

const指向const char c = 'C'; p = &c;限定对象,p比较危险,因为*p = 'x';的类型不会阻止p从编译 - 毕竟,编译器一般不知道在那一点const是指向const char*限定对象,还是可修改对象(赋值可能来自{{} 1}}被指向一个可修改的对象),或根本没有有效的位置。

因此赋值p = &c;会导致编译器发出警告(至少编译器的警告级别足够高,但在gcc和clang中,例如,默认情况下启用),甚至中止带错误的编译(如果传递-pedantic-errors标志,则执行gcc和clang)。语言标准禁止该分配而不明确地将const char * &c强制转换为char*,但只需要诊断,因此编译器可以自由地将其作为警告或错误。

如果你只使用指针来指向一个不可修改的对象时从指向对象读取,这是一个合法的用途,所以这个任务不会被无条件禁止(与演员,它&& #39;标准允许并且甚至不会引起警告,因为演员告诉编译器&#34;我知道我在做什么&#34;)。

因此*p = 'x';是否有效,只能由指向对象的属性决定。如果指向的对象是不可修改的(或者如果p根本没有指向有效对象),则行为是未定义的。未定义的行为如何表现为未定义,但在这种情况下,通常要么是分段错误(如果对象驻留在写保护的内存区域中),要么修改指向对象,就像它被允许一样(如果只有该类型使对象不可修改,并且实现没有采取额外措施来识别这种无效写入)。在字符串文字的情况下,由于历史原因,键入char[N],通常它们存储在程序的.rodata(只读数据)部分,并尝试写入由操作系统检测到并导致段错误。

  

2)对于p,如果我修改字符串文字,则行为未定义,即有时它被修改,有时不修改。为什么这样的设计。实际上,对于越界数组访问,这是可以理解的,因为您访问之前尚未分配的内存,有时您无权访问该内存,因此,分段错误。但有时为什么我可以修改字符串文字。为什么这样。这背后的原因是什么。

语用学

定义语言的委员会并不想将实施者与实施者联系起来。手中。程序员有义务避免未定义的行为,如果他没有,则无论发生什么事情都会发生。

从历史上看,据我所知,有些实现将字符串文字存储在只读存储器中,而实现的则不存在。当语言标准化(创建后近20年,行为多样化)时,主要是对现有常见做法的记录。由于编译器,库或硬件的差异,行为差异很大,因此未定义或实现定义,以允许尽可能多的平台上的符合实现。因此,一些实现允许修改字符串文字,其他实现没有,委员会决定通过使行为未定义来给程序员带来负担。