关于char**与const char**

简介:

   const char**a;
char *b[] = {0};
a = b;

对于上面这段代码,GCC编译器会在"a=b"一句上报告警告,提示不匹配的指针类型。

感觉非常奇怪,非const向const赋值,居然都报错?在网络上搜索相关问题,得到的信息大致如下:

在ANSI C标准中有这么一句话:

什么是合法的赋值形式呢?两个操作数都是指向有限定符或者无限定符的相容的指针,左边指针所指向的类型必须具有右边指针指向类型的全部限定符。

于是,对于语句:

char *test1;
const char *test2;
test2 = test1;

我们来看,左操作数是一个指向有const限定符的char指针,右操作数指向没有限定符的char指针,而char和char本身是相容的,左操作数指向的类型也具有右操作数指向类型的限定符(这里是空),因此,可以赋值。

对于前面的语句"a=b",两者都是指向指针的指针,后者指向的是char *,前者指向的是const char*。 const char*并不是一个有限定符的类型,它是"指向有const限定的char类型的指针"。
所以, const char **和 char **都是没有限定符的指针,但他们指向的类型不一样,前者指向 const char *,后者指向 char *。因此他们并不相容。

看了上面这些东西,实在太绕,抛出一堆概念和规则,并且没有“为什么”。用规则本身来解释问题,而很少谈论为什么要有这样的规则。

那么,这什么要有这样的规则呢?

举个例子,看看如果前面的语句"a=b"没有问题的话,会有什么问题。

const char* s = "abc"; /* s指向常量字符串 */
char* p0 = 0;
char** p1 = &p0; /* p1指向p0 */
const char** p2 = p1; /* p2也指向p0(char**赋值给const char**,先假设这样是成立的) */
*p2 = s; /* p2指向的p0与s具有相同指向,非const指针p0指向了常量字符串 */
*p0 = 'A'; /* 通过p0修改常量字符串,结果一般情况下是程序崩溃 */

这就是规定产生的原因……


目录
相关文章
|
9月前
|
C++
C++ --- error C2664: “LoadLibraryW”: 不能将参数 1 从“const char *”转换为“LPCWSTR”
C++ --- error C2664: “LoadLibraryW”: 不能将参数 1 从“const char *”转换为“LPCWSTR”
184 0
|
1月前
|
C++
无法将参数1从“const char [6]”转换为“char *”的解决方法
无法将参数1从“const char [6]”转换为“char *”的解决方法
|
10月前
|
关系型数据库 MySQL C++
类型收窄 error C2397: conversion from ‘const int‘ to ‘char‘ requires a narrowing conversion
类型收窄 error C2397: conversion from ‘const int‘ to ‘char‘ requires a narrowing conversion
114 0
map使用const char*作为key值查找注意事项
map使用const char*作为key值查找注意事项
error C2664: “StrCmpW”: 不能将参数 2 从“const char [12]”转换为“PCWSTR”
error C2664: “StrCmpW”: 不能将参数 2 从“const char [12]”转换为“PCWSTR”
95 0
|
C++
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
129 0
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决
vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决
628 0
vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决
|
C++
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”
404 0
VS:无法将“char *”转换为“const wchar_t *”/不能将参数从“const char []”转换为“const wchar_t *”