我有一个非常长的字符串对象,我想在其中引用窗口[0,19],[1,20],.....,[980,1000]作为{{1 }}
让我们调用字符串char x[20]
。我试过了
foo
并迭代,但我收到了不兼容的类型错误,因为x = &foo[i]
的类型为&foo[i]
。
如何使用char *
引用字符串foo内存的20-char块?
更哲学地说,char x[20]
和char *x
如果后者不是空终止会有什么区别?
一个目标是不必通过为所有新字符创建全新的内存块来获得2倍的内存要求。
答案 0 :(得分:1)
看一下llvm的StringRef课程。从本质上讲,它只包含两个指针,即开始和结束。你可以做这样的事情,例如:
std::string source = "... something really long ...";
const char * b = source.c_str();
llvm::StringRef window(b + 100, 20);
window
现在是指source
的一部分的实体。您可以在其上调用begin()
和end()
来获取迭代器。您可以像普通字符串一样打印它,如下所示:
std::cout << window;
它提供了各种其他常见的字符串操作,您可以在docs中看到。
答案 1 :(得分:1)
char * p
是指向应该包含字符的内存的指针。隐含的数据没有结束。
char a[100]
是100个字符的内存部分。编译器已知a的结尾访问多维数组和错误检查函数参数。
&amp; a [0]或只是a(元素0的地址)与char *基本相同。
a或p的用户必须以某种方式知道长度:
1)另外提供长度参数。例如:sizeof(a)
(以字节为单位)。
我还想使用numof(a)
,它可以通过添加以下元素而不是字节大小:
#define numof(X) (sizeof(X)/sizeof(*X))
您也可以使用另一个指向结尾的指针来停止。而不是长度。
2)告诉用户p什么时候停止的一些内容或规则。例如:*p == 0
(空)
这是C / C ++的强大灵活性来源(如果误用,也会带来危险)。
a)更改数组的用户也有一个长度限制或指向end的停止位置。 如果最后一个块尺寸过小,您可能还需要进行空终止检查。
b)一次只处理一个数据块。然后你只新增了1个额外的20个char数组。 或者,如果您可以确保没有其他线程同时使用该阵列,您可以暂时更改空终止:
// array is assumed to be a multiple of 20 plus 1 more for null
char * ptr = array;
while ( ptr < array + sizeof(array)-1 )
{
char * end = ptr + 20; // we will stop here
char save_char = *end; // save the character there
*end = 0; // put in temporary null
ProcessBlock( ptr ); // now null terminated !
*end = save_char; // restore the array
ptr = end; // end of this block is start of next
}
答案 2 :(得分:0)
只做
int window_size = 20;
for (size_t i = 0; i < foo.size() - window_size; ++i)
{
const char* x = foo.data() + i;
// Do something with x[0] to x[window_size - 1]
}
答案 3 :(得分:0)
您收到“不兼容的类型错误”的原因是x
和&foo[i]
属于不同类型。考虑一下:
foo
属于char[]
类型(即char
的数组)foo[i]
的类型为char
&foo[i]
属于char*
类型(即指向char
的指针) char* x
和char x[20]
之间的区别在于,在第一种情况下,x
是指向char的指针,在第二种情况下,它是char
的数组。在第一种情况下,您可以将指针指向进程内存中的任何char
。在第二个中,x
通常表现得像指针,但它总是指向数组的开头。
假设foo大小是窗口大小的倍数,您可以像这样遍历窗口:
char foo[FOO_SIZE];
for (unsigned i = 0; i < FOO_SIZE; i += WINDOW_SIZE) {
char first_char = foo[i];
char last_char = foo[i + WINDOW_SIZE - 1]; // Warning: if foo size is not multiple of window size, this may exceed foo in the last window
}
此外,您自己的代码可能很好,只需从&foo[i]
中删除&符号即可。请注意[]
已经取消引用指针,因此不需要额外的&
。