const char *p的形式可以修改p的值合法,也就是让p指向别的字符串合法,但是通过p修改指向的内容是非法的;使用char p[]的形式,修改p指向的值合法,但是修改p的值非法。
1.首先你要清楚“字符串字面值”是什么?“字符串字面值”就是形如你文中的"RF1_230220901"这样的一个不可寻址的一个字符串,它是右值,不可寻址意味着你不能使用取地址符&来取它的地址,对应的汇编语言是个立即数,但是这个字符串字面值在虚拟内存中仍然占有一个位于常量区的地址空间,地址即字符'R'的存储地址。尤其要注意,这样的字面值常量,在最后一个字符,这里是'1'的后面,一定有个隐匿的‘\0’字符来表示字符串字面值的结束。
2.使用const char * p = "RF1_230220901"这样形式来表示一个字符串,就是让指针p指向这个字面值常量,也就是'R'的地址,因为"RF1_230220901"放在常量区,你不能通过p去修改字符串的内容,但是你通过p去访问每个字符仍然是允许的,就是说,可以*(p+1)去访问'F'这个字符,但是你试图去修改p+1这个地址里面的内容,就是*(p +1) = 'L‘这样是是非法的,因为常量区的数据不能修改。你还可以用这个指针指向别的字符串,比如你现在const char * p = "1234"也是合法的。
3.使用 char p[] = "RF1_230220901"这样的形式,是把"RF1_230220901"这个内容,不包含结尾的'\0'字符拷贝给这个字符数组,因为这个数组没有结束字符'\0',所以使用strlen(p)这样的函数,行为未定义,程序会崩溃,但是因为这是个字符数组,你可以修改字符数组中的内容,比如*(p + 1) = 'Q'这样是合法的,但是你试图修改p的值,也就量数组名的值是非法的。
|