【规则】  
1  、  string  为普通类型,不是数组型,只是其内容为字符串;  
2  、  ’a’  和  ”a”  的区别:  ’a’  为字符,  ”a”  为字符串;单引号只能定义一个字符,双引号可以定义多个字符,即字符串。  
3  、指针可以通过加减、自加减改变其值,数组不可以。  
4  、以数组定义的字符串可以修改其中的字符,以指针定义的字符串不能修改其中的字符。  
  
 例如:

char a[]=”hello”; 
  cout<<a;               //输出 hello 
  cout<<*(a+1);      //输出 e,即数组a的第2个字符,即a[1] 
  cout<<a[1];          //输出 e,即数组a的第2个字符,与上同 
  cout<<*a++;        //错误,规则3,数组名是常量,不可以改变其值 
  cout<<*a;            //输出 h,即数组a的第一个字符 
  cout<<a;              //输出hello 
  *a=”L”;            //错误,规则2,*a为字符,”L”为字符串,不匹配 
  *a=’L’;            //正确,规则4,将数组第一个字符修改为L 
  cout<<a;              //输出 Lello 
  a[2]=’6’;          //正确,规则4,将数组第3个字符修改为’6’ 
  cout<<a;              //输出 Le6lo 
    
  char *a="hello"; 
  cout<<a;            //输出 hello 
  cout<<*(a+1);    //输出 e,即字符串a的第2个字符 
  cout<<a[1];        //输出 e,即字符串a的第2个字符,这里也可以视为数组a 
  cout<<*a++;      //输出 h,,规则3,即先计算*a,再使a=a+1 
  cout<<*a;          //输出 e,因上一行中a已经自加1 
  cout<<a;            //输出 ello,因为指针a已经发生变化,指向了下一个地址,即指向以e开头的字符串 
  *a=’L’;         //错误,规则4,不能修改指针定义的字符串的字符。
                             //【注意】此处编译可通过,运行时会出错,提示“不能写入” 
  a[2]=’6’;      //错误,规则4,不能修改指针定义的字符串的字符。


1、以字符串形式出现的,编译器会在结尾自动添加\0,思考,为什么?

  存在的C语言方法,如strlen(s),计算字符串的长度,其中s指针。strlen要计算字符串长度,必须知道哪里是结尾,因此使用\0表示结尾。只有字符数组才有\0的概念,其它类型(int)的数组没有这个概念。因为其他类型的数组或者指针,没有strlen这种方法。

  那么问题来了,int数组如何计算长度呢?如int a1 = {3,7,9,};

  使用sizeof(a1)/sizeof(int)。

2、数组可以在栈上分配,也可以在堆上分配,但必须指定大小。

char a1[100]; //在栈上分配
  char* pa = new char[100];// 在堆上分配,返回首元素的地址

3、char a1[] = "abc"; 相当于在栈顶分配4个字节,分别放上a,b,c,\0,等价于char a1 ={'a','b','c','\0'};

4、char* pa = "abc"; 分析一下就知道,pa是char指针,"abc"是一个文本字符串,显然类型不吻合,需要适配。可认为编译器做了下面的事情:在常量区分配4个字节,分别放上a,b,c,\0,然后把a的地址返回给pa。

  注意:文本字符串放在常量区,是不可修改的,试图修改,运行异常。那么在思考一下,既然右边是const,而pa并没有限定为const char*,按道理赋值失败。为什么可以成功?

  可以认为在C语言中,到处充斥着这样的代码。为了兼容,必须允许。但是,我们应该写const char* pa ="abc"; 这样的话,试图修改pa的内容,编译报错。

5、char a1[] = "abc", 等价于char a1[] = {'a','b','c','\0',}; strlen(a1)等于3,长度不包括\0

  假如这样写 char a1[] = {'a','b','c',}; strlen(a1)是多少? 答案不确定,因为strlen一直找到\0才认为是结尾。
6、 char a1[] = "abc"; 下面的结果分别是什么?

cout<<&a1[0]<<endl;
  cout<<a1<<endl;

  输出相同,都是数组元素的第一个地址。

7、char* pa = "abc"; 下面的结果分别是什么?

cout<<&pa<<endl;
  cout<<&pa[0]<<endl;
  cout<<pa<<endl;

  第一行输出pa在栈上的地址,第二行和第三行输出相同,都是首地址。pa是指针,就是指向首个元素的地址。

8、char a1[5]; 数组名是个指针常量,不能修改指向。

9、char* pa = "abc"; 可认为pa是个指向常量的指针。

10、下面的结果,违反直觉,按道理第4行,第5行应该输出地址。但是却输出指向的字符串。这有一定的合理性,我们打印char指针,往往是要看指向的内容,而不是要看地址是多少。而且cout很容易做到,只要遇到\0就结束。那么问题来了,我想看地址怎么办?使用int强制转化为地址。


1  char a1[]="abc";
2  char* pa="def";
3 
4  cout<<a1<<endl; //输出abc
5  cout<<pa<<endl; //输出def
6 
7  cout<<(int)a1<<endl; // 输出a1地址
8  cout<<(int)pa<<endl; // 输出pa地址


11、


1  char p[]="abcde";
2  char* p2="abcde";
3 
4  cout<<sizeof(p)<<endl; //数组大小为6
5  cout<<sizeof(p2)<<endl; // 指针大小为4
6 
7  cout<<strlen(p)<<endl; // 长度为5
8  cout<<strlen(p2)<<endl; // 长度为5




#include <iostream>
#include <string>
using namespace std;

void convertUnCharToStr(char* str, unsigned char* UnChar, int ucLen)
{
	int i = 0;
	for(i = 0; i < ucLen; i++)
	{
		//格式化输str,每unsigned char 转换字符占两位置%x写输%X写输
		sprintf(str + i * 2, "%02x", UnChar[i]);
	}
}

void convertStrToUnChar(char* str, unsigned char* UnChar)
{
	int i = strlen(str), j = 0, counter = 0;
	char c[2];
	unsigned int bytes[2];

	for (j = 0; j < i; j += 2) 
	{
		if(0 == j % 2)
		{
			c[0] = str[j];
			c[1] = str[j + 1];
			sscanf(c, "%02x" , &bytes[0]);
			UnChar[counter] = bytes[0];
			counter++;
		}
	}
	return;
}

int main()
{
	unsigned char src[6] = {0x12, 0x32,0x56,0x78,0x90,0xab};
	char buffer[20];//维数定义些
	convertUnCharToStr(buffer, src, 6);  
	printf("%s\n", buffer);


	unsigned char dst[6];
	int len = strlen(buffer);
	cout << len << endl;
	convertStrToUnChar(buffer, dst);
	
	int i = 0;
	for(i = 0; i < 6; i++)
	{
		printf("%x ", dst[i]);
	}
	cout << endl;


	return 0;
}