既然你正在读考试,我会充实我的评论,以解释实际发生的事情:
char *str = "abc";
str
是存储在堆栈中的指针.它被初始化为指向文字字符串"abc"
.该文字字符串将存储在已编译可执行文件的数据部分中,并在加载程序时加载到内存中.该部分内存是只读的,因此当您尝试修改str指向的数据时,会出现访问冲突.
char* str = malloc(sizeof(char) * 4); strcpy(str, "abc");
这里,str是与第一个例子相同的堆栈指针.这次,它被初始化为指向堆上的4个字符的内存块,您可以读取和写入.起初,该内存块未初始化,可以包含任何内容.strcpy读取存储"abc"的只读存储器块,并将其复制到str指向的读写存储器块中.请注意,设置str[3] = '\0'
是多余的,因为strcpy已经这样做了.
顺便说一下,如果您在visual studio中工作,请使用strcpy_s来确保在复制的字符串超出预期时不覆盖缓冲区.
char str[] = "abc";
现在str
是一个在堆栈上分配的数组.编译器将使其大小完全符合用于初始化它的字符串文字(包括NULL终止符).堆栈存储器是读写的,因此您可以根据需要修改阵列中的值.
char str[4] = "abc";
这与前一版本实际上是一样的,只是告诉编译器你知道的数据应该比数组的长度更好.如果更改字符串而不是数组大小,则可能会遇到麻烦.
既然你正在读考试,我会充实我的评论,以解释实际发生的事情:
char *str = "abc";
str
是存储在堆栈中的指针.它被初始化为指向文字字符串"abc"
.该文字字符串将存储在已编译可执行文件的数据部分中,并在加载程序时加载到内存中.该部分内存是只读的,因此当您尝试修改str指向的数据时,会出现访问冲突.
char* str = malloc(sizeof(char) * 4); strcpy(str, "abc");
这里,str是与第一个例子相同的堆栈指针.这次,它被初始化为指向堆上的4个字符的内存块,您可以读取和写入.起初,该内存块未初始化,可以包含任何内容.strcpy读取存储"abc"的只读存储器块,并将其复制到str指向的读写存储器块中.请注意,设置str[3] = '\0'
是多余的,因为strcpy已经这样做了.
顺便说一下,如果您在visual studio中工作,请使用strcpy_s来确保在复制的字符串超出预期时不覆盖缓冲区.
char str[] = "abc";
现在str
是一个在堆栈上分配的数组.编译器将使其大小完全符合用于初始化它的字符串文字(包括NULL终止符).堆栈存储器是读写的,因此您可以根据需要修改阵列中的值.
char str[4] = "abc";
这与前一版本实际上是一样的,只是告诉编译器你知道的数据应该比数组的长度更好.如果更改字符串而不是数组大小,则可能会遇到麻烦.
最简单的解决方案是将声明更改str
为
char str[] = "abc";
这使得str
一个char数组被初始化为字符串"abc".目前,您已将str
初始化为指针的指针指向由字符串文字描述的字符串.有一个关键的区别:字符串文字是只读的,以便编译器在存储它们的位置具有最大的灵活性; 修改它们是UB.但是char数组是可变的,因此可以修改它们.
PS.main()
返回一个int
.
因为这是家庭作业我会给出建议,但我不会发布完整的解决方案.
我猜你在str [0] ='b'上遇到了访问冲突?这是因为"abc"是一个字符串文字.
在调用reverse之前复制字符串str points,或者反向调用以分配缓冲区并将反向字符串放入其中.
请记住,您必须释放所分配的所有内存.
勋爵,勋爵.对于那些建议实际进行交换的人,请仔细阅读问题; 没有什么比重申一个已经非常明确的问题更糟的了.无论用于实现交换的方法(临时交换,xor3交换等),这个人似乎都非常熟悉函数的基本内容和相当基本的内在函数.
但是,如前所述,编译器/链接器通常将所有字符串文字放在目标可执行文件的"const数据段"中,随后在适当的"加载/执行"调用期间将其与不可写的MMU描述符相关联.随后通过此描述符发出的所有CPU写周期都会被MMU的异常机制自动捕获,从而产生强制性的"段错误"或特定于平台的等价物.当然,不言而喻,较旧的非MMU平台不会出现这种行为.
虽然这有效地获得了对源语言的"常量/文字"习惯的运行时支持,但是一些平台在历史上促进了显式编译时段的覆盖.然而,这种支持水平逐渐减弱,有利于更严格/更强大的抽象层,从而使许多明显且通常有用的优化变得难以理解.随着时间和磨损逐渐老化"MC/ASM"理念,在一个过于热切的"微软"一代之前,程序员不再被认为具有足够的知识或负责任以做出这种决定.代替我作为项目负责人目睹的许多人为的,而不是创造性的实施,这绝不是一件坏事.
尽管这篇文章正在迅速演变成一个偏离主题的违规行为,但我仍然感到有些自上而下的相关问题在我们的行业中慢慢流行起来.作为一个初出茅庐的C程序员 - 一种最初旨在补充低级开发的语言 - 我的建议是采用自下而上的方法,并通过一些课外汇编语言开发来增强你的学习.由于算法实现可能构成您作为应用工程师的主要关注点,因此重要的是要记住当代CPU设计在过去30年中经历了均匀演变; 今天的超快Intel CPU只不过是我在地球还很年轻的时候编程的4/8位双极处理器的超标量CMOS改进.
与流行的看法相反,汇编语言编程相对容易学习,并且在尝试协调高级构造与有问题或深奥的行为时绝对必要.一旦你考虑了无数个小时的实验,调试,网络搜索和论坛垃圾邮件,毫无疑问,自下而上的方法肯定是阻力最小的途径.
祝你学习顺利.