const char*, char const*, char*const使用时的区别

案例1:

#include<iostream>using namespace std;void main(void){// char* a 与 char a[] 的区别char* a = "abcdef";// a为一指针,其值可以改变。现在a指向的是一常量字符串cout << a << endl;a = "ghijkl";// a现在指向另一常量字符串//a[0] = 'z';// a指向的为常量,编译没问题,但运行出现异常cout << a << endl;cout << sizeof(a) << endl; // 4char b[] = "abcdef";// b为数组首地址,为一常量,其值不可改变。所指内容不是常量字符串cout << b << endl;//b = "ghijkl";// 编译无法通过,b为常量,无法为其指定其它值b[0] = 'z';cout << b << endl;cout << sizeof(b) << endl; // 7// ——————————————————————————// const char* a 与 char* const a 区别char c[] = "abcd";char d[] = "efgh";const char* pC = c;//pC[0] = 'z';// 编译出错,pC为指向常量的指针,做不能修改指针指向的内容cout << pC << endl;pC = d;cout << pC << endl;// pC指向的内容不能改,但可以修改指向char e[] = "abcd";char f[] = "efgh";char* const pE = e;//pE = f;// pE为常量指针,不能改变其指向pE[0] = 'z';// pE为常量指针,虽然不能改变其指向,但可以修改指向内容cout << pE << endl;}// 总结:(1) char* a这种形式:a为指针,可以改变其指向,//其所指向的字符串为常量,不能修改其指向的内容。//(2) char a[]这种形式,a为数组名,为常量,不能再//指向其它字符串,但其指向的内容不是常量字符串,//故可以改变。//(1) const char* a 为指向常量的指针,所指内容为常量,//不能修改,但可以改变其指向,这种形式还与//char const * a等价。//(2) char* const a 为指针常量,不能改变其指向,但可//以修改其指向的内容。//(3) const char* const a 为指向常量的常指针,即不能//改变其指向,也不能改变其指向的内容

const char*, char const*, char*const的区别问题:

几乎是C++面试中每次都会有的题目。

事实上这个概念谁都有,只是三种声明方式非常相似很容易记混。Bjarne在他的The C++ Programming Language里面给出过一个助记的方法:把一个声明从右向左读。char * const cp; ( * 读成 pointer to ) cp is a const pointer to charconst char * p; p is a pointer to const char;char const * p;同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。C++标准规定,const关键字放在类型或变量名之前等价的。

const int n=5; //same as belowint const m=10;

const int *p; //same as below const (int) * pint const *q; // (int) const *p

看一道以前Google的笔试题:题目:const char *p="hello"; foo(&p); //函数foo(const char **pp)下面说法正确的是[]A.函数foo()不能改变p指向的字符串内容B.函数foo()不能使指针p指向malloc生成的地址C.函数foo()可以使p指向新的字符串常量D.函数foo()可以把p赋值为 NULL.至于这道题的答案是众说纷纭。针对上面这道题,我们可以用下面的程序测试:

#include <stdio.h>#include <stdlib.h>#include <stdio.h>void foo(const char **pp){*pp=NULL;*pp="Hello world!";*pp = (char *) malloc(10);snprintf(*pp, 10, "hi google!");(*pp)[1] = 'x'; // runtime error}int main(){const char *p="hello";printf("before foo %s/n",p);foo(&p);printf("after foo %s/n",p);p[1] = 'x'; //runtime errorreturn;}结论如下:在foo函数中,可以使main函数中p指向的新的字符串常量。在foo函数中,可以使main函数中的p指向NULL。在foo函数中,可以使main函数中的p指向由malloc生成的内存块,并可以在main中用free释放,但是会有警告。但是注意,即使在foo中让p指向了由malloc生成的内存块,但是仍旧不能用p[1]=’x’;这样的语句改变p指向的内容。在foo中,不能用(*pp)[1]=’x’;这样的语句改变p的内容。所以,感觉gcc只是根据const的字面的意思对其作了限制,即对于const char*p这样的指针,不管后来p实际指向malloc的内存或者常量的内存,均不能用p[1]=’x’这样的语句改变其内容。但是很奇怪,在foo里面,对p指向malloc的内存后,可以用snprintf之类的函数修改其内容。

深入理解

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 *const *p (7)char **const p 当然还有在(5)、(6)、(7)中再插入一个const的若干情况,不过分析了以上7中,其他的就可类推了!二、理解助记法宝: 1。关键看const 修饰谁。 2。由于没有const *的运算,若出现const*的形式,则const实际上是修饰前面的。 比如:char const*p,由于没有const*运算,则const实际上是修饰前面的char,因此char const*p等价于const char*p。也就是说上面7种情况中,(1)和(2)等价。 同理,(4)和(5)等价。在(6)中,由于没有const*运算,const实际上修饰的是前面的char*,但不能在定义时转换写成 const(char *)*p,因为在定义是"()"是表示函数。三、深入理解7种组合 (0)程序:在执行时为其开辟的空间皆在内存(RAM)中,而RAM里的内存单元是可读可写 的;指针只是用来指定或定位要操作的数据的工具,只是用来读写RAM里内存单元的工作指针。若对指针不加任何限定,程序中一个指针可以指向RAM中的任意位置(除了系统敏感区,如操作系统内核所在区域)并对其指向的内存单元进行读和写操作(由RAM的可读可写属性决定);RAM里内存单元的可读可写属性不会因为对工作指针的限定而变化(见下面的第4点),而所有对指针的各种const限定说白了只是对该指针的读写权限 (包括读写位置)进行了限定 。 (1)char *p:p是一个工作指针,可以用来对任意位置 (非系统敏感区域)进 行读操作和写操作 ,一次读写一个字节(char占一个字节)。 (2)const char*p或者char const *p(因为没有const*p运算,因此const修饰的还是前面的char):可以对任意位置(非系统敏感区域)进行“只读” 操作。(“只读”是相对于char *p来说所限定的内容) (3)char *const p(const 修饰的是p):只能对“某个固定的位置” 进 行读写操作,并且在定义p时就必须初始化(因为在后面不能执行“p=..”的操作,因此就不能在后面初始化,因此只能在定义时初始化)。(“某个固定的位 置”是相对于char *p来说所限定的内容) 可以总结以上3点为:char *p中的指针p通常是”万能”的工作指针 ,而(2)和(3)只是在(1)的基础上加了些特定的限制 ,这些限制在程序中并不是必须的,只是为了防止程序员的粗心大意而产生事与愿违的错 误。另外,要明白“每块内存空间都可有名字;每块内存空间内容皆可变(除非有所限) ” 。都可以…孔子的,老子的. 孙子的…都可以

const char*, char const*, char*const使用时的区别

相关文章:

你感兴趣的文章:

标签云: