2015-08-23 50 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
void fit(char *p , int n); 
int main(void) 
{ 
    char *mesg = "Hey, Lisa. You look so beautiful! "; // Line A 
    puts(mesg); 
    fit(mesg , 6); 
    puts(mesg); 
    system("pause"); 
    return 0; 
} 

void fit(char *p , int n) 
{ 
    if(strlen(p) > n) 
     *(p + n) = '\0'; 
} 

查看上面的代码。函数拟合设计为通过在位置n + 1中放置'\ 0'来仅显示字符串的前n个字符。问题来了。如果在行A中,* mesg被mesg []替换,程序工作正常。但* mesg不起作用。我使用vs2012。我知道*名称中的名称是一个变量,所以名称++是可以的,而名称[]中的名称是常量,因此名称++是不允许的。除了这个区别之外,在声明一个字符串时不应该使用* name和name []是否相同?*声明字符串时,*名称和名称中的不同*

+5

您可以修改字符数组,但不能修改字符串文字。见http://stackoverflow.com/q/1614723/10077 –

+4

这是一个历史遗产,它不要求'char * mesg'是const char * mesg',但它应该是,改为const char * mesg '和编译器应该在'fit(mesg,6)上出现错误;' – chux

回答

3

在C语言中,适用下列规则(其中一些并不适用于其他类似C++):

  1. 阵列可能会降低到指针,可能是由于在第4条所述的损耗其恒定特性。
  2. x[y]形式的任何表达式相当于*(x + y)
  3. 字符串文字表示以空字符结尾的字符数组。
  4. 给定数组的变量名称a是常数,并且等效于&a[0]
  5. 对于任何非常数,非易失性类型T,类型T的表达式可能被分配给一个变量名称,该变量名称的类型可能包含或不包含常量和/ o易失性限定符,如果不合格将具有类型T ,但是一个常数和/或易失性限定的表达式,并且在不合格时具有T类型的表达式可能不会被分配给缺少这种表达式限定符的变量名称。

这意味着所有下面的任务都有效:

  • char str[] = "Hello, world!\n",由于第3条
  • const char str[] = "Hello, world!\n",由于规则3和5
  • volatile char str[] = "Hello, world!\n",由于规则3和5.
  • const volatile char str[] = "Hello, world!\n",由于规则3和5.
  • char *str = "Hello, world!\n",du E要规则3和1
  • const char *str = "Hello, world!\n",由于规则3,1和5
  • volatile char *str = "Hello, world!\n",由于规则3,1和5
  • const volatile char *str = "Hello, world!\n",由于规则3,1,和5.

鉴于规则4和5,以void fit(char*, int)呼叫应如果分配给所述第一参数中的表达是不合格的,例如,如果给定的发言const char *mesg = "Hey, Lisa. You look so beautiful!";,变量名mesg被分配到第一故障在致电void fit(char*, int)

仅仅为了完整性,规则1被规则2所强调,如表达式*(p + n) = '\0'所示,只要p在赋值时从数组中退化。

tl; dr:您所描述的两种情况之间的大部分差异发生在限定符不匹配发生时,如上述规则5所述。这主要是由于“历史原因”(即“e:懒惰),并影响了其他语言。例如,C++保存了一些“与C的兼容性”,换句话说,与懒惰的兼容性。

3
char *mesg = "Hey, Lisa. You look so beautiful! "; // Line A 

在这里,这是字符串文字,这样一个常量,你不能修改它的值。

什么,你不能做的是 -

mesg[0]='A'; 

而且还你已经在你的代码所做的是错误车道

*(p + n) = '\0'; // equivalent to p[n] 

mesg[]="Hey, Lisa. You look so beautiful! "; // would be same as your declaration if declared as const char mesg[]

在此声明表达正在用于初始化另一个数组的内容,因此不会将其转换为指针类型,而是将内容的字符串文字被复制到mesg

+0

尽管如果OP已经声明它为'char mesg []',那么你在这里所说的会在这种情况下不正确... – 3442

+0

@KemyLand请看一下。是的,我明白你的意思,我已经做出了改变,并感谢你的输入:) – ameyCU

+0

是的,一切都是正确的。更好的编辑比回答错误:)。 – 3442