我正在读这个例子
The real "Hello World!" for CUDA!
<{1}}
\0
代表什么?
我不确定为什么16个字符char str[16] = "Hello \0\0\0\0\0\0";
里面有str
然后全部为零(这不是全局变量)。我怎么能确定它只包含零?“
答案 0 :(得分:22)
'\0'
是ASCII NUL
null character(ASCII代码为零)。
指定数组中的所有零字节没有意义。以下是等效的:
char str[16] = "Hello \0\0\0\0\0\0";
char str[16] = "Hello ";
如果数组已部分初始化,则未初始化的元素将接收相应类型的值0。 [IBM]
由于长度为16,编译器将自动确保数组的其余部分("Hello "
归零后。)作者这样做是为了确保&#34;确保&#34;数组的其余部分为零,或作为读者的文档。
与我们的初步分析相反,CUDA内核不&#34;戳入字节&#34;将World!
附加到现有字符串。首先打印Hello
。然后内核将字符串修改为World!
,最后打印出来。
将字符串指定为16个字节的唯一原因是因为这是内核设计使用的块大小,并且它们必须确保内核不会弄乱内存它不应该这样做是
我已经对(部分)原始代码添加了一些评论,以使其更清晰:
__global__ // The kernel which is run in parallel
void hello(char *a, int *b)
{
a[threadIdx.x] += b[threadIdx.x];
}
int main()
{
// The line in question. There's really no point in padding it with zeros.
// The zeros are *not* replaced, and only 12+1 bytes are being specified.
char a[N] = "Hello \0\0\0\0\0\0";
// These values are added (by the CUDA kernel) to the array above. Again,
// since partial arrays are zero-filled, there's no point in filling this in.
int b[N] = {15, 10, 6, 0, -11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// 'H' + 15 = 'W'
// 'e' + 10 = 'o'
// 'l' + 6 = 'r'
// 'l' + 0 = 'l'
// 'o' - 11 = 'd'
// ' ' + 1 = '!'
char *ad;
int *bd;
const int csize = N*sizeof(char);
const int isize = N*sizeof(int);
printf("%s", a); // Print "Hello "
cudaMalloc( (void**)&ad, csize );
cudaMalloc( (void**)&bd, isize );
cudaMemcpy( ad, a, csize, cudaMemcpyHostToDevice );
cudaMemcpy( bd, b, isize, cudaMemcpyHostToDevice );
dim3 dimBlock( blocksize, 1 );
dim3 dimGrid( 1, 1 );
hello<<<dimGrid, dimBlock>>>(ad, bd); // Add the values in b to a
cudaMemcpy( a, ad, csize, cudaMemcpyDeviceToHost );
cudaFree( ad );
cudaFree( bd );
printf("%s\n", a); // print "World!"
return EXIT_SUCCESS;
}
答案 1 :(得分:5)
\0
代表NUL
,Nul用作字符串终止字符。意思是它表示字符串的结尾。 NUL字节的值为0x00
答案 2 :(得分:2)
如前所述,没有多大意义。 \0
只是在那里放置代码为0的字符,但无论如何它都会发生。很好用的是没有给出数组边界,因为额外的0将计入,或者在0之后你有更多的字符。
char foo_and_bar[] = "Foo\0Bar";
将零件与0分开。