为一个朋友解答的C++小问题

回复 末离 的《关于C++的小问题》

关于c++的小问题,char *a="hello" 和char a[]="hello"
两者的区别是什么,
在实际应用中,有什么不同吗?


char *a="hello" 和char a[]="hello"
在char *a = "hello"里 a 是一个字符型针指变量,在编译这一句时,"hello"是一个字符串常量.本质是一个字符数组,但是每一个数组的无数是一个常量; a 就是指向的这个字符数组的第一个元素的存储地址.你可以通过用*(a + i)或者a[ i ] 去访问这个字符串里的每一个元素,但是你不能去用*(a + i) = ' a ' 或者 a[ i ] = ' b ' 去更改任何一个元素的值.在VC++里面, 因为一个字符指针直接赋值一个字符串,而这个字符串是一个常量,所以有下面这个特点:
                                                           char *a = "hello";
                                                           char *b = "hello";
                                                           由于"hello"是一个字符串常量,两条语句的字符串是一样的,所以这时,编译器给开辟了一次"hello"的存储空间, 让a 和 b 都指向这唯一一个"hello"的第一个元素存储的空间,所以a 和 b 是相等的.只要两个字符串有一点点的不同,则a 和 b 就是不相等的了.这样做,节约了空间,因为a 和 b 都是指向的量常,你本来就不能用a 和 b 去做修改字符串的操作,所以这样做是很好的.


在 char a[ ] = "hello" 里, a 就是一个数组名, 它的本质上相当于一个字符型的常量指针, 但是和碎片大哥说的一样,这个a在汇编以后是没有一个空间来存储它的, a 本身表示的就是一个地址, a 相当于一个地址的引用, 用a 去访问元素的时候是属于直接用地址去访问(也就是直接访问).a 所代表的地址是这个数组元素的第一个元素存储的地址,注意a 是代表了这个地址,而不是指向这个地址. 所以以后就不能做些想将a 所代表的地址更改的事了, 但是这个数组的每一个元素都是变量,所以你可以用*(a + i) 或 a[ i ]去访问更改元素的值.  

从上面的比较我们可以看出数组和指针之间是有很大的 联系的.我们就可以想到String 类一般会是怎么设计的.

#include "stdafx.h"
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
class String
{
public:
  String()
  {
     ptr = NULL;
     length = 0;
  }
  String(char *p)
  {
    length = strlen(p);
    ptr = new char[length + 1]; // 最后会有一个空字符
     strcpy(ptr, p);
     ptr[length] = '/0';
  }
  // 重载 = 运算符
  const String &operator = (const char *p)
  {
     if (ptr != NULL)
     {
        delete []ptr;
        length = 0;
     }
   length = strlen(p);
     ptr = new char[length + 1]; // 最后会有一个空字符
     strcpy(ptr, p);
     ptr[length] = '/0';
     return *this;
  }
  // 重载 [] 运算符 此处用来改变字符串的某一元素的值 
  char &operator [] (int subscript)
  {
     if(subscript < 0 || subscript >= length)
     {
       cerr << "/n错误: 下标 " << subscript
        << "越界!" << endl;
       exit(1);
     }
     return ptr[subscript]; // 此处把字符串里你想改的元素的引用返回给你了,所以你就可以去更改它的值
   }

  // 重载 [] 运算符  此处用来访问字符串的某一元素的值
  char operator [] (int subscript) const
  {
    if(subscript < 0 || subscript >= length)
     {
       cerr << "/n错误: 下标 " << subscript
        << "越界!" << endl;
       exit(1);
     }
     return ptr[subscript]; //此处只是把字符串里你想改的元素的值返回了.
  }

  ~String()
  {
     if (ptr != NULL)
     {
       delete []ptr;
     }
  }
  private:
   char *ptr;
   int length;
};

int main(int argc, char* argv[])
{
   String theString("Who are you?");
  cout << theString[2] << endl;

  theString = "Hymrjgc";

  cout << theString[2] << endl;
   return 0;
}

我只是简单的写了几个成员函数,大家可以加很多的,自己也可以做到像STL JAVA MFC C#里面的String 类型那样好。
不过我们在实际应用中,最好就用人家给我们的现成的好了,只是我们应该去了解明白他们可能是怎么去设计的。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值