C上的字符串behvior
我想了解一些关于C上字符串的事情: 我不明白为什么你不能在正常的作业中更改字符串。(但仅通过string.h的函数),例如:我不能执行C上的字符串behvior,c,string,scanf,C,String,Scanf,我想了解一些关于C上字符串的事情: 我不明白为什么你不能在正常的作业中更改字符串。(但仅通过string.h的函数),例如:我不能执行d=“aa”(d是字符指针或字符数组)。 有人能给我解释一下幕后发生了什么吗?编译器给你运行这样的东西,你会收到分段错误 另外,我用C语言运行了一个程序,其中包含以下行: char c='a',*pc=&c; printf("Enter a string:"); scanf("%s",pc); printf("your first char is: %c"
d=“aa”
(d是字符指针或字符数组)。
有人能给我解释一下幕后发生了什么吗?编译器给你运行这样的东西,你会收到分段错误
另外,我用C语言运行了一个程序,其中包含以下行:
char c='a',*pc=&c;
printf("Enter a string:");
scanf("%s",pc);
printf("your first char is: %c",c);
printf("your string is: %s",pc);
请注意:我不希望该程序运行,我问这个问题不是为了获得其他程序的建议,我只是想了解在这些情况下幕后会发生什么。如果我在scanf上输入了两个以上的字母,我会出现分段错误,为什么会发生这种情况? 因为内存只分配给一个字节。 请参见
char c
并用指定“a”
。它等于'a'
和'\0'
写入一个字节的内存位置
如果
scanf()
使用此内存读取多个字节,那么这只是未定义的行为如果我在scanf上输入了两个以上的字母,就会出现分段错误,为什么会发生这种情况?
因为内存只分配给一个字节。
请参见char c
并用指定“a”
。它等于'a'
和'\0'
写入一个字节的内存位置
如果
scanf()
使用此内存读取多个字节,那么这只是未定义的行为如果我在scanf上输入了两个以上的字母,就会出现分段错误,为什么会发生这种情况?
因为内存只分配给一个字节。
请参见char c
并用指定“a”
。它等于'a'
和'\0'
写入一个字节的内存位置
如果
scanf()
使用此内存读取多个字节,那么这只是未定义的行为如果我在scanf上输入了两个以上的字母,就会出现分段错误,为什么会发生这种情况?
因为内存只分配给一个字节。
请参见char c
并用指定“a”
。它等于'a'
和'\0'
写入一个字节的内存位置
如果
scanf()
事实上,字符串基本上是一种约定:C字符串是一个字符数组,其最后一个元素是零字符'\0'
那么宣布
const char s[] = "abc";
完全一样
const char s[] = {'a','b','c','\0'};
特别是,sizeof(s)
在这两种情况下都是4(3+1)(sizeof(“abc”)
)
标准C库包含许多函数(如or…),它们遵循和/或假定字符串是以零结尾的char
-s数组的约定
更好的代码应该是:
char buf[16]="a",*pc= buf;
printf("Enter a string:"); fflush(NULL);
scanf("%15s",pc);
printf("your first char is: %c",buf[0]);
printf("your string is: %s",pc);
一些评论:害怕。读取字符串时,请始终为所读取的字符串指定一个绑定,或者使用一个类似于堆中字符串的函数。当心(使用像……这样的工具)
计算字符串时,还要注意最大大小。请参阅(避免sprintf
)
通常,您采用返回字符串并在堆中动态分配的约定。如果您的系统提供,您可能需要使用或。但是您应该采用这样一种约定,即调用函数(或其他函数,但在您的头脑中定义良好)正在调用字符串
你的程序在语义上可能是错误的,而且有时会出现坏运气。仔细阅读。绝对避免(你的第1、2、3点是可能的)。不幸的是,UB有时可能会“工作”
为了解释一些实际的未定义行为,您必须考虑您的特定实现:编译器、传递给编译器的标志(尤其是优化标志)、操作系统、内核、处理器、月球阶段等等。。。未定义的行为通常是不可复制的(例如,由于……等),请阅读。要解释第1、2、3点的行为,您需要深入了解实现细节;查看编译器生成的汇编代码(gcc-S-fverbose asm
)
我建议您使用所有警告和调试信息编译代码(例如使用gcc-Wall-g
with…),改进代码直到没有警告,并学习如何使用调试器(例如gdb
)一步一步地运行代码。字符串在C中几乎不存在(像“abc”这样的C字符串文字除外)
在某些C源文件中)
事实上,字符串基本上是一种约定:C字符串是一个字符数组,其最后一个元素是零字符'\0'
那么宣布
const char s[] = "abc";
完全一样
const char s[] = {'a','b','c','\0'};
特别是,sizeof(s)
在这两种情况下都是4(3+1)(sizeof(“abc”)
)
标准C库包含许多函数(如or…),它们遵循和/或假定字符串是以零结尾的char
-s数组的约定
更好的代码应该是:
char buf[16]="a",*pc= buf;
printf("Enter a string:"); fflush(NULL);
scanf("%15s",pc);
printf("your first char is: %c",buf[0]);
printf("your string is: %s",pc);
一些评论:害怕