以下程序由于未定义的行为(尝试修改字符串文字)而引发系统分段错误:
int main() {
char *s = "immutable";
s[0] = 'a';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尽管如此,似乎绝对没有办法告诉GCC/Clang甚至发出最轻微的警告(-Wall -Wextra -pedantic -std=c11不做任何事情).
特别是对于初学者来说,这种情况对于告知有用.即使对于非初学者,在一些稍微不那么明显的情况下,它可能会有所帮助:
void f(char *s) {
s[0] = '0';
}
int main() {
char *s = "immutable";
f("literal"); // oops
f(s); // oops
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此外,这将有助于const在C编程中强制实施一些文化.
为什么故意忽视此类案件?标准是否主动禁止在这种情况下发出诊断,或者主要是为了向后兼容(现在尝试强制执行它们会产生太多警告)?
似乎strtol()并且strtod()有效地允许(并强制)你在字符串中抛弃constness:
#include <stdlib.h>
#include <stdio.h>
int main() {
const char *foo = "Hello, world!";
char *bar;
strtol(foo, &bar, 10); // or strtod(foo, &bar);
printf("%d\n", foo == bar); // prints "1"! they're equal
*bar = 'X'; // segmentation fault
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面,我自己没有演出.然而,strtol()基本上把我const char *变成了一个char *对我来说,没有任何警告或任何东西.(事实上,它不会让你输入bar的const char *,所以迫使类型的不安全的变化.)是不是真的很危险?
根据C++标准,字符串文字类型是 array of const char
auto constStr = "aaa";
char* nonConstStr = constStr; //Error here, cannot convert from 'const char *' to 'char *'
char* stillNonConstStr = "aaa"; //Why I don't have error here?
Run Code Online (Sandbox Code Playgroud)
你能解释一下为什么在第3行我没有收到错误吗?
根据http://www.cplusplus.com/reference/cstdlib/strtol/,此功能有一个签名long int strtol (const char* str, char** endptr, int base).
我想知道,如果它被传递const char *到字符串的开头,它如何设法将其转换为非const指针指向第一个未处理的字符而不作弊?什么是strtol的实现看起来不会执行const_cast?
我决定创建一个使用Linux系统调用的简单猜测数字游戏,以及一些C函数来提供更简单的界面.当我将int转换为字符串并在屏幕上打印正确答案时,我似乎遇到了分段错误.
这是输出:
Enter A Number One Through Ten:" :
3
Response did not match! The Answer Is:Segmentation fault
Run Code Online (Sandbox Code Playgroud)
这是C代码:
// print.c
#include "/usr/include/stdio.h"
#include "/usr/include/string.h"
#include "/usr/include/stdlib.h"
#include "/usr/include/time.h"
void print(const char* msg)
{
printf(msg);
return;
}
int compare(const char* str, const char* str2)
{
int i = strcmp(str, str2);
if (i == 0)
{
return 1;
}
else
{
return 0;
}
}
int divide(int num, int dem)
{
if (dem == 0)
{
printf("Undefined");
return 0;
}
else …Run Code Online (Sandbox Code Playgroud) 我知道c中文件范围的初始化器的限制:你不能使用变量(甚至const),函数等......但是我真的不明白为什么这不起作用:
#include <stdlib.h>
#include <stdio.h>
//unsigned long a = "string"[0] > '0'; // this does not compile
unsigned long a = 's' > '0'; // this works fine, output is "a = 1"
int main(void)
{
printf("a = %lu\n",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么带有字符串文字的行给出:错误:初始化元素不是常量.字符串文字不被视为常量吗?有没有办法使它工作?
提前致谢
我很困惑为什么编译器给出
const char s[]="hello";
s[2]='t'; // Compile Time Error
char *t = "hello";
*(t+2)='u'; // Run time Error
Run Code Online (Sandbox Code Playgroud)
我想在这两种情况下编译器都应该给出编译时错误.任何人都可以告诉我这种方式的特殊原因吗?
可能重复:
字符串文字是否为常量?
以下是否在ANSI C中有效?
#include <stdio.h>
/* This returns "Hans" if arg != 0, "Gretel" if arg == 0 */
char* foo(int arg)
{
return arg ? "Hans" : "Gretel";
}
int main()
{
char* p_ch;
p_ch = foo(1);
printf("%s\n", p_ch);
p_ch = foo(0);
printf("%s\n", p_ch);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该代码在GCC/Linux下编译并运行良好.
MinGW/Windows说:
invalid conversion from `const char*' to `char*'
Run Code Online (Sandbox Code Playgroud)
MS Visual C/C++ 2008对代码很好.
char*变量分配给文本字符串,而不是在初始化时吗?static位置类.这是否意味着它们在定义的函数之外是不可见的?const类型到非const对应的转换何时无效?我认为这个问题是这个SO答案的延伸.说我有以下代码:
#include <stdio.h>
#include <string.h>
void func(char *str)
{
strcpy(str, "Test");
}
int main()
{
char testStr[20] = "Original";
func(testStr);
printf("%s\n", testStr); /* Prints "Test" followed by a new-line */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,不应该func期望指向只读文字的指针作为参数?然而,传递的是只读文字堆栈上的副本.
即使这会产生正确的结果,这样做是否100%正确?难道提高代码的可读性,如果func()接受char [],而不是char *?
我正在写C并且必须返回一个char*我正在尝试复制strcpy函数.我有以下代码
int main()
{
char tmp[100];
char* cpyString;
const char* cPtr = &tmp[0];
printf("Enter word:");
fflush(stdin);
scanf("%s", &tmp);
cpyString = strcpy("Sample", cPtr);
printf("new count is %d\n", strlen(cpyString));
}
int strlen(char* s)
{
int count = 0;
while(*(s) != 0x00)
{
count++;
s = s+0x01;
}
return count;
}
char* strcpy(char* dest, const char* src)
{
char* retPtr = dest;
int i =0;
int srcLength = strlen(src);
for(i = 0; i< srcLength; i++)
{
*(dest) = *(src); //at this line program …Run Code Online (Sandbox Code Playgroud)