为什么不指向字母C?
我想倒读我的字符串。我做到了,但我不明白我的代码的两部分是如何工作的为什么不指向字母C?,c,C,我想倒读我的字符串。我做到了,但我不明白我的代码的两部分是如何工作的 char s1[] = "ABC"; printf("%s", s1); size_t len = strlen(s1); printf("\n%d", len); char *t = s1 + len - 1; printf("\n%s\n", t); while (t>=s1) { printf("%c", *t); t = t - 1; } 第一:t如何指向字母C 第二:如何添加变量len,
char s1[] = "ABC";
printf("%s", s1);
size_t len = strlen(s1);
printf("\n%d", len);
char *t = s1 + len - 1;
printf("\n%s\n", t);
while (t>=s1)
{
printf("%c", *t);
t = t - 1;
}
- 第一:
如何指向字母C李>t
- 第二:如何添加变量
,该变量包含整数,而数组包含文本?这是因为指针t使用指针算法添加地址吗李>len
- 这
看起来像char s1[] = "ABC";
0x100 0x101 0x102 0x103 . . . .Assume 0x100 is base address of s1 -------------------------------- | A | B | C | \0 | -------------------------------- s1
这里的0x100 0x101 0x102 0x103 . . . . -------------------------------- | A | B | C | \0 | -------------------------------- s1 t <-- t points here
是字符数组,它指向基址s1
(假设) 我想反向读取字符串 为此,您需要有人指向0x100
位置,即数组的最后一个元素0x102
上面两行代码是编写的。现在看来size_t len = strlen(s1); /* finding length of array s1 i.e it returns 3 here */ char *t = s1 + len - 1; /* (0x100 + 3*1) - 1 i.e char pointer t points to 0x102 */
0x100 0x101 0x102 0x103 . . . .Assume 0x100 is base address of s1 -------------------------------- | A | B | C | \0 | -------------------------------- s1
0x100 0x101 0x102 0x103 . . . . -------------------------------- | A | B | C | \0 | -------------------------------- s1 t <-- t points here
是字符指针,s1
是一个整数变量,因此当您执行指针算术时,它将根据指针所指数据的大小自动递增。例如len
评价为char *t = s1 + len;
t = 0x100 + 3*sizeof(*s1); ==> 0x100 + 3*1 ==> 0x103
在C语言中,数组有点奇怪。At-of-x可以很容易地降级为指向x的指针。例如,如果传递到另一个例程,或者在添加到该例程时。所以你是对的,这是指针算法。(在指针算术中,您可以添加指针和整数以获得指针。)chars1[]=“ABC”代码>
是一个由4个字符组成的数组s1
具有值char[4]
{'A'、'B'、'C'、'\0'}
size\u t len=strlen(s1)代码>
从类型数组“衰减”(读取:自动转换)到类型指针。因此,s1
从4个字符的数组衰减为指向数组第一个字符的指针s1
在遇到空字节分隔符strlen
之前,对字节数进行计数。从'\0'
开始,我们可以计算'A'
,'A'
,'B'
-这就是'C'
C中的指针是普通整数(好的,在大多数体系结构上)。您可以对它们进行加法和减法运算,并使用len=3
将它们转换为整数。但是在不使用强制转换的情况下添加它们将使用“指针算术”,这意味着uintpttr\u t
等于(int*)5+2
5+2*sizeof(int)
,即char*t=s1+len-1代码>
衰减到指向s1
数组中第一个字符的指针,即s1
。我们添加了'A'
,这意味着+(len=3)
指向s1+3
数组中的s1=(char[4]){'A'、'B'、'C'、'\0'}
字节。然后我们减去'\0'
,因此-1
现在将指向t
数组中包含字符s1
的字节'C'
开始:while (t >= s1) { ... *t ... t = t - 1; }
指向s1
'A'
指向t
'C'
而:
大于t
。两个<代码>t-s1=2s1
循环:s1+2=t
等于*t
'C'
减量:
,所以现在t--
将指向t
'B'
而:
大于t
。由onw提供。s1
循环:
等于*t
'B'
减量:然后
,所以现在t--
将指向t
'A'
while:Now
等于thent
。两者都指向数组的第一个字符。s1
循环:
等于*t
'B'
递减:然后
,因此现在t--
将指向数组前面的未知位置。作为指针t
(在大多数体系结构上)是简单的整数,您可以将其作为普通变量进行递减和递增。
而:
现在低于t
。循环终止 注:s1
printf(“\n%d”,len)代码>是未定义的行为并生成。使用
打印printf(“\n%zu”,len)
变量大小\u t
- 您可以使用
说明符打印指针值,并强制转换为void%p
printf(“%p”,(void*)t)
。在C语言中,将指针分配到数组之前的一个元素是未定义的行为。当t=s1-1
时,这种行为发生在循环的结束条件中。在循环时更改为t=t-1
do{..}
采用printf(“\n%d”,len)代码>具有未定义的行为<代码>%d
,而不是int
size\t
有点像ptr+n
我在代码中看不到&ptr[n]
任何软件。@ctrl-alt-delor,我认为Jan意味着对t的赋值,即t=C
指向字母“C”,因为char*t=s1+len-1
。因此,不是字面上的char s1[]=“ABC”
,而是更像t=C
或只是“t指向一个'C'”@ctrl-alt-delor编号。*t='C'
printf说明符接受一个%d
参数int
printf说明符接受%zu
参数。变量参数列表中的所有参数都进行整数提升(即,size\u t
转换为char
-)。非常感谢您需要一点说明,指针算术知道所指向项的大小,并在代码中向指针p添加整数n,创建一个n*sizeof(*p)的指针地址p之后的字节。例如,如果您有一个int
并且ptrToInt是0x100,那么int*ptrToInt
的地址是0x100+sizeof(int)*n;是@Wyck此ptrToInt+n
是正确的。例如,在OP案例中,我在commentsn*sizeof(*p)
中写到,(0x100+3*1)
是3
,而n
是sizeof(*p)
。欢迎使用堆栈溢出家族@JanKlimaszewskinit:1
这里s1是字符数组,指向基地址<