字符指针, 字符数组, 字符串
预备知识: C程序在内存中的空间占用分配
(1)代码区:存放程序代码;
(2)数据区
a.静态数据区: 在编译器进行编译的时候就为该变量分配的内存,即全局变量和静态变量(用static声明的变量),存放在这个区的数据程序全部执行结束后系统自动释放,声明周期贯穿于整个程序执行过程。全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(.data),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bss)。
b.堆区:这部分存储空间完全由程序员自己负责管理,它的分配和释放都由程序员自己负责。这个区是唯一一个可以由程序员自己决定变量生存 期的区间。可以用malloc,new申请对内存,并通过free和delete释放空间。如果程序员自己在堆区申请了空间,又忘记将这片内存释放掉,就 会造成内存泄露的问题,导致后面一直无法访问这片存储区域。但程序退出后,系统自动回收资源。分配方式倒是类似于链表。
c.栈区:存放函数的形式参数和局部变量,由编译器分配和自动释放,函数执行完后,局部变量和形参占用的空间会自动被释放。效率比较高,但是分配的容量很有限。
d.常量区: 存放常量的区间,如字符串常量等,注意在常量区存放的数据一旦经初始化后就不能被修改。 程序结束后由系统释放。
字符串:字符串是一个以'\0'结尾的字符数组, 实际上在C语言中没有字符串这种数据类型
字符指针: 字符指针是一个指向字符的指针
字符数组:字符数组是元素为字符的数组
关于字符串赋值的例子: 以下示例中1,2,3是正确的, 而4是错误的
1.
char *p1 = "123";
2.
char p2[] = "123";
3.
char *p3;
p3 = "123";
4.
char p4[10];
p4 = "123";
对于示例1和示例3, 双引号做了3件事:
1.申请了空间(在常量区),存放了字符串
2.在字符串尾加上了'/0'
3.返回地址
对于示例2:
1.申请空间(在栈空间) ,存放字符串
2.在字符串尾加上了'/0'
关于常量空间还是栈空间分配的一个示例
/**
* 错误写法, 因为字符串1234567是在常量池中存储, 不能被修改, 所以第二条赋值语句错误
*/
void test16() {
char *p = "1234567";
*(p + 3) = 'a';
}
/**
* 正确,对比test16(),用数组的形式初始化字符串,1234567是存储在栈内存中的
*/
void test17(){
char p[] = "1234567";
p[3] = 'a';
printf("%c", p[3]);
}
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy