在调试C语言程序时遇到的情况
指向指针的数组定义如下:
char * msg[5] =
{
" Thank you for the wonderful evening, ",
"You certainly prove that a ",
"is a special kind of guy. We must get together",
"over a delicious ",
" and have a few laughs"
};
然后定义了一个指向char*类型的指针:
char* *pt=msg;
当我想用下面语句修改字符串其中一个字符时出现异常:
**pt='K';//编译没错误,但运行出现异常
就是将msg[0]元素的第一个字符修改为k时出现的异常,整体修改数组元素就没有任何问题
譬如:*pt="fajlgjalhglajlg";//运行正常
char* 是 const 类型,允许你对用字符串给char* 赋值,比如这样:
*pt="fajlgjalhglajlg";
但是,你不能用 pt 这个指针去修改字符串中的文字,比如:
**pt='K' ;
你可以用字符串数组来解决这个问题,也就是这样 char[] ....
在C++中,如果用指针来援引字符串,比如: char *p="hicjiajia"; 此时该字符串为常量,不可以用指针p进行修改,比如:p[0]='Q'; 因为不可以修改常量值;如此定义字符数组道理是一样的,无非是多了几个常量指针,如:p[0]、p[1]、p[2]等,这些指针指向的字符串都是常量,不可以随意更改。如果你想可以修改的话,就需要定义成数组形式如: char p[]="hicjiajia"; 此时的 p[0]='Q'; 则是正确的。
至于*pt="fajlgjalhglajlg"; 是可以的,这里你首先要明白这几点:这里的*pt是一个指针,它里面存放地址,等价于pt[0]或者*(pt+0) ;另外,每一个字符串都是一个地址,这句话只是让*pt指针改变了指向,现在它指向了新的字符串"fajlgjalhglajlg"; 原字符串"Thank you for the wonderful evening" 并没有被覆盖掉,它还在捏呢。
如果你是在不甘心,想按照你自己的思路来,你可以这样定义字符数组:
char msg[5][80]={
" Thank you for the wonderful evening, ",
...........
}
然后这样来调用: msg[0][0]='K';
C++标准中如是说
Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementationdefined. The effect of attempting to modify a string literal is undefined.
根本原因是:你数组内的那些字符串都是常量, 存放在内存的文字常量去,这里的数据是只读的,不可修改。
下面代码语句的错误原因与你的代码一致,请体会:
char *str = "Hello world" ;
*str = 'G' ; // "Hello world" 在文字常量区,不可通过指针或地址改变。
str = "Test linux"; // 这句是可以的,因为改变的仅仅是str这个指针,"Test linux"依然在文字常量区,它赋给str仅仅是它在常量区的地址。
你这个问题怎么说呢,你要搞清楚你硬编码的那些字符串是常量字符串,你试图用指针修改其内容就会报错,这就是**pt='K' ;报错的原因,因为你试图修改一个常量字符串的第一个字符。
而:*pt="fajlgjalhglajlg";//运行正常这个很简单,
因为你修改的是msg[]数组里的元素的值(改变了msg[0]指向的地址,指向另一个常量字符串),这个当然是可写的。