首页 > 代码库 > 字符数组、字符指针请不要再纠结
字符数组、字符指针请不要再纠结
在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
字符数组、字符指针请不要再纠结
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。