我对strlen()
进行了一些研究并提出了一个问题。
假设我有一个50
元素数组和一个指向第一个元素的指针,意思是:
char A[50],*x;
gets(A);
x=&A[0];
根据我的理解,strlen(x)
应该给我字符串的长度。
我的问题是,当我增加x
时会发生什么?
答案 0 :(得分:7)
首先,对于题外话表示抱歉,但请不要使用过时的gets()
功能。请改用fgets
。
在回答您的问题时,如果x
是指向有效非空字符串的指针,则strlen(x+1)
将始终等于strlen(x) - 1
。
假设我们有这个字符串,x指向它:
+---+---+---+---+---+---+
a: | H | e | l | l | o | \0|
+---+---+---+---+---+---+
^
|
+---|---+
x: | * |
+-------+
即,x
指向字符串的第一个字符。现在,strlen
所做的只是从指向字符开始并计算字符,直到它找到终止'\0'
。
因此,如果我们增加x
,现在它指向'e'
(也就是说,它指向字符串" ello"),如下所示:
+---+---+---+---+---+---+
a: | H | e | l | l | o | \0|
+---+---+---+---+---+---+
^
|
/
/
/
|
+---|---+
x: | * |
+-------+
因此strlen
的长度会减少一个。
脚注:我提醒过一个我不止一次遇到的有趣的错误。当您使用malloc
为字符串分配空间时,您始终必须记住为终止'\0'
包含空格。不要这样做:
char *p = malloc(strlen(str + 1));
我的同事曾经这样做了一次(不,真的,这是一个同事,而不是我!),并且很难找到追踪,因为很容易看到错误的代码并且看不到它不是
char *p = malloc(strlen(str) + 1);
应该是这样的。
答案 1 :(得分:1)
它将比之前的回报少。在C中,字符串只是指向第一个字符的内存地址的指针,因此如果您的字符串是
"ABCDEF"
如果你增加指针,而不是指向' A'它将指向' B',所以新字符串是
"BCDEF"
strlen("BCDEF")
为5,而strlen("ABCDEF")
为6。
答案 2 :(得分:0)
它给你一个更小的。 x += i
大致相当于伪代码x = substr(x, i)
。 (请注意,如果i
超过x
的长度,则会发生不好的事情。)
答案 3 :(得分:0)
您的代码:
char A[50],*x;
gets(A);
x=&A[0];
strlen(x)
应该给我字符串的长度当我增加
x?
时会发生什么strlen(x
)现在给我的相同 如前所述的价值或较小的价值,若然,为何会发生?
答案比人们想象的要复杂得多。答案是:取决于它!
通过声明A[50]
编译器将在堆栈上分配50
个字节,这些字节未初始化为任何值。
让我们说A
的内容恰好是
A[50] = { '5', '1', '2', '3', 0 /*.............*/ };
然后考虑两种情况:
a)用户输入:<enter>
b)用户输入:'7'<enter>
数组A
的内容将用于不同的
a) { 0, '1', '2', '3', 0 /*.............*/ };
b) { '7', 0, '2', '3', 0 /*.............*/ };
strlen
的结果可能让您感到惊讶:
这是测试程序和结果:
#include <stdio.h>
#include <string.h>
int main(void)
{
char A[50] = { '5', '1', '2', '3', 0 };
char *x;
gets(A);
x=&A[0];
for (int i=0; i < 5; i++)
printf("%d: %02X\n", i, A[i]);
printf("strlen(x) = %zu\n", strlen(x));
printf("strlen(x+1)= %zu\n", strlen(x+1));
return 0;
}
测试:
<enter>
0: 00
1: 31
2: 32
3: 33
4: 00
strlen(x) = 0
strlen(x+1)= 3
7<enter>
0: 37
1: 00
2: 32
3: 33
4: 00
strlen(x) = 1
strlen(x+1)= 0
如您所知strlen
计算从起始位置到遇到第一个'\0'
的字符数。如果起始字节等于'\0'
而不是strlen(x)
=
0
。
对于方案 a) strlen(x)
,strlen(x+1)
将为0
和3
对于方案 b) strlen(x)
,strlen(x+1)
将为1
和0
。
请不要使用gets
(Why is the gets function so dangerous that it should not be used?)并注意我以十六进制格式打印ASCII
个字符,例如'2' = 0x32
。