【C指针】深入理解指针(最终篇)数组&&指针&&指针运算题解析(一)2:https://developer.aliyun.com/article/1474745
💮 💮 💮 strlen
计算字符串
数组
int main() { char arr[] = "abcdef"; printf("%zd\n", strlen(arr));//arr也是数组首元素的地址 6 printf("%zd\n", strlen(arr + 0));//arr + 0是数组首元素的地址,6 //printf("%zd\n", strlen(*arr));//?传递是'a'-97,//err //printf("%zd\n", strlen(arr[1]));//?'b'-98//err printf("%zd\n", strlen(&arr));//6, &arr虽然是数组的地址,但是也是指向数组的起始位置 printf("%zd\n", strlen(&arr + 1));//随机值 printf("%zd\n", strlen(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 - 5 return 0; }
printf(“%zd\n”, strlen(arr));// 6
arr也是数组首元素的地址,从a地址开始,直到\0停止,并且\0不计算在内。
printf(“%zd\n”, strlen(arr + 0));//6
arr + 0是数组首元素的地址,也是从a地址开始,直到\0停止,并且\0不计算在内。
printf(“%zd\n”, strlen(*arr));//访问冲突
*arr传递是'a'-97,字符a对应的ASCII码值为97,而97为内存空间里的一个地址,不属于数组arr的空间,那么就会访问冲突
printf(“%zd\n”, strlen(arr[1]));//访问冲突
注意:
(同样在字符串中,该结论同样适用)arr[1],因为arr[1]取出来的是字符'b',字符'b'的ASCII码值98同样是一个地址,但不是字符串起始地址。
传递*arr或arr[1]给strlen,strlen是无法直接访问这些地址处的内存空间的,因为这些地址都不属于strlen的作用域。
而arr名本身,以及arr地址&arr,都是字符串的起始地址,所以可以作为strlen函数的参数。
小结:
strlen的参数必须是字符串的起始地址,才能正确计算长度。
arr
和arr+0
都是数组首元素的地址,传给strlen
计算长度都是6*arr
和arr[1]
访问到的是字符'a'
和'b'
,传给strlen
会报错&arr
虽然是数组的地址,但也指向数组第一个元素,所以strlen(&arr)
可以正确计算长度&arr+1
会指向字符串的其他位置,传给strlen
会产生随机值或者错误结果
🏄 指针变量
🏄🏄 sizeof
计算指针变量
int main() { char* p = "abcdef"; printf("%zd\n", sizeof(p)); printf("%zd\n", sizeof(p + 1)); printf("%zd\n", sizeof(*p)); printf("%zd\n", sizeof(p[0])); printf("%zd\n", sizeof(&p)); printf("%zd\n", sizeof(&p + 1)); printf("%zd\n", sizeof(&p[0] + 1)); return 0; }
- printf(“%zd\n”, sizeof§);//4/8
p
是char*
类型的指针变量,存放的是a
的地址,是地址,那就是4或8字节。
2.printf(“%zd\n”, sizeof(p + 1));4/8
p+1
计算的是'b'
字符的地址,依然是地址,大小也是4/8个字节。
printf(“%zd\n”, sizeof(*p));// 1字节
p
访问的是'a'
字符,sizeof
计算的是字符类型大小,是1
字节。
printf(“%zd\n”, sizeof(p[0]));//1字节
p[0]等价于*(p+0),(p+0)也等价pp[0]-- > *(p+0) - >*p也是访问'a'字符是1字节。
printf(“%zd\n”, sizeof(&p));//4/8
&p是p指针变量的地址,是地址,大小也是4/8个字节。
printf(“%zd\n”, sizeof(&p + 1));//4/8个字节
&p + 1是指向p指针变量后面的空间,也是地址,是4/8个字节
- printf(“%zd\n”, sizeof(&p[0] + 1));//4/8
&p[0]+1
访问'b'
字符的地址,是地址就是4/8
个字节。
小结:
sizeof运算符计算:
- 指针变量时,计算的是指针变量本身占用的内存空间,4或8字节。
- 字符或整数类型时,计算的是该类型变量占用的内存大小,如char是1字节。
- 地址时,地址也是指针类型,计算的还是指针类型占用的内存大小,4或8字节。
🏄🏄🏄strlen
计算指针变量
int main() { char* p = "abcdef"; printf("%zd\n", strlen(p)); printf("%zd\n", strlen(p + 1)); //printf("%zd\n", strlen(*p)); //printf("%zd\n", strlen(p[0])); printf("%zd\n", strlen(&p)); printf("%zd\n", strlen(&p + 1)); printf("%zd\n", strlen(&p[0] + 1)); return 0; }
运行该代码,打印strlen的结果解释:
printf(“%zd\n”, strlen(p ));//6
因为p指向字符串"abcdef"的首地址,strlen计算字符串长度就是6。
printf(“%zd\n”, strlen(p + 1));//5
结果是5,因为p+1指向从'b'开始的字符串,长度是5。
printf(“%zd\n”, strlen(*p));//访问冲突
*p是'a'字符, size_t strlen ( const char * str );strlen接受一个地址,‘a’`字符不是地址,如果是的话,那又是访问ASCII码值然后报错。
printf(“%zd\n”, strlen(p[0])); //访问冲突
同理,p[0]也是字符,不能用strlen。
printf(“%zd\n”, strlen(&p));随机值
&p是指针p的地址,strlen无法识别,结果是随机值。
printf(“%zd\n”, strlen(&p + 1))随机值;
同理,&p+1找的是p后面地址,然后开始在p后面不断找\0,也是随机值。
- printf(“%zd\n”, strlen(&p[0] + 1));//5
因为&p[0]+1
指向从'b'
开始的字符串。
strlen
只能计算字符串常量或以'\0'
结束的字符串长度,其他情况如字符,地址都无法识别长度,可能导致随机值或报错。
3️⃣ 总结
本小节我们学习了sizeof和strlen对一维字符数组,字符串数组和指针变量进行练习,我们应该对指针有了更多的理解,但是他们都离不开我们以下的知识点。sizeof用于计算变量或类型占用的内存空间(以字节为单位),它是编译期就能确定的常量。
strlen用于计算字符串长度,但仅限于以'\0'作为字符串结束标志的字符串。它需要在运行期扫描字符串计算长度,他接收地址,不能接收数值,否则就会访问编译器就会报错,造成访问冲突。
【C指针】深入理解指针(最终篇)数组&&指针&&指针运算题解析(一)3