字符指针的初始化以及程序分析实例
来源:互联网 发布:淘宝怎样发布宝贝 编辑:程序博客网 时间:2024/04/28 09:48
1. 初学者经常被这个问题所困惑: char *p="abc"==>"abc"是一个const char*,为什么能够赋值给char *呢?
2. 很多论坛上都可以看到这样的提问帖,不过这些帖子有的讲的是错误的,有的虽然是对的,但是讲的不细致,初学者不好理解。对此,我根据我的经验,以及CSDN上的一些帖子仔细地说一下其中的道理。
3. 按照 C/C++ 标准的描述,"abc" 是 string literal (字符字面量、字符文字量),具有静态存储性质,类型是数组类型,并且不能被改变。注意:"abc" 是一个数组类型的对象,是左值。当然左值可以转化为右值使用,就像数组类型的对象可以转化为指针一样。
4. 虽然 "abc" 是数组类型,但是 C 和 C++ 在类型规定上是有区别的:在 C 中,"abc" 的类型是 char [4];在 C++ 中,其类型是 const char [4]。 由于数组类型可以转换为指针类型来使用,所以在 C 和 C++ 中 "abc" 可分别作为 char* 及 const char* 使用。
5. 为了兼容c中char *p="abc"这种现象的存在,C++特别允许初始化时const char*到char*的自动转换。但是这条规则被 C++ 标明为 “Deprecated”,不被推荐使用。
6. 综上所述,在 C 中:char *p="abc"是完全合乎规则的事情,在 C++ 中:由于有特殊规定,所以这样也可以。
但在c++中要注意:char *p="abc" 能不能编译通过要看你使用的编译器。鉴于大量遗留代码的存在,大部分编译器允许其通过,或者给个警告。当然,程序员自己必须保证绝不去修改其值:
A. 程序员不应该在代码中出现*p='A'这样的语句。这是当初约定好了的:编译器允许char *p="abc"通过,而程序员保证不去修改它。
B. *p='A'编译时应该允许通过,因为单就这条语句而言,它完全合法。 C. 运行时*p='A'能不能通过要看实际的运行环境,包括你使用的操作系统、编译器、编译器选项 等等,一句话,其运行结果由不得你,且不应该由你去关心,因为这种行为本身已经违反约定了。
例:当我们修改字符串常量类型的指针变量时,编译器会提示程序出错的。下面来具体讲一讲这种类型的错误。
程序1:
#include <string.h>#include <stdio.h>int main(){ //char str[5]="good"; char *str="good"; char *strtemp=NULL; printf("The string befor reversal: %s\n",str); strtemp=strrev(str); printf("The string strtemp reversed is: %s\n",strtemp); return 0;}
当我们用VC++编译时,会终止程序,并且弹出这样的提示信息:
但是这样的提示还是不够清楚,我们可以换个编译器,
当我们用VS2013编译运行下面的程序时:程序2:
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <stdio.h>#include <string.h>int _tmain(int argc, _TCHAR* argv[]){char *forward = "string";printf("Before strrev(): %s\n", forward);_strrev(forward);printf("After strrev(): %s\n", forward);return 0;}VS2013会终止程序,并且弹出这样的提示信息:
其实在程序中,我们已经修改了字符串常量指针,所以编译器会弹出提示信息,并且程序不能正常运行。
在程序1中,有这样几句代码:
char *str="good"; char *strtemp=NULL; printf("The string befor reversal: %s\n",str); strtemp=strrev(str);
系统函数strrev( )已经修改了字符串指针变量str的值,所以程序会出现修改常量的错误。
在程序2中:
char *forward = "string";printf("Before strrev(): %s\n", forward);_strrev(forward);printf("After strrev(): %s\n", forward);这几句代码也是犯了同样的错误。
所以可以将程序1修改如下:
#include <string.h>#include <stdio.h>int main(){ char str[5]="good"; //char *str="good"; char *strtemp=NULL; printf("The string befor reversal: %s\n",str); strtemp=strrev(str); printf("The string strtemp reversed is: %s\n",strtemp); return 0;}
此程序在VC++6.0的运行结果如下:
1 0
- 字符指针的初始化以及程序分析实例
- 字符指针的初始化
- 字符指针的初始化
- 指针和字符的初始化
- 字符指针和字符数组的初始化
- C程序设计语言- 指针与数组-4.2----字符指针与函数、指针数组以及指向指针的指针、指针数组的初始化
- 字符型指针初始化
- C++实例:指向指针的指针的初始化
- 类以及类实例的初始化
- c语言中字符串常见初始化时的问题,以及字符串数组与指针区别的分析
- 字符串截取以及字符数组和字符指针的区别
- 结构体指针初始化以及结构体中成员变量是指针的初始化
- c和指针 前三章知识点以及常见的问题和程序分析
- C语言指针问题,初始化,赋值,以及字符数组,字符串常量等问题
- C语言指针初始化的必要性以及指针变量与指针值的用法
- 研究多重指针的实例分析
- 【Storm】storm安装、配置、使用以及Storm单词计数程序的实例分析
- 【Storm】storm安装、配置、使用以及Storm单词计数程序的实例分析
- 帮助文档打开后右边显示为空
- iOS基础之沙盒机制-路径获取
- 深刻理解Python中的元类(metaclass)
- 自然数幂和模板
- 数组和逗号表达式
- 字符指针的初始化以及程序分析实例
- 【案列】私人通讯录01
- 简单脱壳教程笔记(3)---手脱UPX壳(2)
- “1”+ “1”等于几?
- 蓝桥杯 第五届 六角填数
- 一个简易的账号登录/广播的使用
- 十二.通过bootstrap的modal.js来完成删除功能
- 安卓 jni 开发 —— Android Studio 打包 so 的坑
- [扫描线 线段树 暴力] BZOJ 4059 [Cerc2012]Non-boring sequences