在正式开始之前想先介绍几点字符串的相关知识。
char arr[ ][ ] = {'a','b','c','d','e','f'} 括号内的字符串末尾没有'\0'所以这个字符串在计算长度的时候是停不住的。
char arr[ ][ ] = "abcdef" 引号内的字符串在末尾是有'\0'存在的
sizeof:
1:计算整个数组的大小,单位为字节。
2:只有两种形式出现在括号内表示整个数组,其余的任何形式均表示首元素地址
1>sizeof(数组名),数组名单独放在括号内,计算的是整个数组的大小,单位为字节。
2>sizeof(&数组名 ),取地址数组名取出的是整个数组的地址,表示整个数组。
3>sizeof不进行运算,如下例:
short s = 3;
int a = 10;
printf("%d", sizeof(s = a+5)); //short类型为两个字节,所以输出结果为2
printf("%d", s); //不进行运算,所以输出结果为3
strlen:
它从内存中的某个位置(可以是开头、中间或是某个不确定位置)开始扫描,知道碰到第一个字符串的'\0'停止,然后返回计数器值(长度不包括'\0').值得注意的是它括号内需要传送一个地址。
关于地址:
地址的大小是一定的。若电脑是32位的,则地址大小为4个字节;若电脑为64位的,则地址大小为8个字节。
下面给予几组练习:
int a[ ] = {1,2,3,4}
sizeof(a)//16 4个元素均为整形,每个整型元素为4个字节,所以结果为4*4=16
sizeof(a+0)//4 a+0为首元素地址电脑为32位时地址永远为4个字节,电脑为64位是地址永远为8个字节
sizeof(*a)//4 首元素地址,*进行解引用操作找到'1'
sizeof(a+1)//4 第二个元素地址,但仍为地址
sizeof(a[1])//4 第二个元素地址,但仍为地址
sizeof(&a)//4 取地址仍为地址
sizeof(*&a)//16 &a为数组地址,*&a拿到的是整个数组的地址
sizeof(*a+1)//4 *a为地址,加1后跳过16个字节
sizeof(*a[0])//4
sizeof(*a[0]+1)//4
arr与arr+1之间差4个字节;arr[0]与arr[0]+1之间差4个字节;&arr与&arr+1之间差16个字节。
char a[ ] = "abcdef"
sizeof(arr)//7 字符串后面存在'\0'所以字符串可以停下来,char为字符型,每个字符型为1个字节大小
sizeof(arr+0)//4 为首元素地址
sizeof(*arr)//1 解引用找到第一个元素为a,该字符大小为1个字节
sizeof(arr[1])//1 第二个元素b字符大小为1字节
sizeof(&arr)//4 为数组地址
sizeof(&arr+1)//4 跳过现在的数组的'\0'的下一个数组的地址
sizeof(&arr[0]+1)//4 为一个地址
char arr[ ] = {'a','b','c','d','e','f'}
strlen(arr)//随机数 因为字符串后面不存在'\0'所以它停不住就会一直往后计数
strlen(arr+0)//随机数
strlen(*arr)//error strlen需要的是一个地址,给他传一个元素没有用
strlen(arr[1])//error strlen需要的是一个地址,给他传一个元素没有用
strlen(&arr)//随机数
strlen(&arr+1)//随机数
strlen(&arr[0]+1)//随机数
'a' 'b' 'c' 'd' 'e' 'f' 'a'
| | |
&arr开始计数 | |
&arr[0]+1开始计数 |
&arr+1开始计数
int a[3][4] = {0}
sizeof(a)//48 数组的总大小为(3*4)*4
sizeof(a[0][0])//4 第一行第一列元素为4个字节
sizeof(a[0])//16 第一行数组的数组名有4个元素,字节大小为4*4
sizeof(a[0]+1)//4 a[0]没有单独放在括号内,所以代表首元素地址。为4个字节大小
sizeof(a+1)//4 a为单独放在括号内,所以降级成为首元素地址。第一行地址加1后变为第二行元素地址
sizeof(&a[0]+1)//4 &a[0]取出第一行元素地址,加以后变为第二行元素地址
sizeof(*a)//16 将级为第一行元素地址,第一行解引用后大小为4*4=16
sizeof(a[3])//1 sizeof不进行访问,所以a[3]的效果与a[1]、a[2]相同,为行元素的大小为4*4=16
char *p = "abcdef"
sizeof(p)//4 指针,指向的是地址
sizeof(*p)//1 *p为首元素a,大小为一个字节
sizeof(&p)//4 地址类型为char **p
sizeof(&p[0]+1)//4 指向的是b的地址,但仍为地址
sizeof(p+1)//4 指向b的地址
sizeof(p[0])//1 p+0解引用a,字符大小为一个字节
sizeof(&p+1)//4 +1跳过一个指针变量的大小
strlen(p)//6 字符串末尾存在'\0'
strlen(*p)//error 为首元素,不是地址
strlen(&p)//随机数
strlen(&p[0]+1)//5
strlen(p+1)//5
strlen(p[0])//error 首元素,不是地址
strlen(&p+1)//随机数