1
#include <stdio.h>

#define slice(bare_string,start_index) #bare_string+start_index
#define arcane_slice(bare_string,start_index) "ARCANE" #bare_string+start_index

int main(){
    printf("slice(FIRSTA,0)==> `%s`\n",slice(FIRSTA,0));
    printf("slice(SECOND,2)==> `%s`\n",slice(SECOND,2));
    printf("slice(THIRDA,5)==> `%s`\n",slice(THIRDA,5));
    printf("slice(FOURTH,6)==> `%s`\n",slice(FOURTH,6));
    printf("slice(FIFTHA,7)==> `%s`\n",slice(FIFTHA,7));
    printf("arcane_slice(FIRSTA,0)==> `%s`\n",arcane_slice(FIRST,0));
    printf("arcane_slice(SECOND,2)==> `%s`\n",arcane_slice(SECOND,2));
    printf("arcane_slice(THIRDA,5)==> `%s`\n",arcane_slice(THIRDA,5));
    printf("arcane_slice(FOURTH,6)==> `%s`\n",arcane_slice(FOURTH,6));
    printf("arcane_slice(FIFTHA,7)==> `%s`\n",arcane_slice(FIFTHA,7));
    return 0;
}

输出:

slice(FIRSTA,0)==> `FIRSTA`
slice(SECOND,2)==> `COND`
slice(THIRDA,5)==> `A`
slice(FOURTH,6)==> ``
slice(FIFTHA,7)==> `slice(FIFTHA,7)==> `%s`
`
arcane_slice(FIRSTA,0)==> `ARCANEFIRST`
arcane_slice(SECOND,2)==> `CANESECOND`
arcane_slice(THIRDA,5)==> `ETHIRDA`
arcane_slice(FOURTH,6)==> `FOURTH`
arcane_slice(FIFTHA,7)==> `IFTHA`

我有上面需要帮助的 C 代码。我从应该从传递的索引“切片” 到字符串末尾的
类似函数的宏中得到奇怪的行为。它不是真正意义上的切片,而是 从某个点传递一个指针,从该 地址开始打印。我设法弄清楚在字符串 中首先连接然后“切片”。我还发现当 等于 6时从空字节开始打印,这就是 你得到“空”字符串的原因。奇怪的部分是什么时候是 7。它将第一个参数打印 到(interpolator string) 并与两者中传递的裸字符串连接。slice

printf
arcane_slice
start_index
printf
start_index
printf
arcane_sliceslice(如输出中的第 5 行和第 10 行所示)
为什么会这样?
我最疯狂的猜测是,当start_index超过字符串的长度时,
指针指向程序地址空间中数据段的开头。但是
你可以用“为什么它不开始打印FIRSTA” 来反驳它

4

3 回答 3

1

不是任何“数据段”,堆栈。这就是我所记得的:当 C 调用一个函数时,它首先将数据放入堆栈,首先是变量参数,然后是格式,所有这些都是按顺序分配给您的文本的内存地址。在该内存块中,最后一个参数(c-string)首先出现,第一个参数最后出现,因此:

记忆:

"FIFTHA\0slice(FIFTHA,7)==> `%s`\n\0"

论据:

<pointer-to-"FIFTHA"> <pointer-to-"slice...">

由于您过度增加了第一个字符,因此它也会跳过'\0'字符并指向格式。

尝试使用更多占位符进行实验,例如

 printf("1: %s, 2: %s\n", slice(FIFTHA,7), slice(FIFTHA,6));
于 2013-08-31T11:30:29.680 回答
0
 slice(bare_string,start_index) #bare_string+start_index  

您正在传递 astringbare_string存储您传递的字符串的起始地址,然后返回更改的指针位置,即bare_string+start_index

char str[6]="Hello";

char *ptr =str;

printf("%s\n",str);//prints hello

printf("%s\n",str+1);//prints ello
printf("%s\n",str+2);//prints llo
printf("%s\n",str+3);//prints lo
printf("%s\n",str+4);//prints o
printf("%s %c=%d  \n",str+5,*(str+5),*(str+5));//prints Null
printf("%s %c=%d  \n",str+6,*(str+6),*(str+6));//prints Null or may be Undefined behavior
printf("%s %c=%d  \n",str+7,*(str+7),*(str+7));//prints Null or may be Undefined behaviour

你的情况也发生了同样的情况。

测试代码:

#include<stdio.h>

main()
{
char str[6]="Hello";

char *ptr =str;

printf("%s\n",str);//prints hello

printf("%s\n",str+1);//prints ello
printf("%s\n",str+2);//prints llo
printf("%s\n",str+3);//prints lo
printf("%s\n",str+4);//prints o
printf("%s %c=%d  \n",str+5,*(str+5),*(str+5));//prints Null
printf("%s %c=%d  \n",str+6,*(str+6),*(str+6));//prints Null or may be Undefined behavior
printf("%s %c=%d  \n",str+7,*(str+7),*(str+7));//prints Null or may be Undefined behaviour

}
于 2013-08-31T11:06:30.343 回答
0

你自己已经回答了你的问题。 "FIFTHA"+7给你一个字符串对象之外的指针,这是 C 中未定义的行为。

没有简单的方法可以在 C 中为此类“切片”获得更类似于 Python 的行为。您可以通过向字符串添加后缀(全为零字节)使其适用于达到某个上限的索引:

#define slice(bare_string,start_index) ((#bare_string "\0\0\0\0\0\0\0")+(start_index))

此外,在使用宏时,过度使用括号是一种很好的做法(也可以避免错误)。

#define slice(bare_string,start_index) ((#bare_string)+(start_index))
#define arcane_slice(bare_string,start_index) (("ARCANE" #bare_string)+(start_index))
于 2013-08-31T11:08:34.287 回答