我有一个使用字符串初始化字符指针的例子.我得到了一些行为在一种情况下有效,但在另一种情况下无效.我将用3个代码示例来解释:

first代码是这样的:

#include <stdio.h>

int main(void) {
    char* f = "test";
    printf("%s", f);//prints "test"
}

这段代码工作正常,包含它的目的是表明我们可以用字符串初始化一个字符指针并将其打印出来.

second代码是这样的:

#include <stdio.h>


void strcpy(char* dst, char* src) {
    int i = 0;
    do {
        *(dst + i) = *(src + i);

    } while (*(src + (i++)));
}

int main(void) {
    char first[] = "test2";
    char second[] = "test3";

    strcpy(second, first);

    printf("%s", second); //prints "test2"
}

这个代码也很好用.包含它的关键是因为下一行代码将无法工作.

third代码是这样的:

#include <stdio.h>


void strcpy(char* dst, char* src) {
    int i = 0;
    do {
        *(dst + i) = *(src + i);

    } while (*(src + (i++)));
}

int main(void) {
    char first[] = "test4";
    char *second = "test5"; //ONLY THIS LINE IS CHANGED

    strcpy(second, first);

    printf("%s", second); //PRINTS NOTHING
}

你知道为什么第三个代码什么都不打印吗?它只是第一个和第二个样本的组合,所以我不明白为什么它不工作?

推荐答案

char *second = "test5";后缀second指向由字符串文字创建的数组的第一个字符.关于字符串文字,C 2018 6.4.5 7说:

.如果程序试图修改这样的数组,则行为是未定义的.

由于程序在调用strcpy(second, first);时试图修改数组,因此程序的行为未被定义.

C实现的一个常见行为是将字符串字面量数组放在内存中,并标记为进程只读,因此试图修改这样的数组会导致内存访问冲突.

优化器还可能导致其他行为最初令程序员感到惊讶,因为优化可能假设没有try 修改字符串文字的数组,因此可能基于该假设来转换程序.

C++相关问答推荐

C:gcc返回多个错误定义,但msvc—不""'

了解一些CLIPS原语数据类型

球体—立方体重叠:无、部分或全部?

字符串令牌化xpath表达式

为什么输出不是从上到下C

是否所有C编译器在将浮点数转换为整型数时都会隐式删除小数?

Win32API Wizzard97 PropSheet_SetWizButton不工作

如何捕捉只有换行符或空格字符缓冲区的边缘大小写

GTK3按钮信号错误

如何使用_newindex数组我总是得到错误的参数

如何在GET_STRING输入后对少数几个特定字符串进行C判断?

在进程之间重定向输出和输入流的问题

使用ld将目标文件链接到C标准库

C语言中奇怪的输出打印数组

如何将两个uint32_t值交织成一个uint64_t?

我可以创建适用于不同endian的 colored颜色 struct 吗?

将 struct 数组写入二进制文件时发生Valgrind错误

当我将偏移量更改为任何非零值时,C中的mmap共享内存出现无效参数错误

在我的函数中实现va_arg的问题

#define X Defined(Y) 是有效的 C/C++ 宏定义吗?