面试题答案
一键面试- 实参传递的限制:
void func1(const char *p)
:- 实参可以是
const char *
类型,也可以是char *
类型。因为char *
类型可以隐式转换为const char *
类型。这是因为const
修饰符表示指针所指向的数据是常量,而从非const
到const
的转换是安全的,不会破坏数据的只读性。
- 实参可以是
void func2(char * const p)
:- 实参必须是
char *
类型,不能是const char *
类型。因为char * const
表示指针本身是常量,不能改变指针的指向,但可以修改指针所指向的数据。而const char *
类型表示所指向的数据是常量,不能被修改,无法满足func2
中对指针所指向数据可修改的要求。
- 实参必须是
- 对函数内部操作字符串的影响:
void func1(const char *p)
:- 在函数内部,不能通过指针
p
修改其所指向的字符串内容。例如,不能进行*p = 'a';
这样的操作,否则会导致编译错误。这有助于保护传递进来的字符串数据不被函数意外修改,适用于函数只需要读取字符串的场景。
- 在函数内部,不能通过指针
void func2(char * const p)
:- 在函数内部,可以修改指针
p
所指向的字符串内容,例如*p = 'a';
是合法的。但是,不能修改指针p
本身的指向,例如p++;
这样的操作会导致编译错误。这适用于函数需要修改字符串内容,但又要确保指针始终指向传递进来的起始位置的场景。
- 在函数内部,可以修改指针
- 实现类似功能(打印字符串)时函数实现的不同:
void func1(const char *p)
:- 由于不能修改字符串内容,打印字符串可以直接使用
printf("%s", p);
等类似的标准库函数,因为这些函数只读取字符串。例如:
- 由于不能修改字符串内容,打印字符串可以直接使用
#include <stdio.h>
void func1(const char *p) {
printf("%s\n", p);
}
void func2(char * const p)
:- 虽然也可以使用
printf("%s", p);
来打印字符串,但因为指针所指向的数据可修改,如果在打印之前不小心修改了字符串内容,可能会导致打印结果不符合预期。例如:
- 虽然也可以使用
#include <stdio.h>
void func2(char * const p) {
// 这里如果误操作修改了p指向的内容
// 可能影响打印结果,一般来说实现打印功能
// 和func1没有本质区别,只是多了误修改的风险
printf("%s\n", p);
}
在实现打印功能上,二者核心代码类似,但func2
存在误修改字符串的潜在风险,而func1
由于对字符串的只读限制,更加安全。