在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
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
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
原文地址:http://blog.csdn.net/a491057947/article/details/43234707