阅读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 ...
随机推荐
- Q1:Valid Parentheses
Question: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine i ...
- 网站Web性能测试:ApacheBench,Webbench,http_load使用教程
网站Web性能测试:ApacheBench,Webbench,http_load使用教程 Web服务器 欲思 10个月前 (05-25) 0评论 一个网站或者博客到底能够承受多大的用户访问量经常是 ...
- elasticsearch5.4体验
Elasticsearch是基于Lucene分布式.实时查询的搜索分析引擎.我目前应用在日志集中化处理上... 01.下载elasticsearch5.4 https://www.elasti ...
- maven依赖导致包重复加载及冲突
maven中配置 pom时,有时配置添加一个 jar却会自动导入多个 jar包,往往这些自动导入的 jar包会与我们项目中已存在的 jar包重复,从而导致冲突.由于这些 jar包不是我们自己配置的,所 ...
- 深入理解SpringBoot配置
一.application.properties的位置 1.当前目录的 "/config"的子目录下 2.当前目录下 3.classpath根目录的"/config&qu ...
- 利用pushState开发无刷页面切换(转)
相关文档:https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulatingthebrowser_history 实现目标 ...
- Google map API V3
本文主要总结Google map API V3使用中最简单也是最常见的一些操作以及相关概念,如果需要更加详细的信息,请直接阅读Google提供的关于map的文档. google map api v3文 ...
- Android中可以做的两件坏事——破解锁屏密码和获取Wifi密码
来源:http://blog.csdn.net/jiangwei0910410003/article/details/41800409 今天咋们来看一下我在现实中遇到的两个问题和解决方案 问题一:忘记 ...
- Accounting_会计基础知识
作为企业的财务人员,必须拥有一些技能和财务方面的知识,本文就所讲述的是财务岗位必须掌握的知识总结,仅供参考. 1.账面价值.账面余额和账面净值 账面价值是指某科目(通常是资产类科目)的账面余额减去相关 ...
- Unix环境高级编程(五)进程环境
本章主要介绍了Unix进程环境,包含main函数是如何被调用的,命令行参数如何传递,存储方式布局,分配存储空间,环境变量,进程终止方法,全局跳转longjmp和setjmp函数及进程的资源限制. ma ...