一、sizeof与strlen区别
sizeof是关键字,参数可以是各种数据(包括函数,类型,对象,数组,指针……)用于计算数据所占字节大小
strlen是函数,参数类型必须是字符型指针(char *),用于计算字符串,从字符串的第一个地址开始遍历,直到遇到‘\0’停止
二、sizeof(字符型数组)、strlen(字符型数组)
sizeof(字符型数组):
int main() { char arr[] = { 'a','b','c','d','e','f' }; printf("%zd\n", sizeof(arr));//6 此处arr代表整个数组,整个数组6个字符,总字节数为6 printf("%zd\n", sizeof(arr + 0));//4/8 此处arr+0为首元素地址,地址的大小是4或8个字节 printf("%zd\n", sizeof(*arr));//1 此处*arr是首元素,即字符a,大小为1字节 printf("%zd\n", sizeof(arr[1]));//1 此处arr[1]是字符b,大小为1字节 printf("%zd\n", sizeof(&arr));//4/8 此处&arr为整个字符数组的地址,地址的大小为4或8个字节 printf("%zd\n", sizeof(&arr + 1));//4/8 此处&arr+1为整个字符数组的地址+1,仍然是地址,地址的大小是4或8个字节 printf("%zd\n", sizeof(&arr[0] + 1));//4/8 此处&arr[0]+1是字符a的地址+1,仍然是地址,地址的带笑傲是4或8个字节 return 0; }
strlen(字符型数组):
int main() { char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", strlen(arr));//随机值 此处arr代表首字符地址,也是字符指针,符合参数要求,strlen遇到\0停止,数组中没有\0,因此为随机值 printf("%d\n", strlen(arr+0));//随机值 此处arr+0代表首字符地址+0,仍然是首字符地址,也是字符指针,符合参数要求,strlen遇到\0停止,数组中没有\0,因此为随机值 //printf("%d\n", strlen(*arr));//报错 此处*arr是字符a,不符合参数要求 //(在strlen函数的角度来看,函数会将传入的任何数据,都当作为字符指针,也就是地址,字符a的ASCII码值为97,97作为地址直接访问,该行为是非法的,报错) // printf("%d\n", strlen(arr[1]));//报错 此处arr[1]是字符b,不符合参数要求 //(在strlen函数的角度来看,函数会将传入的任何数据,都当作为字符指针,也就是地址,字符a的ASCII码值为97,97作为地址直接访问,该行为是非法的,报错) printf("%d\n", strlen(&arr));//随机值 此处&arr是整个字符数组的地址,符合参数要求,但是不知何时会遇到\0,因此为随机值 printf("%d\n", strlen(&arr + 1));//随机值 此处&arr是整个数组的地址+1,仍然是地址,符合参数要求,但是不知何时会遇到\0,因此是随机值 printf("%d\n", strlen(&arr[0] + 1));//随机值 此处&arr[0]+1是字符a的地址+1,仍然是地址,符合参数要求,但是不知何时会遇到\0,因此是随机值 return 0; }
三、sizeof(字符串)、strlen(字符串)
sizeof(字符串):
int main() { char arr[] = "abcdef"; printf("%zd\n", sizeof(arr));//7 此处arr是整个数组(字符串),字符串中除了abcdef还有末尾的\0,因此一共7个字节 printf("%zd\n", sizeof(arr + 0));//4/8 此处arr+0是首元素地址+0,结果仍然是首元素地址,地址占4/8个字节 printf("%zd\n", sizeof(*arr));//1 此处*arr是字符a,大小为1个字节 printf("%zd\n", sizeof(arr[1]));//1 此处arr[1]是字符a,大小为1个字节 printf("%zd\n", sizeof(&arr));//4/8 此处&arr是整个字符串的地址,地址的大小是4/8个字节 printf("%zd\n", sizeof(&arr + 1));//4/8 此处&arr+1是整个个字符串的地址+1,仍然是地址,地址的大小是4/8个字节 printf("%zd\n", sizeof(&arr[0] + 1));//4/8 此处&arr[0]+1是字符a的地址+1,仍然是地址,地址的大小是4/8个字节 return 0; }
strlen(字符串):
int main() { char arr[] = "abcdef"; printf("%d\n", strlen(arr));//6 此处arr是首字符地址,即字符a的地址,符合strlen函数参数要求,从起始地址开始遍历遇到\0停止,一共6个字节 printf("%d\n", strlen(arr + 0));//6 此处arr+0是首字符地址+0,结果仍然是首字符a的地址,符合strlen函数参数要求,从起始地址开始遍历遇到\0停止,一共6个字节 //printf("%d\n", strlen(*arr));//报错 此处*arr是字符a,不符合strlen函数参数要求 // 在strlen函数的角度来看,它会将任何传给它的数据都当作为地址,字符a的ASCII码值为97,97作为地址直接访问,一定是非法的 //printf("%d\n", strlen(arr[1]));//报错 此处arr[1]是字符b,不符合strlen函数参数要求 // 在strlen函数的角度来看,它会将任何传给它的数据都当作为地址,字符b的ASCII码值为98,98作为地址直接访问,一定是非法的 printf("%d\n", strlen(&arr));//6 此处&arr是取整个字符串的地址,符合strlen函数参数要求,整个字符串的地址和首字符地址相同,因此strlen函数会将首字符地址作为起始地址,从此处开始遍历,一共6个字符,共6个字节 printf("%d\n", strlen(&arr + 1));//随机值 此处&arr+1是整个字符串的地址+1,结果是\0后面的地址,strlen函数将这个地址作为起始地址,从\0后面开始遍历,无法确定什么时候会再次遇到\0,因此为随机值 printf("%d\n", strlen(&arr[0] + 1));//5 此处&arr[0]+1是字符a的地址+1,结果是字符b的地址,那么strlen函数将把字符b的地址当做起始地址,从此处开始遍历,一共5个字符,共5个字节 return 0; }
四、sizeof(字符串指针)、strlen(字符串指针)
sizeof(字符串指针):
int main() { char* p = "abcdef";//字符串也是一个表达式,其值是首字符的地址,即字符a的地址 printf("%d\n", sizeof(p));//4/8 此处p是字符a的地址,地址的大小是4或8字节 printf("%d\n", sizeof(p + 1));//4/8 此处p+1是 字符a的地址+1,结果仍然是地址,地址的大小是4或8字节 printf("%d\n", sizeof(*p));//1 此处*p是字符a,字符a的大小是1字节 printf("%d\n", sizeof(p[0]));//1 此处p[0]是字符a,字符a的大小是1字节 printf("%d\n", sizeof(&p));//4/8 此处&p取的是指针变量p的地址,地址的大小是4或8字节 printf("%d\n", sizeof(&p + 1));//4/8 此处&p+1是指针变量p的地址+1,结果仍然是地址,地址的大小是4或8字节 printf("%d\n", sizeof(&p[0] + 1));//4/8 此处&p[0]+1是字符a的地址+1,结果是字符b的地址,地址的大小是4或8字节 return 0; }
strlen(字符串指针):
int main() { char* p = "abcdef";//字符串也是一个表达式,其值是首字符的地址,即字符a的地址 printf("%d\n", strlen(p));//6 此处p是字符a的地址,符合strlen函数参数要求,将字符a的地址作为起始地址向后遍历,直到遇到\0停止,一共6个字符 printf("%d\n", strlen(p + 1));//5 此处p+1是字符a的地址+1,结果是字符b的地址,符合strlen函数参数要求,将字符b的地址作为起始地址向后遍历,直到遇到\0停止,一共5个字符 //printf("%d\n", strlen(*p));//报错 此处*p是字符a,不符合strlen函数参数要求,报错 //printf("%d\n", strlen(p[0]));//报错,此处p[0]是字符a,不符合strlen函数参数的要求 printf("%d\n", strlen(&p));//随机值 此处&p是取指针变量p的地址,将p的地址作为起始地址向后遍历,但不知道何时回遇到\0,因此为随机值 printf("%d\n", strlen(&p + 1));//随机值 此处&p+1是指针变量p的地址+1,将次地址作为起始地址向后遍历,但不知道何时会遇到\0,因此为随机值 printf("%d\n", strlen(&p[0] + 1));//5 此处&p[0]+1是字符a的地址+1,结果是字符b的地址,将字符b的地址作为起始地址向后遍历,直到遇到\0停止,一共5个字符 return 0; }