Suppose running on Linux, which one is the correct output of following code (C)

#include <stdio.h>

void test1(void) {
    char* my_array = "abc";
    my_array[1] = '+';
    printf("my array is %s ", my_array);
}

void test2(void) {
    char my_array[] = "abc";
    my_array[1] = '-';
    printf("my array is %s ", my_array);
}

int main(int argc, char** argv) {
    test2();
    test1();
    return 0;
}

my array is a+b my array is a-b
my array is a-b my array is abc
my array is a-c Segmentation fault(core dump)
my array is a-b my array is a+b
解答:

test1() 中定义了一个 my_array 指针,且该指针指向了 "abc" 字符串常量,当尝试修改字串常量的值时会产生段错误
test2() 中定义了一个 my_array 字符数组,可以正常修改数组中某个元素的值,不会产生错误

两种错误:

A#include <stdio.h>

char* returnStr() {
    char p[] = "hello world!";
    return p;
}

int main() {
    char *str = NULL;
    str = returnStr();
    printf("%s\n", str);
    return 0;
}

选项 A 中 p[] 是定义在函数栈上的局部数组,在函数返回时,这个数组的内存会被释放,导致返回的指针 p 指向的内存不再有效,选项 A 错误

D
#include <stdio.h>
#include <stdlib.h>

char* returnStr() {
    char* p = (char*)malloc(13*sizeof(char));
    *p = "hello world!";
    return p;
}

int main() {
    char *str = NULL;
    str = returnStr();
    printf("%s\n", str);
    free(str);
    return 0;
}

选项 D 中使用 malloc 动态分配了内存,返回的指针有效,但是 p = "hello world!"; 语法错误,不能将 const char 转换为 char 类型,选项 D 错误

在C和C++中,*符号在不同的上下文中确实有不同的含义:

  1. 声明指针变量时*表示“这是一个指针类型”。例如:

    int x = 10;
    int* ptr = &x;  // 这里的*表示ptr是一个指向int的指针
    
  2. 在表达式中使用时*表示“解引用”,即获取指针指向的值。例如:

    int value = *ptr;  // 这里的*是解引用操作,value会得到10
    

需要注意的是,这两种用法完全不同:

  • 声明时的*:是类型的一部分,表示这是一个指针变量
  • 表达式中的*:是一个运算符,用于访问指针指向的内存位置

举个完整的例子:

#include <iostream>
int main() {
    int x = 10;         // 普通整数变量
    int* ptr = &x;      // 声明指针ptr,指向x的地址
    *ptr = 20;          // 解引用ptr,修改它指向的值(即x的值)
    std::cout << x;     // 输出20
    return 0;
}

这种双重语义刚开始可能会让人困惑,但它是C/C++指针系统的基础设计。