#include<stdio.h>
int main()
{
char* t="C++";
t[1]='p';
t[2]='p';
printf("%s",t);
return 0;
}
#include<stdio.h>
int main()
{
char* t="C++";
t[1]='p';
t[2]='p';
printf("%s",t);
return 0;
}
C字符串字面量创建一个匿名的char
数组。任何尝试修改该数组的行为都是未定义的。理想情况下,这应该通过将数组设为const
来实现,但C并不总是有const
,而将其添加到字符串字面量中会破坏现有代码。
char* t="C++";
这是合法的,但潜在风险很高。包含字符'C', '+', '+', '\0'
的数组可能存储在读写内存或只读内存中,取决于编译器的心情。
t[1]='p';
在这里,您的程序行为是未定义的,因为您正在尝试修改字符串常量的内容。编译器不需要在编译时或运行时警告您,也不需要采取任何措施使其“工作”。
如果您想让编译器知道该字符串是只读的,最好自己添加const
限定符:
const char *t = "C++";
t
尝试这样做的话。如果您想要能够修改它,您应该将t
设置为可写数组。char t[] = "C++";
t
指针指向"C++"
的开头,这样做将t
变成一个数组,将"C++"
的内容复制到其中。只要不超出其范围,您可以随意处理t
的内容。#include<conio.h>
<conio.h>
是专门为 Windows (和 MS-DOS) 设计的。如果您的程序不需要在其他系统上运行,那么保留它是可以的。如果您希望它具有可移植性,请将其删除。
void main()
int main(void)
(在C语言中,int main()
是有问题的,但在C++中是正确的。)printf("%s",t);
printf("%s\n", t);
}之前包含以下行:)
getch();
后来OP将其删除了。这是特定于Windows的。在Windows开发系统中,保持输出窗口不关闭可能是必要的,这是一个不幸的问题。如果您想要更标准的方法,getchar()
只需从标准输入读取一个字符,并让您按下 Enter 键完成(尽管它不会给您提示)。或者,如果您从IDE或命令提示符中运行程序,则大多数情况下它们不会立即关闭窗口。
最后,由于main
返回类型为int
,因此实际上应该这样做;您可以添加
return 0;
在闭合的}
之前加上这句话并不是必须的,但这并不是一个坏主意。(C99添加了隐式的return 0;
,但Microsoft不支持C99。)(更新于2019年:Microsoft对C99功能的支持略有改善。我不确定是否需要return 0;
。)
char s[] = "foobar";
,将字符串文字内容复制到数组中是在编译时还是运行时完成的? - torez233“C++”是一个字符串字面量,存储在只读位置,因此不能被修改。由此可见-
char* t="C++"; // t is pointing to a string literal stored in read only location
char t[] = "C++" ; // Copying the string literal to array t
实际上要做的是 -
t[1] = 'p' ;
您的代码还存在其他几个问题。
指针通常用于指向已经存在的数据,这样您就可以像这样使用它:
char arr[] = "C++";
char* t = &arr[0];
此外,可修改的,
t[1] = 'p';
t[2] = 'p';
当然,使用字符串有一种特殊的方式——让指针指向一个字符串常量。就像你所使用的方式:
char *t = "C++"; // you cannot modify it in most operating systems
t[1] = 'p';
t[2] = 'p';
有一种更好的使用方式,更加便携和易于理解:
const char* t="C++";
2. 你的代码有很多不符合C标准的地方。
#include <stdio.h> // You'd better add a space between, for this is a good coding convention
#include <conio.h> // only supported by vc/vs in windows, you can use getchar() instead
int main() // main returns int
{
char* t = "C++";
t[1] = 'p';
t[2] = 'p';
printf("%s\n", t); // it's a good habit to add a '\n' when printing a string
getchar(); // getchar() is supported by c standard library
return 0; // return 0 here
}
3.关于打印字符串
Linux是行缓冲的(如果您使用Windows,则忽略此信息:P),为了在控制台中更易于阅读,最好在您打印的字符串末尾添加'\n':
printf("%s\n",t);
printf("%s",t);
在Linux中,您应该在stdlib.h中添加fflush()函数。printf("%s",t);
fflush(stdout);
char* t="C++";
没有任何问题。字符串字面量提供了一个静态分配的4个元素数组形式的“已经存在的数据”。(指针应该是 const
,但不一定非得这样。) - Keith Thompsonfflush
声明在 <stdio.h>
中,而不是 <stdlib.h>
。无论如何,最好打印换行符;如果您不想打印,那么还是应该这样做。 - Keith Thompson#include<stdio.h>
是完全可移植的——但添加空格确实可以提高可读性。没有必要调用 fflush(stdout)
,当程序终止时所有输出文件都会被刷新。 - Keith Thompson一些标准运行库的版本需要使用\n
来使输出出现。
printf("%s\n",t);
\n
不是问题,但可能会成为一个问题。"最后一行是否需要终止换行符是实现定义的。"--N1570 7.21.2p2。如果实现需要一个终止换行符而程序没有提供,则行为是未定义的。在Windows和POSIX/Unix/Linux下,它将只打印字符串而没有换行符(如果将shell提示符连接到输出上,则可能会造成视觉上的混淆)。 - Keith Thompson
main
返回的是int
类型,而不是void
类型。 - GManNickG'\n'
,printf()
输出可能会在下一条语句执行之前不显示(默认情况下,流stdout
是行缓冲的)。请尝试使用printf("%s\n", t);
或printf("%s", t); fflush(stdout);
。 - pmg'\n'
是实现定义的。如果需要,那么即使使用fflush(stdout)
,行为也是未定义的。最好的方法是直接打印换行符,这样更容易和可靠。(在许多系统上,换行符不是必需的,但如果缺少它,输出将与下一个 shell 提示相邻,这很丑陋。) - Keith Thompson