首页 > 代码库 > 字符数组、字符指针请不要再纠结

字符数组、字符指针请不要再纠结

        在C语言中字符数组、字符指针的一些特质感觉有点模糊,有些时候只知道要这样做却不知道为什么,过段时间就忘了,下次又得费时费力费钱的找答案,难受。OK,今天就好好琢磨琢磨~

     先来两个基本概念:

1、声明字符数组

int a[10];
定义了一个长度为10的数组a。换句话说它定义了一个由10个对象组成的集合,这10个对象存储在相邻的内存区域中,名字分别为a[0]、a[1]、...如果pa的声明为

int *pa;
则说明它是一个指向整形对象的指针,那么赋值语句

pa = &a[0];
则可以将指针pa指向数组a的第 0 个元素,也就是说pa的值为数组元素a[0]的地址。这样,赋值语句

x = *pa;
将把数组元素a[0]中的内容复制到变量 x 中。

那么,根据指针运算的定义,pa+1将指向下一个元素,pa+i将指向pa所指向数组元素之后的第i个元素。无论数组a中元素的类型或数组长度是什么,上面结论都成立。指针加 1 意味着指向下一个对象。

所以,pa = &a[0] 也可以写成下列形式:

pa = a;
综上:&a[i] 和 a+i 的含义是相同的。相应地,如果 pa 是个指针,那么在它的表达式中也可以加下标(是的,你没有看错

char a[100];
char *b = NULL;

memset(a, 0, sizeof(a));

a[0] = '0';
a[1] = '1';
a[2] = '2';


b = a;
char test= b[1];       //现在test的值就是 1

但是有一点必须记住,数组名和指针之间的一个不同之处:指针是一个变量,因此,在C语言中,语句pa = a 和 pa++ 都是合法的。但是数组名不是变量,因此,类似于a = pa 和 a++形式的语句是非法的。


2、关于字符指针

char *a = "test";
这里的指针a是一个变量,它指向静态常量区的"test"的首地址,并且常规状态下“test”不可改变(当然,通过某些手段也是可以改变的)。


有了以上两点,下面继续...

1、字符数组转字符指针

有时候需要在字符数组和字符指针之间相互转换,不可避免的用到strcpy()函数,先看看它的源码:

void strcpy(char *s, char *t)
 {
       while ((*s++ = *t++) != '\0')
           ;
 }

再来看个超简单的例子:

char *a = NULL;
char b[5]= {'1','2'};

a = b;            //OK,这样正确
strcpy(a,b);   //这样会报内存错
最开始,指针变量指向NULL,a在内存中是没有分配空间的,a = b  的时候,指针变量a指向了数组的首元素地址也就是  ‘1‘ 。但strcpy的时候,*s 是无法被赋值的,因为没有为它开辟内存空间。有人会问,开辟内存空间是吧,那行,我这样  char *a = "abc"; 现在*a 有内存空间了吧!试了发现仍然不行,因为 *a 现在是不可改变的,强行赋值当然出错。如果非要用strcpy也行,那得重新开辟内存给 a。

char *a = (char *)malloc(100);   //大小自己看情况定吧
char b[5] = {'1','2'};

strcpy(a,b);                    //这样就没问题了

这两种方式的区别就是:

直接赋值时,改变的仅仅是指针的指向,即a指向了数组b。

使用函数strcpy时,在内存中多开辟了一块空间,也就是说现在内存中有两块内容一样空间,都为{‘1‘,‘2‘},一块由a指向,一块由b指向。


2、字符指针转字符数组

char *a = "123";
char b[5];
memset(b,0,sizeof(b));b = a;                //会报错
strcpy(b,a);          //OK

前面说了,数组名不是变量,不能当左值,显然 b = a 会报错。

strcpy里面的两个参数传给char * 一点问题都没有,s指向b 的首地址,t指向常量区的‘1‘。

字符数组单个元素的值是可以改变的。这里要说一下的是字符数组初始化的问题,一般三种情况:

1、定义的时候直接用字符串赋值
char a[10]="hello";
注意:不能先定义再给它赋值

2、对数组中字符逐个赋值
char a[10]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘};

3、利用strcpy


参考资料:The C Programming Language

字符数组、字符指针请不要再纠结