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++中,*
符号在不同的上下文中确实有不同的含义:
-
声明指针变量时,
*
表示“这是一个指针类型”。例如:int x = 10; int* ptr = &x; // 这里的*表示ptr是一个指向int的指针
-
在表达式中使用时,
*
表示“解引用”,即获取指针指向的值。例如: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++指针系统的基础设计。