首先要明确的一点,无论是const char *s还是char * const s,这里的s都是指针。
我对这两种声明的理解方式是:看const右边接的是什么,则const修饰的就是什么。
const char *s中,可以把const右边分成char和(*s)两个部分看,显然char和(*s)在代码里指的都是字符,所以const char *s指的是s指向的字符(串)是常量,不能修改,而s指针本身是可以修改的。
char * const s中,const右边只有一个s,显然在代码中s指的是指针,所以char * const s指的是s指针本身是常量,不能修改,而其指向的字符串可以修改。
除此之外,还特地就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.
测试代码如下:
/*************************************************************************
> File Name: test.c
> Author: Julian Wang
> Mail: 13508417@qq.com
> Created Time: Wed 10 Jun 2015 06:20:06 PM CST
************************************************************************/
#include<stdio.h>
#include<stdio.h>
int main(){
const char *s = "hello";
printf("%s\n", s);
s++;
++s;
/*waring*/
char *p = s;
/*compile error*/
// *s = 'c';
/*warning,core dump*/
// *p = 'c';
/*warning,core dump*/
// snprintf(s , 3 , "%d", 11);
/*warning,core dumped*/
// snprintf(p , 3 , "%d", 11);
printf("%s\n", s);
/*warning*/
s = (char *)malloc(1000 * sizeof(char));
/*compile error*/
// *s = 'a';
/*warning,but it works!*/
snprintf(s , 10 , "%d", 12345);
printf("%s\n", s);
return 0;
}
从程序的编译和运行结果可以看出。
(1)对于(*s)=‘a’;这样直接通过指针s对字符串赋值的语句,则无论如何编译器都会报错。
(2)对于const char *s = "hello";指针s初始化的那部分内存区域,也即本例中的“hello”,不论以何种方式对其进行修改(包括使用一般的指针p,snprint函数),可以编译通过,但运行时都会报段错误——Segmentation fault (core dumped)。
(3)如果让s指向malloc出的一块新的内存区域,并且用snprintf函数对s指向的这片区域进行赋值操作,虽然编译会报warning,但是确实可以完成赋值。
故我的答案为ACD。