char[]数组与char *指针的区别
char[]数组与char *指针的区别
问题描述
虽然很久之前有看过关于char指针和char数组的区别,但是当时没有系统的整理,到现在频繁遇到,在string,char[], char *中迷失了。由于string涉及的内容很多,因此本文中就先不整理了,对char[]和
char *进行了一个整理,原理可能还是不太明白,但至少印象深刻了很多。
整型数组和整型指针
在讨论字符数组、字符指针以及字符串之前,先看下整型数组与整型指针的区别
int a[]={1,2,3};//整型数组,a的指向不能改变,但数组的内容可以改变
int *p = a;//整型指针,可以改变指向
//resetiosflags(ios::right)<<setw(12)用来设置右对齐的格式
cout<<"a = "<<resetiosflags(ios::right)<<setw(12)<<a<<endl;//输出结果为a在内存中的位置
cout<<"&a = "<<resetiosflags(ios::right)<<setw(11)<<&a<<endl;//对数组名取地址,结果同上
cout<<"p = "<<resetiosflags(ios::right)<<setw(12)<<p<<endl;//输出结果与a一致
cout<<"&p = "<<resetiosflags(ios::right)<<setw(11)<<&p<<endl;
cout<<"&a[0] = "<<resetiosflags(ios::right)<<setw(7)<<&a[0]<<endl;//数组第一个元素的地址

从结果可以看出,整型数组名和对数组名用取地址"&"运算符得到的结果是一致的,其结果与数组的首个元素在内容在的地址相同;但对于整型指针,两者的值有所不同
cout<<"*a = "<<*a<<endl;
cout<<"*p = "<<*p<<endl;
cout<<"&(*a) = "<<&(*a)<<endl;
cout<<"&(*p) = "<<&(*p)<<endl;
cout<<"*(&a) = "<<*(&a)<<endl;
cout<<"*(&p) = "<<*(&p)<<endl;

此处* a代表的是a指向的数组的第一个元素的值,* p 与* a 相同
对* a和* p取地址得到的实际上就是数组的地址
&a和&p已经是地址了,
加上* 得到的结果对于数组名而言,是数组的地址,对指针p而言,是其指向的内容的地址
void f1(int arr[])//与 f1(int *arr)在本质上一致
{
cout<<"In f1 sizeof(arr) is: "
<<sizeof(arr)<<endl;//这个时候,虽然传入的是数组,但是arr自动退化为指针
}
cout<<"In main sizeof(a) is: "<<sizeof(a)<<endl;//输出12,即整个数组的大小
cout<<"In main sizeof(p) is: "<<sizeof(p)<<endl;//输出4,即整型指针的大小
f1(a);
if (a== p)//用==对a和p进行比较时,两者是相同的
{
cout<<"a == p "<<endl;
}
else
cout<<"a != p "<<endl;
对数组名和指针名用sizeof的结果如下

总的来说,在整型数组中,数组名相当于指向数组首元素的指针,但其指向不可改变。当将一个数组作为参数传递给函数时,实际传入的是指针。
字符数组和字符指针
首先定义两个字符数组和两个字符指针
char ch1[] = "hello world";//字符数组
char ch2[] = "hello world";
char * ch3 = "hello world";//字符指针
char * ch4 = "hello world";
然后对数组以及指针进行一系列的输出
输出字符数组的名和指针名
//这四个语句的输入是相同的
cout<<"ch1 = "<<ch1<<endl;//输出的是整个字符数组的内容
cout<<"ch2 = "<<ch2<<endl;//同上
cout<<"ch3 = "<<ch3<<endl;//输出的指针指向的整个区域的值
cout<<"ch4 = "<<ch4<<endl;
输出字符数组的名和指针名的结果如下图所示

从输出结果可以看到与整型数组和整型指针的输出结果完全不同,在整型数组和整型指针的情况下,输出的是内存中的地址,字符串数组名输出的结果是整个字符串数组的内容,字符串指针输出的内容是所指向的字符串的所有内容。
对数组和指针名取地址
cout<<"&ch1 = "<<&ch1<<endl;//每个指针各自在内存中的地址
cout<<"&ch2 = "<<&ch2<<endl;
cout<<"&ch3 = "<<&ch3<<endl;
cout<<"&ch4 = "<<&ch4<<endl;
对字符数组和字符指针取地址后的输入结果如下图

从结果可以看出,输出的是每个指针各自的地址(数组名实质上就是指向数组首地址的指针)
对首元素去地址
cout<<"&ch1[0] = "<<&ch1[0]<<endl;//输出的结果是整个字符串数组
cout<<"&ch2[0] = "<<&ch2[0]<<endl;//同上
cout<<"&ch3[0] = "<<&ch3[0]<<endl;//同上
cout<<"&ch4[0] = "<<&ch4[0]<<endl;//同上
在整型数组中,&a[0]的输出结果是数组的首地址,在字符串中,结果却不是

由结果可知,字符数组的第一个元素取地址的结果输出的却是整个字符串
对数组名和指针用* ,同时对首元素取地址后用*
cout<<"*ch1 = "<<*ch1<<endl;
cout<<"*ch2 = "<<*ch2<<endl;
cout<<"*ch3 = "<<*ch3<<endl;
cout<<"*ch4 = "<<*ch4<<endl;
cout<<"*(&ch1[0]) = "<<*(&ch1[0])<<endl;
cout<<"*(&ch2[0]) = "<<*(&ch2[0])<<endl;
cout<<"*(&ch3[0]) = "<<*(&ch3[0])<<endl;
cout<<"*(&ch4[0]) = "<<*(&ch4[0])<<endl;

