深入了解字符串和字符数组
一:深入认识sizeof和strlen
(1).sizeof是C语言的一个关键字,也是C语言的一个运算符,很多人可能会误认为sizeof是个函数,但实际上不是,sizeof运算符的作用是用来返回一个类型的或者一个变量所占用的内存字节数。为什么我们需要sizeof呢?,主要的一个原因是int、double等等类型的大小与各个平台的内存有关;二是C语言除了ADT(抽象数据类型:一个数据元素集合以及在这些数据上的操作)之外还有UDT,这些是自定义类型的数据是无法一眼就可以看出来的。=
(2).strlen是C语言的一个函数库,这是函数库是:size_t strlen(const char * s);这个函数接收一个字符串的指针,返回这个字符串的长(以字节为单位)。注意的一点是:strlen返回的字符串长度是不包含字符串结尾’\0’的。为什么我们需要strlen函数库?因为我们在定义字符串的时候,我们无法直接得到字符串的字节长度。
二:sizeof和strlend在程序中的运用和差别
实验测试:
#include "stdio.h"
#include "string.h"
//strlen函数的实现过程
int my_strlen(const char *p)
{
int cnt = 0;
while (p++ != '\0')
{
cnt++;
}
return cnt;
}
int main(void)
{
//第七次测试:
char* p = "liunx";
printf("sizeof(p) = %d\n",sizeof( p)); //4
printf("strlen(p) = %d\n", strlen(p)); //5
//第六次测试:
char a[7] = {"hellow world"};
printf("sizeof(a) = %d\n", sizeof(a)); // 7
printf("strlen(a) = %d\n", strlen(a)); // >=12
//第五次测试:
//我们可以得出sizeof运算符的包括'\0'的
char a[] = {"hellow world"};
printf("sizeof(a) = %d\n", sizeof(a)); //13
printf("strlen(a) = %d\n", strlen(a)); //12
//第四次测试:
//我们还可以得出了当遇到0的时候,strlen的运行也结束了
char a[5] = { 1 ,0,1};
printf("sizeof(a) = %d\n", sizeof(a)); //5
printf("strlen(a) = %d\n", strlen(a)); //1
//第三次测试:
//这个跟测试二的结论是一样的
char a[5] = { 1 };
printf("sizeof(a) = %d\n", sizeof(a)); //5
printf("strlen(a) = %d\n", strlen(a)); //1
//第二次测试:
//1.我们仍然可以得到sizeof可以直接计算出字符串数组的元素个数。
//2.通过上面对strlen的分析,得到0这个结果,也证实我们上面的说法,strlen只计算\0前面的数据长度
char a[5] = { 0 };
printf("sizeof(a) = %d\n", sizeof(a)); //5
printf("strlen(a) = %d\n", strlen(a)); //0
//第一次测试:
//1.我们可以分析到sizeof可以直接得出字符数组的元素的个数(可以得到上面对sizeof的分析是合理的),
//2.而strlen运行得出数据不一样,可以得到strlen在这里没有什么意义
char a[5];
printf("sizeof(a) = %d\n", sizeof(a)); //5
printf("strlen(a) = %d\n", strlen(a)); //19或者23
char* p = "liunx";
int len = strlen(p);
printf("P的长度为: %d", len); //结果为5
return 0;
}
总结:
一: sizeof(数组名)得到的永远是数组的元素个数(也就是数组的大小),和数组中有无初始化,初始化多少都没有关系,strlen是用来计算字符串的长度
的只能传递合法的字符串进去才有意义,如果传递随便传递一个字符指针,这个字符串指针是并不是字符串是没有意义的。
二:当使用sizeof检测字符串数组的大小的时候,如果我们没有给字符串数组定义大小的时候,牢记字符串的部'\0'是包括的。
三:定义通过实验测试七,我们可以得到sizeof(p)永远是4,因为这时候sizeof测的是字符指针p本身的长度,和字符串的长度是没有什么关系的。
字符串和字符数组的本质区别(内存分配的角度)
一: 字符串数组:
char a[] = “liunx”;定义一个数组a,数组a占6个字节,右值“liunx”本身中存在于编译器中,编译器将他用来初始化字符串数组a之后就丢弃
了(也就是说内存中是没有“liunx”这个字符串的);这句话就相当于a[] = {'l'、'i'、'n'、'u'、'x'、'\0'};
二: 字符串:
char *p = “liunx”;定义了一个字符指针p,p指针占4个字节,分配在栈上;同时还定义了一个字符串“liunx”,分配在代码段;然后把代码段中的字符串的首地址赋值给p。
#include "stdio.h"
#include "string.h"
char b[5]; //全局变量存储在数据段
int main(void)
{
//字符串存储在栈上
char a[7];
char* p = a;
//字符串存储在代码段
char* p = b;
//字符串存储在堆内存上
char* p = (char*)malloc();
return 0 ;
}
总结对比:
字符串数组和字符串有本质的区别。字符数组本身是数组,数组自身带内存空间,可以用来存储东西(所以数组类似于容器);而字符串本身是指针,本身永远
只占4个字节,而且这四个字节还不能用来存储有效数据,所以只能吧有效数据存储在别的地方,然后把地址存储在p中。也就是说字符串数组自己存储这些字符
串需要额外的内存来存储字符,字符串本身只存储真正的那些字符所在的内存空间的首地址。字符串可以存储在栈上、数据段或者堆内存,使用我们使用频率
比字符串数组多。