C语言const char和char有什么区别,指针变量date有点懵,请帮我讲解一下?
发布网友
发布时间:2022-11-10 15:47
我来回答
共4个回答
热心网友
时间:2023-11-27 16:23
有一个判断 C 语言的声明式的技巧,那就是“从右往左读”,C++ 创始人 Bjarne Stroustrup 在其著作《The C++ Programming Language》中推荐了这种方法,《C 专家编程》中也提及了这种技巧。相比于其他的“根据 const 与其他词素的距离判断”、“根据 const 的前后关系判断”等等,个人认为这是最人性化的方法。从某种意义上来说,C 编译器在进行词法分析的时候巧合地运用了这种范式来进行语义转换,这一点在 Backus(上下文无关法) 范式中也有体现。
具体的方法是:
const char * A:A 是一个指针,指向 const char。
char const * A:A 是一个指针,指向 const char。
char * const A:A 是一个 const 指针,指向 char。
const char * const A:A 是一个 const 指针,指向 const char。
const char const * const A:A 是一个 const 指针,指向 const char,后面两个(从右往左读)有一个是多余的。
看到给出的示例:
const char* date;
这是一个指向 const char 的指针,这说明指针本身可变,但是其指向的 char 是不可变的,而 date = "new string" 中常量字符串其实是一个指针,因为指针可变,所以这里没问题。
但是如果写成 char* const date,那么这就是一个不可变的指针,但是其指向的 char 是可变的,这时候写 date = "new string" 就会报错:
error: cannot assign to variable 'date' with const-qualified type 'char *const'
但是如果尝试如下语句:
char* const date = "Hello, world!";
date[0] = 'H';
编译能通过,但是运行时会出错:
zsh: bus error
总线错误是怎么引起的呢?不是指向的 char 可变吗?对,指向的 char 可变,所以编译能通过,但是赋给 date 的是一个字面字符串,按照 C 语言操作内存的机制,尝试更改字面字符串的会引起 bus error,至于具体的原因,可以继续深入了解 C 语言的编译机制和运行原理,这里不再赘述。追问谢谢,讲的很清楚(虽然我怀疑你是从哪里复制黏贴的),按我的理解const *char是 指针指向一个不可修改的变量(如果指针指向的变量前没有const,那么能修改吗)。char* const是指针在赋初值后就不能修改了是吗(如果是常量也不能修改吗)。
追答
“const *char是 指针指向一个不可修改的变量”这里是 const char *(应该是打错了吧...),其他的都对,另外是真的推荐这种“从右往左读”的判断声明式意思的方法,因为编译器生成语法树的时候就是这么做的,这种方法不仅对于判断 const 有用,无论那个声明式多么复杂,都可以用这种方法解决,比如说:
const char * Func_A (int const * Func_B (void * a, int b), int c);
这是一个函数声明,“从右往左”读:
首先是 Func_A,返回一个参数,这个参数 is a pointer to const char,即一个指向 const char 的指针;接受两个参数,第一个参数是一个函数,这个参数 Func_B 接受一个 void * 和一个 int,返回一个参数,这个参数 is a const pointer to int,即一个 const 指针,指向一个 int;Func_A 的第二个参数是一个 int。
下面是《Expert C Programming》中的一个例子(手头没有中文电子版,位置大概是靠前面的几章吧?):
热心网友
时间:2023-11-27 16:23
这里并不是常量,而是指向常量的指针。指针的值是可以变化的。
today.date="today is ";
today.date="this day is ";
这两条语句中,字符串被分配在了不可变化的区域,两条语句是指向了不同的内存地址是没有问题的。
如果你这样做就会报错:
today.date="to2ay is "; //赋值
today.date[3]='d'; //修改
因为你试图修改常量字符串的数据,这是不可以的。
热心网友
时间:2023-11-27 16:24
const char*是指date指向的内容不能变,而不是date不可以赋值
也就是today.date = "2020-02-03"合法
但是today.date[0]='2'非法
热心网友
时间:2023-11-27 16:24
const 常量 ---不可更改的
char* 字符指针 存储的是char的地址
const char* 字符常量指针 是一个存储常量char地址的指针 就是你这个指针存的const char的地址,即"指针自身不是常量" const char* xx == char const* xx
char * const 才是字符指针常量 储存是的char的地址,char的内容可更改,即"指针本身是常量"
如果想要都不能更改的话 可以用const char * const xx 或者 char const* const xx
热心网友
时间:2023-12-19 17:21
有一个判断 C 语言的声明式的技巧,那就是“从右往左读”,C++ 创始人 Bjarne Stroustrup 在其著作《The C++ Programming Language》中推荐了这种方法,《C 专家编程》中也提及了这种技巧。相比于其他的“根据 const 与其他词素的距离判断”、“根据 const 的前后关系判断”等等,个人认为这是最人性化的方法。从某种意义上来说,C 编译器在进行词法分析的时候巧合地运用了这种范式来进行语义转换,这一点在 Backus(上下文无关法) 范式中也有体现。
具体的方法是:
const char * A:A 是一个指针,指向 const char。
char const * A:A 是一个指针,指向 const char。
char * const A:A 是一个 const 指针,指向 char。
const char * const A:A 是一个 const 指针,指向 const char。
const char const * const A:A 是一个 const 指针,指向 const char,后面两个(从右往左读)有一个是多余的。
看到给出的示例:
const char* date;
这是一个指向 const char 的指针,这说明指针本身可变,但是其指向的 char 是不可变的,而 date = "new string" 中常量字符串其实是一个指针,因为指针可变,所以这里没问题。
但是如果写成 char* const date,那么这就是一个不可变的指针,但是其指向的 char 是可变的,这时候写 date = "new string" 就会报错:
error: cannot assign to variable 'date' with const-qualified type 'char *const'
但是如果尝试如下语句:
char* const date = "Hello, world!";
date[0] = 'H';
编译能通过,但是运行时会出错:
zsh: bus error
总线错误是怎么引起的呢?不是指向的 char 可变吗?对,指向的 char 可变,所以编译能通过,但是赋给 date 的是一个字面字符串,按照 C 语言操作内存的机制,尝试更改字面字符串的会引起 bus error,至于具体的原因,可以继续深入了解 C 语言的编译机制和运行原理,这里不再赘述。追问谢谢,讲的很清楚(虽然我怀疑你是从哪里复制黏贴的),按我的理解const *char是 指针指向一个不可修改的变量(如果指针指向的变量前没有const,那么能修改吗)。char* const是指针在赋初值后就不能修改了是吗(如果是常量也不能修改吗)。
追答
“const *char是 指针指向一个不可修改的变量”这里是 const char *(应该是打错了吧...),其他的都对,另外是真的推荐这种“从右往左读”的判断声明式意思的方法,因为编译器生成语法树的时候就是这么做的,这种方法不仅对于判断 const 有用,无论那个声明式多么复杂,都可以用这种方法解决,比如说:
const char * Func_A (int const * Func_B (void * a, int b), int c);
这是一个函数声明,“从右往左”读:
首先是 Func_A,返回一个参数,这个参数 is a pointer to const char,即一个指向 const char 的指针;接受两个参数,第一个参数是一个函数,这个参数 Func_B 接受一个 void * 和一个 int,返回一个参数,这个参数 is a const pointer to int,即一个 const 指针,指向一个 int;Func_A 的第二个参数是一个 int。
下面是《Expert C Programming》中的一个例子(手头没有中文电子版,位置大概是靠前面的几章吧?):
热心网友
时间:2023-12-19 17:21
这里并不是常量,而是指向常量的指针。指针的值是可以变化的。
today.date="today is ";
today.date="this day is ";
这两条语句中,字符串被分配在了不可变化的区域,两条语句是指向了不同的内存地址是没有问题的。
如果你这样做就会报错:
today.date="to2ay is "; //赋值
today.date[3]='d'; //修改
因为你试图修改常量字符串的数据,这是不可以的。
热心网友
时间:2023-12-19 17:22
const char*是指date指向的内容不能变,而不是date不可以赋值
也就是today.date = "2020-02-03"合法
但是today.date[0]='2'非法
热心网友
时间:2023-12-19 17:22
const 常量 ---不可更改的
char* 字符指针 存储的是char的地址
const char* 字符常量指针 是一个存储常量char地址的指针 就是你这个指针存的const char的地址,即"指针自身不是常量" const char* xx == char const* xx
char * const 才是字符指针常量 储存是的char的地址,char的内容可更改,即"指针本身是常量"
如果想要都不能更改的话 可以用const char * const xx 或者 char const* const xx