阅读ANSI C,寻找乐趣和裨益——const char **与char **为何不兼容
#include<stdio.h>
void foo1(const char**p)
{ }
void foo2(const char*p)
{ }
int main(int argc,char **argv)
{
foo1(argv);
char *p;
foo2(p);
return ;
}
为什么第一个调用有警告,第二个没有?

要解释这个问题,真是破费心机。
ANSI C 6.3.16.1节对于简单赋值这样描述:
两个操作数都是指向有限定符或者无限定符的相容类型的指针,左边指针所指向的类型必须具有右边指针所指向类型的全部限定符。
(在顶层const时不再适用!)
函数调用时,实参传递给形参,相当于赋值操作。
当第一次阅读到这个问题时,我是没有理解透彻的,《c专家编程》对这里的描述也是模棱两可,直到学习了c++之后,才算明白。
先看《c专家编程》上对这里的描述:

正是因为看了这本书,在学习c++的时候,刚开始一直很疑惑,为什么c++这里和c语言不一样,到后来,我明白了,是《c专家编程》这里讲解还是不够。对于上面的描述,我们做如下测试:
char *cp;
char * const p="abc";
cp=p;
这样的赋值不会有警告,是不是和《c专家编程》描述有出入呢?在c++的学习中,我知道了,顶层const在赋值时会被忽略,在C语言中,也是同样的道理。所以,多多阅读书籍才能更好的提高。回到之前的话题,char *赋值给const char *不会有任何警告,证明它们是相容的,那为什么char ** 赋值给const char **就会有警告呢?
ANSI C 并没有对上述情况加以解释说明,但是在6.1.2.5节中这样讲述:
const float * 类型并不是一个有限定符的类型(在我当初阅读的时候,觉得这里和她上面的举例是矛盾的,这里没有限定符,那上面那个例子不就是说自身有一个const限定符吗?后来我发现,上面所说的限定符仅仅是指const,也并没有说是指针的呀!)---它的类型是“指向一个具有const限定符的float类型的指针”,也就是说const限定符修饰的是指针所指向的类型,而不是指针本身。
类似地,const char **也是一个没有限定符修饰的指针类型(注意这里的描述是对于指针类型的)。它的类型是“指向有const限定符的char类型的指针的指针”。由于它和char **一样都是没有限定符的指针类型,但它们指向的类型不一样,一个指向const char * ,一个指向char * 。因此它们是不相容的。虽然char *可以赋值给const cahr *,但是相容性不能传递,那么const char **与char **还是不相容。
阅读ANSI C,寻找乐趣和裨益——const char **与char **为何不兼容的更多相关文章
- 【转】深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p
一.可能的组合: (1)const char*p (2)char const*p (3)char *const p(4)const char **p (5)char const**p (6)char ...
- 【C++】int、const char*、char*、char、string之间的转换
#include "stdafx.h" #include<string> #include<vector> #include<iostream> ...
- 字符串复制char *strcpy(char* dest, const char *src);
⒈strcpy的实现代码 char * strcpy(char * strDest,const char * strSrc) { if ((NULL==strDest) || (NULL==strSr ...
- [转载] 已知strcpy的函数原型:char *strcpy(char *strDest, const char *strSrc),编写函数 strcpy(C++版)
已知strcpy的函数原型:char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串,strSrc 是源字符串.不调用C++/C ...
- const char*、char*、char* const、char[]、string的区别
1.const char* p: p is a pointer to const char(char const* p 一样) 意思就是不能通过p指针来修改p指向的内容(但是内容可以修改). 2. ...
- C 和 OC 字符串转换 NSString 和 char * 转换 const char* 与 char *
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { char *s = "He ...
- 无法从“const char *”转换为“char *”
写了如下的一段代码: const char *str; char *p=str; 提示错误: const char* 不能用于初始化char *类型的实体.这是为什么?我想应该是const char ...
- string、const char*、 char* 、char[]相互转换
转化总结如下: 目标格式 源格式 string const char* char* char[] string NULL const char*=string.c_str(); const char* ...
- string、const char*、 char* 、char[]相互转换(待整理)
string.const char*. char* .char[]相互转换(全) https://blog.csdn.net/rongrongyaofeiqi/article/details/5244 ...
随机推荐
- 所有标准API
序号 系统版本 模块 应用场景 类型 API/接口 参数规格 样例代码 备注 登记者 登记时间 关键字 1 12.1.3 AP 付款核销 API ap_pay_invoice_pkg.ap_pay_i ...
- CEF 各个版本适应的平台参考表
This Wiki page provides information about CEF branches and instructions for downloading, building an ...
- Openstack网络相关概念比较复杂,经常使人混淆,本文进行相关说明。
Openstack网络相关概念比较复杂,经常使人混淆,本文进行相关说明. 文中相关术语与缩写 英文 缩写 中文 Virtual Local Area Network VLAN 虚拟局域网 Virtua ...
- oper
package main.java.com.zte.controller.ems; import java.util.HashMap; import java.util.List; import ja ...
- TP3.2批量上传文件(图片),解决同名冲突问题
1.html <form action="{:U('Upload/index')}" enctype="multipart/form-data" meth ...
- JavaScript-实现滚动条
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Java虚拟机学习 - 内存调优 ( 9 )
JVM调优主要是针对内存管理方面的调优,包括控制各个代的大小,GC策略.由于GC开始垃圾回收时会挂起应用线程,严重影响了性能,调优的目是为了尽量降低GC所导致的应用线程暂停时间. 减少Full GC次 ...
- c# 网站生成静态页面
在一些需要经常更新页面数据的网站中,一般访问量不是很大的都直接发布的是带后台代码,每次访问都是有数据库交互的.但是一旦访问量增加了,那么这些服务器开销变成本就要考虑进来了,像一些文章,后台编辑后,文章 ...
- iOS10:CallKit的简单应用
CallKit 这个开发框架,能够让语音或视讯电话的开发者将 UI 界面整合在 iPhone 原生的电话 App 中.将允许开发者将通讯 App 的功能内建在电话 App 的“常用联络资讯”,以及“通 ...
- Ubuntu16.04 安装RabbitMQ
转载https://www.cnblogs.com/hongdada/p/7203589.html 安装RabbitMQ 由于rabbitMq需要erlang语言的支持,在安装rabbitMq之前需要 ...