You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++如何避免char*[]函数传参时隐式转换为char**?

原理说明

C/C++存在数组形参自动退化的语法规则:所有声明为T[]、T[N]形式的函数形参,都会被编译器自动调整为T*类型。你示例中func的形参const char *arr[]实际等价于const char **arr,因此sizeof(arr)拿到的是指针的大小,和main中栈上分配的完整数组类型的sizeof结果不一致。

解决方案

要避免数组退化,核心是不让形参被编译器识别为指针类型,可选用以下两种方案:

方案1:使用数组引用(全C++版本通用)

将形参声明为数组的引用,同时通过模板自动推导数组长度,即可完全避免退化:

#include <iostream>

// 模板参数N自动推导为数组的元素个数
template<size_t N>
void func(const char* (&arr)[N])
{
    std::cout << sizeof(arr) << ", " << sizeof(char*) << std::endl;
}

int main()
{
    const char *arr[] = { "aaa","bbb","ccc" };
    std::cout << sizeof(arr) << ", " << sizeof(char*) << std::endl;
    func(arr);
    return 0;
}

运行输出和你预期一致:

24, 8
24, 8

注意语法中(&arr)的括号不可省略,否则会被解析为「引用的数组」而非「数组的引用」,属于非法声明。

方案2:使用std::span(C++20及以上版本支持)

如果使用较新的C++标准,可以用std::span封装数组信息,它本身携带了数组的起始地址和长度,也不需要模板推导:

#include <iostream>
#include <span>

void func(std::span<const char*> arr)
{
    // size_bytes()返回数组所有元素的总字节数,等价于原数组的sizeof结果
    std::cout << arr.size_bytes() << ", " << sizeof(char*) << std::endl;
}

int main()
{
    const char *arr[] = { "aaa","bbb","ccc" };
    std::cout << sizeof(arr) << ", " << sizeof(char*) << std::endl;
    func(arr);
    return 0;
}

运行结果同样符合预期。

内容的提问来源于stack exchange,提问作者folibis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:57:03