#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 **为何不兼容的更多相关文章

  1. 【转】深入理解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 ...

  2. 【C++】int、const char*、char*、char、string之间的转换

    #include "stdafx.h" #include<string> #include<vector> #include<iostream> ...

  3. 字符串复制char *strcpy(char* dest, const char *src);

    ⒈strcpy的实现代码 char * strcpy(char * strDest,const char * strSrc) { if ((NULL==strDest) || (NULL==strSr ...

  4. [转载] 已知strcpy的函数原型:char *strcpy(char *strDest, const char *strSrc),编写函数 strcpy(C++版)

    已知strcpy的函数原型:char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串,strSrc 是源字符串.不调用C++/C ...

  5. const char*、char*、char* const、char[]、string的区别

    1.const char* p: p is a pointer to const char(char const* p 一样)   意思就是不能通过p指针来修改p指向的内容(但是内容可以修改). 2. ...

  6. C 和 OC 字符串转换 NSString 和 char * 转换 const char* 与 char *

    #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { char *s = "He ...

  7. 无法从“const char *”转换为“char *”

    写了如下的一段代码: const char *str; char *p=str; 提示错误: const char* 不能用于初始化char *类型的实体.这是为什么?我想应该是const char ...

  8. string、const char*、 char* 、char[]相互转换

    转化总结如下: 目标格式 源格式 string const char* char* char[] string NULL const char*=string.c_str(); const char* ...

  9. string、const char*、 char* 、char[]相互转换(待整理)

    string.const char*. char* .char[]相互转换(全) https://blog.csdn.net/rongrongyaofeiqi/article/details/5244 ...

随机推荐

  1. 递归和for循环

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #http://www.cnblogs.com/BeginMan/p/3223356.html #递归2 '非 ...

  2. .NET Remoting三种信道Http,Tcp,IPC和Web Service的访问速度比较(转)

    Remoting和Web Service是.net中的重要技术,都可用来实现分布式系统开发,如果是不同的平台就只能选择Web Service,但如果是同一平台,就都可以选择了.到底选择那种,当然还有访 ...

  3. Java中初级数值类型的大小, volatile和包装类wrapped type的比较

    Java中的初级数值类型 Java是静态类型语言, 所有的变量必须先声明再使用. 其初级类型一共8种: boolean: 数据只包含1bit信息, 但是占空间为8-bit, 默认值为false byt ...

  4. spring thymeleaf 自定义标签

    概述 thymeleaf2.1.5自定义标签及自定义属性案例,类似于JSP中的自定义JSTL标签 详细 代码下载:http://www.demodashi.com/demo/10495.html 一. ...

  5. POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)

    Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 56150   Accepted: 19398 Desc ...

  6. Ubuntu14.04 mount远程服务器上的目录

    备忘用. 一,远程服务器设置: 1,在/etc/exports中添加如下配置: /home/xxx *(insecure,rw,sync,no_root_squash,anonuid=123,anon ...

  7. iOS GCD中级篇 - dispatch_group的理解及使用

    上一篇GCD基础篇,以及同步.异步,并发.并行几个概率的理解 关于dispatch_group的概念以及几种场景下的使用 1.关于dispatch_group 把一组任务提交到队列中,这些队列可以不相 ...

  8. Android开发学习之Activity的简介

    1.Activity的概念介绍 Activity是Android组件中最基本也是最常用的一种组件,在一个Android应用中,一个Activity通常就是一个单独的屏幕.每一个Activity都被实现 ...

  9. Jquery与mootools对比

    换了新公司以后就很少使用原生Js来实现界面交互了,而是更多的依赖Jquery. 1.Jquery优点: 良好的一致性$().().xxxxx与强大的DOM api组件可以让一个js菜鸟一周之类立马开发 ...

  10. regular expression 练习

    练习有一个文件,文件名为output_1981.10.21.txt .下面使用Python: 读取文件名中的日期时间信息,并找出这一天是周几.将文件改名为output_YYYY-MM-DD-W.txt ...