char[]和char*的区别

1、char[]是一个数组定义,char*是指针定义(也称char[]为静态数组,char*为动态数组)。

2、指针和数组的区别

(1)指针和数组的分配

数组是开辟一块连续的内存空间,数组本身的标识符(也就是通常所说的数组名)代表整个数组,可以使用sizeof来获得数组所占据内存空间的大小(注意,不是数组元素的个数,而是数组占据内存空间的大小,这是以字节为单位的)。举例如下:

#include<stdio.h>

void main()

{

    char a[] = "hello";

    int b[] = { 1, 2, 3, 4, 5 };

 

    printf("a:%d\n", sizeof(a));

    printf("bmemory size: %d bytes\n", sizeof(b));

    printf("belements: %d\n", sizeof(b) / sizeof(int));

 

    getchar();

    return;

}

运行结果:

数组a为字符型,后面的字符串实际上占据6个字节空间(注意最后有一个\0标识字符串结束)。sizeof(b)就可以看出如何获得数组占据的内存空间,VS编译器为int类型分配4个字节的内存空间,通过Sizeof(b)/sizeof(int)就可以算出数组元素个数。

(1)空间的分配

这里又分为两种情况。

第一、如果是全局的和静态的

char *p =“hello”;

这里定义了一个指针,指向rodata section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是编译器优化的一个措施。

char a[] = “hello”;

这里定义了一个数组,分配在可写数据块,不会被放到字符串池。

 

第二、如果是局部的

char *p =“hello”;

这里定义了一个指针,指向rodata section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是编译器优化的一个措施。另外,在函数中可以返回它的地址,也就是说,指针是局部变量,但是它所指向的内容是全局的。

char a[] = “hello”;

这是定义了一个数组,分配在堆栈上,初始化由编译器进行(短的时候直接用指令填充,长的时候就从全局字符串拷贝),不会被放到字符串池(同样如前,可能会从字符串池中拷贝过来)。注意不应该返回它的地址。

附:

1、对于整型指针,如int *p = new int;那么cout<<p只会输出这个指针的值,而不会输出这个指针指向的内容。对于字符型指针,如char *pch = “abcde”;那么cout<<ch就会输出指针指向的内容,即abcde。

实例代码:

#include"stdafx.h"

#include<iostream>

#include<stdio.h>

 

using  namespace std;

 

void main()

{

    int *p = newint;

    *p= 2;

   

    char *pch = "abcde";

 

    cout<< p <<"<<pch<< endl;

 

    getchar();

    return;

}

运行结果:

这里的char ch[]=“abc”;表示ch是一个足以存放字符串初值和空字符‘/0’的一维数组,可以更改数组中的字符,但是ch本身是不可改变的常量。

char *pch = “abc”;这里pch是一个指针,其初值指向一个字符串常量,之后它可以指向其他位置,但如果试图修改字符串的内容,结果将不确定。

总结:

1、 char p[]表示p是一个数组指针,相当于const pointer,不允许对该指针进行修改。但该指针所指向的数组内容,是分配在栈上面的,是可以修改的。

2、char * pch表示pp是一个可变指针,允许对其进行修改,即可以指向其他地方,如pch= p也是可以的。对于*pch = "abc";这样的情况,由于编译器优化,一般都会将abc存放在常量区域内,然后pp指针是局部变量,存放在栈中,因此,在函数返回中,允许返回该地址(实际上指向一个常量地址,字符串常量区);而,char p[]是局部变量,当函数结束,存在栈中的数组内容均被销毁,因此返回p地址是不允许的。

同时,从上面的例子可以看出,cout确实存在一些规律:

1、对于数字指针如int*p=new int; 那么cout<<p只会输出这个指针的值,而不会输出这个指针指向的内容。
2、对于字符指针入char *p="sdf f";那么cout<<p就会输出指针指向的数据,即sdf f。那么,像&(p+1),由于p+1指向的是一个地址,不是一个指针,无法进行取址操作。&p[1] = &p + 1,这样取到的实际上是从p+1开始的字符串内容。

分析上面的程序:

*pch = "abc";

p[] = "abc";

*pch指向的是字符串中的第一个字符。

cout << pch; // 返回pp地址开始的字符串:abc

cout << p; // 返回p地址开始的字符串:abc

cout << *p; // 返回第一个字符:a

cout << *(p+1); // 返回第二个字符:b

cout << &p[1];// 返回从第二个字符开始的字符串:bc

2015年5月16日

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值