[C++] 为什么const char**形参不能接收char**类型的实参?

本文探讨了在C++中,const char**形参为何不能接受char**类型的实参。根据C++标准,赋值操作必须满足两操作数类型相容且左侧指针具有右侧的所有限定符。const char**和char**之间的转换不满足这一条件,导致赋值错误。分析了const在指针和引用参数中的作用,以及const形参的优势,包括保护实参不被意外修改和在某些情况下创建临时变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们知道,const存在的意义之一,就是用来对指针或引用类型的形参进行限定,从而达到防止修改实参的作用(因为只有指针和引用类型非按值传递)。使用const指针或引用形参的理由有如下几条:

  • 1.const形参可以接受非const实参,而非const形参只能接受非const实参;
    如:
void sum(const int*,int*);
int main()
{
        int i = 1,j = 3;
        sum(&i,&j);//OK,第一个参数const int*可以接受int*类型数据
        return 0;
}
void sum(const int* a,int* b)
{
        cout << "sum: " << (*a + *b) << endl;
}

  • 2.使用const形参可以避免无意识的修改实参,如上例中形参a为const int*类型,不能修改a的值;
  • 3.如果形参为引用类型,使用const形参可以在必要时生成临时变量,包括以下两种场景:
  • 3.1.实参类型正确,但非左值;
  • 3.2.实参类型不正确,但可以转化为正确的类型;
    如:
void sum(const int& a,int& b);

int main()
{
        double a = 3.45;
        int b = 4;
        sum(a,b); //OK,实参类型不正确(double),但由于const的存在,会生成一个临时变量,然后让a指向这个变量
        //sum(b,a);//BAD,int&形参不会接受double实参
        sum(5,b);//OK,5非左值,但const int&可以接受
        //sum(b,5);//BAD,5非左值,int&不会接受
        return 0;
}

因此,const 修饰的指针类型可以接受它的非const形式,如const int*类型形参可以接受int*类型实参,const char*可以接受char*类型实参,const float*类型形参可以接受float*类型实参,…

那么,const char **类型形参可不可以接受char** 类型实参呢?

我们先试一下:

#include <iostream>

using namespace std;

void print(const char** pch);

int main()
{

        char* name = new char[20];
        char ch;
        cout << "please enter a name:" << endl;

        cin.getline(name,20);
        print(&name);
        return 0;
}
void print(const char** pch)
{
        cout << "pch:" << *pch << endl;
}

编译时,发现出错:

$ g++ test_const.cpp -o tc
test_const.cpp: In function ‘int main()’:
test_const.cpp:17:15: error: invalid conversion from ‘char**’ to ‘const char**’ [-fpermissive]
         print(&name);
               ^~~~~
test_const.cpp:7:6: note:   initializing argument 1 of ‘void print(const char**)’
 void print(const char** pch);
      ^~~~~

很显然,const char**类型形参是不接受char**类型实参的,这是为什么呢?

在C标准中规定,对于赋值操作,必须满足如下的条件:

  • 1.两操作数都是指向有限定符或无限定符的相容类型的指针;
  • 2.左边指针必须具有右边指针所指向类型的全部限定符;

所以,对于const char*char*来说:

const char* cch;
char* ch;
cch = ch;

左操作数是一个指向有const修饰的char类型的指针;
右操作数是一个指向char类型的指针;
char 和char 是相容的(同一类型),且左操作数具有右操作数的全部限定符,还多了一个const。因此,是允许这样操作的。

对于const char**char**来说:

const char** cch;
char** ch;
cch = ch;

左操作数是一个指向有const修饰的char的指针的指针;
右操作数是一个指向没有const修饰的char的指针的指针;

首先,两操作数都是没有限定符的指针类型,分别指向const char *char *,因此,它们的类型不同,因此,不满足第一个条件,从而不能完成赋值。

同样地,我们也可以知道,const float**不接受float**const int**不接受int *

参考资料:《C专家编程》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值