以下是我对C中字符串的一些基本问题。
char * string =“Hello world”;
const char * string =“Hello world”;
char * str =(char *)malloc(sizeof(char));
的scanf( “%S”,STR);
的printf( “%S \ n” 个,STR);
答案 0 :(得分:2)
1. 以下两个初始化之间有什么区别。 不同之处在于错误的编译和运行时检查,正如其他人已经告诉过的那样。
char * string =“Hello world”; --->存储在只读数据段中 无法更改,但如果您更改该值,则编译器不会给出 任何错误只会在运行时出现。
const char * string =“Hello world”; --->这也存储在读取中 只有具有编译时检查的数据段,因为它被声明为 const所以,如果你要更改字符串的值,那么你将得到一个 编译时出错,这比运行时的失败要好得多。
2. 请指导正确使用字符串的动态分配。
char *str = (char *)malloc(sizeof(char));
scanf("%s",str);
printf("%s\n",str);
此代码可能会有效,但并非总是如此。问题出现在run-time
,当您访问segmentation fault
时,area of memory
会被您的程序拥有你应该在这个dynamic memory allocation
中一直非常小心,因为它会导致非常危险error at run time
。
你应该始终allocate the amount of memory you need correctly
。
最大的错误发生在use of string
期间。您应该始终牢记is a '\0' character present at last of the string
,并且在分配期间your responsibility to allocate memory for this.
希望这有帮助。
答案 1 :(得分:1)
以下两个初始化之间有什么区别。
由于遗留原因,字符串文字的类型为char*
。最好只通过const char*
指向它们,因为不允许修改它们。
我看到以下分配足以容纳一个任意长度的字符串。
错误。此分配仅为一个字符分配内存。如果您尝试在string
中写入多个字节,则会出现缓冲区溢出。
动态分配内存的正确方法很简单:
char *string = malloc(your_desired_max_length);
此处显式强制转换是多余的,sizeof(char)
按定义为1。
另外:请记住,字符串终结符(0)也必须符合字符串。
答案 2 :(得分:1)
两个声明之间的区别在于,如果尝试通过const char*
声明的指针修改字符串文字,编译器将产生错误(这比运行时故障更可取)。以下代码:
const char* s = "hello"; /* 's' is a pointer to 'const char'. */
*s = 'a';
导致VC2010发出以下错误:
错误C2166:l-value指定const对象
尝试修改通过char*
声明的指针生成的字符串文字,直到运行时才会检测到(VC2010没有发出错误),其行为未定义。
当malloc()
内存用于存储字符串时,必须记住分配一个额外的char
来存储空终止符作为所有(或几乎所有)C字符串处理函数需要null终止符。例如,要分配缓冲区以存储"hello"
:
char* p = malloc(6); /* 5 for "hello" and 1 for null terminator. */
sizeof(char)
保证为1,因此不需要,并且无需转换malloc()
的返回值。当不再需要p
时,请记住free()
已分配的内存:
free(p);
答案 3 :(得分:1)
在第一种情况下,您明确地将char*
强制转换为const
,这意味着您在编译器级别禁止对其后面的字符进行更改。在C中,实际上是未定义的行为(在运行时)尝试修改这些字符而不管它们的常量,但是字符串文字 是char *
,而不是const char *
在第二种情况下,我看到两个问题。
第一个是你永远不应该从malloc
转换返回值,因为它可以掩盖某些错误(特别是在指针和整数大小不同的系统上)。具体来说,除非有适当的malloc
原型,否则编译器可能会认为它返回int
而不是正确的void *
。
因此,如果您忘记包含stdlib.h
,您可能会遇到编译器无法警告您的一些有趣行为,因为您通过明确的演员告诉它您知道你在做什么。
C完全能够在从void *
返回的malloc
和任何其他指针类型之间进行隐式转换。
第二个问题是它只为一个字符分配空间,这将是一个字符串的终止空值。
最好写成:
char *string = malloc (max_str_size + 1);
(并且不要乘以sizeof(char)
,这是浪费时间 - 它总是 1)。
答案 4 :(得分:1)
以下两个初始化之间的差异。
首先, char * string =“Hello world”;
- 将“Hello world”存储在堆栈段中作为常量字符串,并将其地址分配给指针的字符串'变量 “Hello world”是不变的。并且你不能做字符串[5] ='g',这样做会导致分段错误 其中'string'变量本身不是常数。你可以改变它的约束力:
string =“其他一些字符串”; //这是正确的,没有分段错误const char * string =“Hello world”;
再次将“Hello world”存储在堆栈段中作为常量字符串,并将其地址分配给“string”变量。 并且字符串[5] ='g',这会导致分段错误 这里没有使用const关键字!
现在,
char * string =(char *)malloc(sizeof(char));
以上声明与第一个相同,但这次你的分配是来自堆段(不是来自堆栈)的动态
答案 5 :(得分:0)
代码:
char *string = (char *)malloc(sizeof(char));
不会持有任意长度的字符串。它将分配一个字符并返回一个指向char字符的指针。请注意,指向字符的指针和指向字符串的指针是相同的。
要为字符串分配空间,您必须执行以下操作:
char *data="Hello, world";
char *copy=(char*)malloc(strlen(data)+1);
strcpy(copy,data);
您需要准确地告诉malloc
要分配的字节数。 +1
用于需要结束的空终止符。
对于存储在只读段中的文字字符串,这是一个实现问题,尽管几乎总是如此。大多数C编译器都非常放松地对这些字符串进行访问,但是尝试修改它们会遇到麻烦,所以你应该总是声明它们const char *
以避免任何问题。
答案 6 :(得分:0)
这个特定的分配可能看起来有效,因为程序堆中可能有足够的空间,但事实并非如此。您可以通过使用建议的方法和memcpy分配两个“任意”字符串来验证它:将足够长的字符串分配给相应的地址。在最好的情况下,你会看到垃圾,在最坏的情况下,你会有分段错误或从malloc或free中断言。