楼上说的都有道理,但是没解释出本质区别。
区别就在于两个定义中str的类型不同。
第一个,在
char * str;
中,明显str的类型是char*。这没什么特殊的,只是一个简单的char指针。
第二个,char str[];是不能这样定义的,所以假定用
char str[6] = "abcde";
那么这里str的类型是char[6](6个,不是5个,因为最后有个0) ,而这种定义语句也是定义一个char[6]类型的唯一方法。char[6]是什么意思呢?他不是char*,也不是char* const (以下讨论这个),而是一个特殊的类。这个类的大小是6字节(比如sizeof(str)返回6),它可以用[ ]来返回一个char&(比如str[3]的类型是char&),但是自身不能直接被修改,比如str ="abcde";就不可以。
我刚才说char[6]很像char* const。这是因为,假如有
char* const str2 = "abcde";
那么str和str基本有同样的行为,比如str2[3]也是一个char&,而且str2 = "abcde"也不可以用,但是char* const和char[6]有本质的不同。前者只是一个指针。什么意思呢,就是str2的值是"abcde"的地址(而"abcde"被存在其他的地方),而str的内存值直接就是6个字节,"abcde"。所以两者还是截然不同的类型。比如,sizeof(str2)是4(32位操作系统)或8(64位),而sizeof(str)是6.
char[6]可以被直接转换为char*。转换的时候,得到的结果是一个指向第一个元素的指针。反过来,char*也可以转换为char[6],转换的结果是一个变量指向char*所指向的那个内存区域。
楼上说的str++可以在char* str时用而不能在char str[6]时用,这是因为数组类型 char[6]不能用作一个左值。
楼上还有说char * str可以指向任何字符串常量。这个是无必要的。char *可以指向任何内存区域,不一定必须是字符串常量。当然,如果指向一个无效内存,用的时候会出问题。
另外楼上说一个"Hello World!"放在常量储存区,一个"Hello World!"放在线程堆栈区,这也是不对的。事实上,无论如何,"Hello World!"本身都在常量储存区。而:
char *str = "Hello World!";
会在堆栈上储存一个4个字节(假定32位系统)的指针指向储存"Hello World!"的区域。
而
char str[] = "Hello World!";
会首先在堆栈上先分配一个13字节的char数组,然后把常量储存区的那个"Hello World!"复制过来。
追问#include
void main()
{
int i;
char *s="eff"; /*您说说s[i]时,char*与char s[]="eff"的区别 为什么这程序里char*是乱码 另一个程序就这样调用没问题*/
for (i = 0; s[i] != '\0'; i++)
{
if ((s[i] >= 'a') && (s[i] <= 'z'))
{
printf("az %d %s\n",s[i],s);
s[i] = s[i] - 32;
printf("az %d\n",s[i]);
}
}
printf("[%s]\n", s);
}
本回答被网友采纳