在 C 程序中使用 Struct 和 strlen 进行数学运算
Math with Struct and strlen in C program
谁能解释一下下面的代码片段:strlen(S -> S + 5)
完整的代码在下面,但是如果我用其他数字替换 +5
(-1,0,1,2,3...)
输出有一个我无法辨别的模式,因此我想问这个值是如何确定的。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct S {
char *S;// = 1 BYTE EACH
};
int main(void) {
struct S *S = (struct S *) malloc(sizeof(struct S));//pointer created to Structure S with memory allocated of associated size.
S -> S = "123[=10=]""45678";// Pointer S now pointing to the value S which is holding "123[=10=]""45678" Which has a stop character [=10=]
printf("%s\n", S->S);// The pointer S points to the string S
printf("%c\n\n", S -> S[6]);// gives the value, the character, in the string at [] position
printf("Length %d\n", strlen(S -> S)); // = 3 because the "[=10=] stop character stops the count (0,1,2,3)
printf("Length + 5 = %d\n", strlen(S -> S+ 5)); // = total of 5
printf("%d", strlen(S -> S + 5) + S -> S[3]);
free(S);
return 0;
}
S -> S + 5
是字符串指针在结构内的偏移量(距离起始位置 5 个字符),因此该子字符串的长度会有所不同。
如果您使用 S -> S - 1 那么您已经超出了字符串的开头,任何事情都可能发生。
如果您确实想要 Length + 5(正如您的打印语句所建议的那样),那么您需要将 +5 移出括号 :)
printf("Length + 5 = %d\n", strlen(S -> S) + 5); // = total of 5
if I replace +5 with other numbers (-1,0,1,2,3...) the output has a
pattern I cannot discern and therefore I am asking how the value is
determined.
对于指针指向:
S -> S = "123[=10=]""45678"
这些是 strlen
的结果:
// reaching outside the string boundary, Undefined Behaviour
strlen(S -> S-1) // UB: crash, 0 or 4
// Equivalent to:
printf("%d\n", strlen(S -> S)); // 3 = strlen("123");
printf("%d\n", strlen(S -> S+1)); // 2 = strlen("23");
printf("%d\n", strlen(S -> S+2)); // 1 = strlen("3");
printf("%d\n", strlen(S -> S+3)); // 0 = strlen("");
printf("%d\n", strlen(S -> S+4)); // 5 = strlen("45678");
printf("%d\n", strlen(S -> S+5)); // 4 = strlen("5678");
注:
size_t strlen ( const char * str );
Returns C
字符串的长度 str
.
C
字符串的长度由终止符 null-character 决定。
C
字符串与字符串开头和 terminating null character
之间的字符数一样长(不包括终止空字符本身)。 terminating null character
是 '[=20=]'
。
这里要理解的重要一点是
S->S = "123[=10=]""45678";
首先,->
是指针的成员访问运算符。这里的诀窍是
这个:
"123[=11=]""45678"
在 C 中,当您将两个字符串文字写在一起时,它们会连接成一个。
例如
const char *txt = "Hello " "world";
puts(txt);
将打印 Hello world
。这与做
是一样的
const char *txt = "Hello world";
puts(txt);
现在"123[=22=]""45678"
正在使用字符串文字连接,并且还使用了一个技巧来存储
两个单独的字符串一次。字符串以 '[=23=]'
结尾,通常你不需要
使用字符串时需要明确使用 '[=23=]'
终止字节
文字,编译器会为你做,但你可以用它来存储多个
字符串一次。 S->S
的记忆是这样的
index 0 1 2 3 4 5 6 7 8 9
+-----+-----+-----+------+-----+-----+-----+-----+-----+------+
| '1' | '2' | '3' | '[=14=]' | '4' | '5' | '6' | '7' | '8' | '[=14=]' |
+-----+-----+-----+------+-----+-----+-----+-----+-----+------+
第二个要理解的重要事情是:
S -> S + 5
这相当于
&(S->S[5])
S->S + 5
是指针运算,就像常规运算一样
不同之处在于编译器会处理对象的大小。如果你有:
int arr[] = { 99, 11, 33, 55 };
而你想获取数组第二个元素1的地址,可以这样做:
&(arr[1])
。但是你也可以使用指针算法和等价物
语句将是 arr+1
。编译器负责 int
的大小
当它添加偏移量时(即 1*sizeof(int)
)。
上面的代码同时使用了这两种东西,'[=23=]'
-终止字节的技巧和
指针算术。这就是为什么当你这样做时
printf("%s\n", S->S);
printf
将开始一个字符一个字符地打印,直到找到
'[=23=]'
-终止字节。 123
打印在屏幕上。但如你所见,那里
在 '[=23=]'
终止字节之后有更多字节。所以如果你这样做
printf("%s\n", S->S + 4);
它将打印 45678
.
注释
1在C中,你从0开始计数,所以第一个元素在arr[0]
,
第二个 arr[1]
,等等
谁能解释一下下面的代码片段:strlen(S -> S + 5)
完整的代码在下面,但是如果我用其他数字替换 +5
(-1,0,1,2,3...)
输出有一个我无法辨别的模式,因此我想问这个值是如何确定的。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct S {
char *S;// = 1 BYTE EACH
};
int main(void) {
struct S *S = (struct S *) malloc(sizeof(struct S));//pointer created to Structure S with memory allocated of associated size.
S -> S = "123[=10=]""45678";// Pointer S now pointing to the value S which is holding "123[=10=]""45678" Which has a stop character [=10=]
printf("%s\n", S->S);// The pointer S points to the string S
printf("%c\n\n", S -> S[6]);// gives the value, the character, in the string at [] position
printf("Length %d\n", strlen(S -> S)); // = 3 because the "[=10=] stop character stops the count (0,1,2,3)
printf("Length + 5 = %d\n", strlen(S -> S+ 5)); // = total of 5
printf("%d", strlen(S -> S + 5) + S -> S[3]);
free(S);
return 0;
}
S -> S + 5
是字符串指针在结构内的偏移量(距离起始位置 5 个字符),因此该子字符串的长度会有所不同。
如果您使用 S -> S - 1 那么您已经超出了字符串的开头,任何事情都可能发生。
如果您确实想要 Length + 5(正如您的打印语句所建议的那样),那么您需要将 +5 移出括号 :)
printf("Length + 5 = %d\n", strlen(S -> S) + 5); // = total of 5
if I replace +5 with other numbers (-1,0,1,2,3...) the output has a pattern I cannot discern and therefore I am asking how the value is determined.
对于指针指向:
S -> S = "123[=10=]""45678"
这些是 strlen
的结果:
// reaching outside the string boundary, Undefined Behaviour
strlen(S -> S-1) // UB: crash, 0 or 4
// Equivalent to:
printf("%d\n", strlen(S -> S)); // 3 = strlen("123");
printf("%d\n", strlen(S -> S+1)); // 2 = strlen("23");
printf("%d\n", strlen(S -> S+2)); // 1 = strlen("3");
printf("%d\n", strlen(S -> S+3)); // 0 = strlen("");
printf("%d\n", strlen(S -> S+4)); // 5 = strlen("45678");
printf("%d\n", strlen(S -> S+5)); // 4 = strlen("5678");
注:
size_t strlen ( const char * str );
Returns C
字符串的长度 str
.
C
字符串的长度由终止符 null-character 决定。
C
字符串与字符串开头和 terminating null character
之间的字符数一样长(不包括终止空字符本身)。 terminating null character
是 '[=20=]'
。
这里要理解的重要一点是
S->S = "123[=10=]""45678";
首先,->
是指针的成员访问运算符。这里的诀窍是
这个:
"123[=11=]""45678"
在 C 中,当您将两个字符串文字写在一起时,它们会连接成一个。 例如
const char *txt = "Hello " "world";
puts(txt);
将打印 Hello world
。这与做
const char *txt = "Hello world";
puts(txt);
现在"123[=22=]""45678"
正在使用字符串文字连接,并且还使用了一个技巧来存储
两个单独的字符串一次。字符串以 '[=23=]'
结尾,通常你不需要
使用字符串时需要明确使用 '[=23=]'
终止字节
文字,编译器会为你做,但你可以用它来存储多个
字符串一次。 S->S
的记忆是这样的
index 0 1 2 3 4 5 6 7 8 9
+-----+-----+-----+------+-----+-----+-----+-----+-----+------+
| '1' | '2' | '3' | '[=14=]' | '4' | '5' | '6' | '7' | '8' | '[=14=]' |
+-----+-----+-----+------+-----+-----+-----+-----+-----+------+
第二个要理解的重要事情是:
S -> S + 5
这相当于
&(S->S[5])
S->S + 5
是指针运算,就像常规运算一样
不同之处在于编译器会处理对象的大小。如果你有:
int arr[] = { 99, 11, 33, 55 };
而你想获取数组第二个元素1的地址,可以这样做:
&(arr[1])
。但是你也可以使用指针算法和等价物
语句将是 arr+1
。编译器负责 int
的大小
当它添加偏移量时(即 1*sizeof(int)
)。
上面的代码同时使用了这两种东西,'[=23=]'
-终止字节的技巧和
指针算术。这就是为什么当你这样做时
printf("%s\n", S->S);
printf
将开始一个字符一个字符地打印,直到找到
'[=23=]'
-终止字节。 123
打印在屏幕上。但如你所见,那里
在 '[=23=]'
终止字节之后有更多字节。所以如果你这样做
printf("%s\n", S->S + 4);
它将打印 45678
.
注释
1在C中,你从0开始计数,所以第一个元素在arr[0]
,
第二个 arr[1]
,等等