首先,关于数组初始化我将它分为三种:
- 不完全初始化:
int arr[5]={1,2,3}
剩下的元素默认为0; - 未指定数组长度:
int arr[]={1,2,3,4}
- 字符串形式初始化:
char arr[]='abcd'
可能其中有两种初始化容易搞混,一是字符数组:char arr[4]={'a','b','c','d'};一是初始化为字符串的数组:char arr[4]='abcd'。
其实,第二种以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写 "abc",那么编译器帮你存储的是"abc/0",char arr[]="abc"实际上存储的是 char arr[]={'a','b','c','\0'}',还是属于字符数组。
弄清楚char arr[4]={'a','b','c','d'};char arr[4]='abcd'的区别后, 接下来讲讲sizeof和strlen的作用和区别。
sizeof()”运算符求的是字符数组的长度,而不是字符串长度。只跟你给该字符串数组定义了多大空间有关,而跟字符串是否结束无关.如果遇到字符串,编译时会自动在末尾增加一个 null 字符,即char arr1[]='abc\0'。
strlen:用来计算以’\0’结尾的字符串长度的函数。它并不是计算内存大小,仅计算字符串从开端到’\0’结尾字符的个数(不包含’\0’)。
举个栗子:
1.1 一维数组
1.1.1 sizeof()问题
(1)整形数组
(2)字符数组
(3)初始化为字符串的数组
总结:
一个指针(或者说数组/数组元素地址)的大小在32位平台是4,64位平台是8。原因:在32位cpu上,指针能够存储这2^32次个地址就需要4个字节。(1字节=8位),64位同理;
1. 求地址的大小(数首元素地址,下一个元素地址,整个数组地址,下一个数组地址...)都是4/8字节。
2. 求元素的大小,就看是整形还是字符,整形4个字节,字符型1个字节。
3. 不分char,int等类型,只要是求地址大小,都是4/8。
1.1.2 strlen()问题
(1)字符数组
(2)初始化为字符串的数组
总结:
C 库函数 size_t strlen(const char \*str) **接收的类型是地址char \***,从给定地址**往后寻找,从给定直到空结束字符**(不包括空结束字符),然后返回字符串 str 的长度。
如果传给strlen()的参数是未可知范围的地址,strlen会**一直走下去,直到遇到"\0"为止**,‘\0’出现位置是未知的,结果就是随机值(如char arr[]={'a','b','c'},strlen(arr) 随机);
如果传给strlen()的地址后面会出现'\0',那么就返回字符串的长度(char arr[]=“abc”,strlen(arr) =6);
如果传给strlen的参数是一个具体的元素而不是一个地址,这样会把字符a的ascii码值97传给strlen函数,而此函数是访问不到这个地址的,因此会程序中断。(char arr[]={'a','b','c'},strlen(*arr) 报错)。
以上。