结果比较好理解,就是字符数组的第一个字符
&和* 同时使用
cout<<"&(*ch1) = "<<&(*ch1)<<endl;
cout<<"&(*ch2) = "<<&(*ch2)<<endl;
cout<<"&(*ch3) = "<<&(*ch3)<<endl;
cout<<"&(*ch4) = "<<&(*ch4)<<endl;
cout<<"*(&ch1) = "<<*(&ch1) <<endl;
cout<<"*(&ch2) = "<<*(&ch2) <<endl;
cout<<"*(&ch3) = "<<*(&ch3) <<endl;
cout<<"*(&ch4) = "<<*(&ch4) <<endl;

输出的结果是整个字符数组,和整型的情况又不同
用==和strcmp比较
if (ch1== ch2)
cout<<"ch1== ch2"<<endl;
else
cout<<"ch1 != ch2"<<endl;
if (ch3== ch4)
cout<<"ch3== ch4"<<endl;
else
cout<<"ch3 != ch4"<<endl;
if (strcmp(ch1,ch2) == 0 )
cout<<"Using strcmp, ch1 = ch2"<<endl;
else
cout<<"ch3 != ch4"<<endl;

由于ch1和ch2s是两个不同的数组,所以用== 判断的返回结果为假
ch3和ch4是两个指针,其指向内容相同,因此用== 判断返回值为真
strcmp比较的只是数组的内容,ch1与ch2的内容是相同的
char[]数组与char *指针的区别的更多相关文章
- c++ 踩坑大法好 char字符,char数组,char*
1,基本语法 1,定义一个char字符: char hehe='a'; //单引号 2,定义一个由char字符组成的数组: char daqing[] = "abcd"; char ...
- char数组与char指针
1.以字符串形式出现的,编译器会在结尾自动添加\0,思考,为什么? 存在的C语言方法,如strlen(s),计算字符串的长度,其中s指针.strlen要计算字符串长度,必须知道哪里是结尾,因此使用\0 ...
- 别人不会给你说的---C语言中数组名和指针的区别 及 sizeof用法
引自: http://blog.csdn.net/tianyue168/article/details/5781924 #i nclude <iostream.h> int main( ...
- C/C++数组名与指针的区别详解
1.数组名不是指针我们看下面的示例: #include <iostream> int main() { ]; char *pStr = str; cout << sizeof( ...
- CPP-基础:C/C++数组名与指针的区别
2005-08-23 08:36 来源:天极网 作者:宋宝华 责任编辑:方舟·yesky 引言 指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用.于是乎,很 ...
- 【转】C语言中数组名和指针的区别
注:本文转自http://www.cnblogs.com/furaibo/archive/2010/03/19/1689710.html 魔幻数组名 请看程序(本文程序在WIN32平台下编译): #i ...
- C++中数组名和指针的区别联系
原文:http://www.cnblogs.com/ddx-deng/archive/2012/12/16/3755862.html 第一个结论: #include "iostream.h& ...
- char、char*、char**数组(有图,非常清楚)good
平时都用的是char数组,基本忘记了char*数组和char**数组该怎么用了 char s1[10]; s1[0] s1[1]等都是char s1是char*,等同于&s1[0] char* ...
- c语言结构体中的一个char数组怎么赋值?
目录 前景提示 这里的结构体处理的步骤 一.char数组类型的处理 二.char数组指针类型的处理 三.全部代码 1. char数组 2. char数组指针 结语 前景提示 定义一个结构体,结构体中有 ...
随机推荐
- ASP.NET MVC 3 初认知
什么是ASP.NET MVC 1. asp.net mvc 是微软官方提供的mvc模式编写asp.net web应用程序的框架. 2. 是微软既asp.net webForm 后的又一种开放方式,而非 ...
- HorseCome
紫气东来,祝福也随之而来,喜鹊登梅,福禄也登上眉梢,马年将至,喜庆将萦绕身旁,在这个美好的日子送上我最真挚的祝福,祝身体安康. 春晓,春晓,处处绿杨芳草.山山水水,欢欢笑笑,共祝六合同春,步步登高!
- Java多线程4:synchronized关键字
原文:http://www.cnblogs.com/skywang12345/p/3479202.html 1. synchronized原理在java中,每一个对象有且仅有一个同步锁.这也意味着,同 ...
- Tomcat启动后访问首页报错 显示JSP 空指针异常
HTTP Status 500 - type Exception report message description The server encountered an internal error ...
- openfire的smack和asmack
smack你可以看成是一套封装好了的用于实现XMPP协议传输的API,它是一个非常简单并且功能强大的类库,给用户发送消息只需要三行代码.下载地址:http://www.igniterealtime.o ...
- .NET 框架 (转载)
转载:http://www.tracefact.net/CLR-and-Framework/DotNet-Framework.aspx .NET框架 三年前写的<.NET之美>的第六章,现 ...
- 如何屏蔽LOGD\LOGI等打印输出
今天被打印信息的去除困扰了,想了想,如果靠一个一个的改动未免太繁琐.因此就仔细的看了下这部分的打印原理.当然下面只是简单的进行了知识罗列不过有需要的朋友可以随便看看.说不准会有些收获呢. Includ ...
- NDK(15)在ndk代码中注册和注销native函数
转自: http://www.cnblogs.com/canphp/archive/2012/11/13/2768937.html C和C++注册native函数的方式大致上相同,下面给出具体的代码 ...
- 面试题_31_to_47_JVM 底层与GC(Garbage Collection)的面试问题
31)64 位 JVM 中,int 的长度是多数?Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位.意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类 ...
- 进程间通信机制<转>
1 文件映射 文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待.因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容. ...