同时替换多个字符

时间:2011-07-27 05:35:10

标签: c++ c random char int

所以在我的代码中,我有一系列字符,我想用随机数据替换。由于rand可以替换整数,我想我可以通过一次替换四个字符而不是一次替换一个字符来节省一些时间。所以基本上不是这样的:

  unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
  for (i = 34; i < flenght; i++) // generating the data to send.
     TXT[i] = rand() % 255;

我想做点什么:

unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght; i+4) // generating the data to send.
  TXT[i] = rand() % 4294967295;

有效的东西,但我不知道如何做后半部分。非常感谢您给予我的任何帮助,谢谢!

7 个答案:

答案 0 :(得分:3)

那不行。编译器将从rand() % big_number获取结果并切断额外数据以使其适合unsigned char

速度方面,你的初步方法很好。您考虑的优化是有效的,但很可能是不需要的。它可能不会产生显着的差异。

当然,你想做什么 可能但是考虑到你的错误,我会说要理解现在如何远远超过好处。继续学习,下次遇到这样的代码时,你会知道该怎么做(并判断是否有必要),回顾这一刻并微笑:)。

答案 1 :(得分:0)

您必须直接访问内存,并对数据进行一些转换。你可能想要这样的东西:

unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght/sizeof(int); i+=sizeof(int)) // generating the data to send.
{
     int *temp = (int*)&TXT[i]; // very ugly
     *temp = rand() % 4294967295;
}

虽然因为对齐问题可能会有问题,所以要小心。对齐问题可能会导致程序意外崩溃,并且很难调试。如果我是你,我不会这样做,你的初始代码就好了。

答案 2 :(得分:0)

 TXT[i] = rand() % 4294967295;

不会按照你期望的方式工作。也许您期望rand()%4294967295将生成一个4字节整数(您可能将其解释为4个不同的字符)。 rand()%4294967295生成的值将被输入到单个char中,并且仅分配给TXT[i]的索引之一。

虽然并不清楚为什么需要同时进行4次分配,但是一种方法是使用位运算符来获得生成的数字的4个不同的有效字节,然后可以将这些字节分配给4个不同的索引。

答案 3 :(得分:0)

unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght; i+4)
    // generating the data to send.
    TXT[i] = rand() % 4294967295;

这有几个问题:

  • TXT不能保证内存对齐,因为CPU需要写入int数据(无论是否有效 - 可能相对较慢 - 或者不是 - 例如Solaris上的SIGBUS - 是特定于硬件的)
  • 可能错过最后1-3个字符(即使您将i + 4更改为i += 4 ;-P)
  • rand()无论如何都会返回int - 您无需使用任何内容进行修改
  • 您需要通过int*编写随机数据,这样您一次只能访问4个字节而不是简单地从随机数据的末尾切换一个字节并覆盖每四个单个字符
  • 对于这样的东西,你依赖于int的大小,你应该用sizeof(int)来写它,所以即使int不是32位也可以工作,或者使用(目前很遗憾)非标准但常见的typedef,例如int32_t(或在Windows上我认为它是__int32,或者您可以使用boost或其他库标题来获取{{ 1}},或编写自己的int32_t)。

对齐文本数据实际上非常棘手:你的代码建议你想要typedef - 来自第35个字符的大小切片......即使整个字符数组正确对齐整数,第35个字符也不会是

如果确实总是第35个,那么你可以使用前导字符填充数据,这样你就可以访问第36个(大概是32位int大小的倍数),然后将文本对齐一个32位地址(使用特定于编译器的int或使用与#pragma的联合)。如果真实代码改变了你开始覆盖的字符,这样你就不能简单地将数据对齐一次,那么你就会陷入困境:

  • 你原来的角色一次覆盖
  • 非便携式未对齐覆盖(如果您的系统可能并且更好),或者
  • 实现覆盖最多三个前导未对齐字符的代码,然后切换到对齐地址的32位整数覆盖模式,然后返回到最多三个尾随字符的逐个字符覆盖。

答案 4 :(得分:0)

有很多有效的答案C很不关心它存储在哪个地址的类型。所以你可以通过以下方式逃脱:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>


char *arr;
int *iArr;


int main (void){
  int i;
  arr = malloc(100);
  /* Error handling ommitted, yes that's evil */
  iArr = (int*) arr;

  for (i = 0; i < 25; i++) {
   iArr[i] = rand() % INT_MAX;
  }

  for (i = 0; i < 25; i++) {
   printf("iArr[%d] = %d\n", i, iArr[i]);
 }

for (i  = 0; i < 100; i++) {
  printf("arr[%d] = %c\n", i, arr[i]);
}
free(arr);
return 0;
}

最后,数组只是内存中的一些连续块。你可以随意解释(如果你愿意)。如果您知道sizeof(int)= 4 * sizeof(char),则上述代码将起作用。

我不是说我推荐它。其他人已经指出了发生的事情,TXT中所有字符的第一个循环将产生相同的结果。人们可以想到例如展开一个循环,但实际上我并不关心它。

仅仅(int *)就足够警告了。这对编译器意味着,不要考虑你认为类型只是“相信”程序员,他知道更好。

这个“知道更好”可能是C编程中所有邪恶的根源......

答案 5 :(得分:0)

这不起作用,因为在这种特殊情况下,生成的值将转换为数组元素的类型 - char。但您可以自由地按照自己喜欢的方式解释分配的内存。例如,您可以将其转换为数组int

unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght-sizeof(int); i+=sizeof(int)) // generating the data to send.
    *(int*)(TXT+i) = rand(); // There is no need in modulo operator
for (; i < flenght; ++i) // generating the data to send.
    TXT[i] = rand(); // There is no need in modulo operator either

我只想完成解决方案,其中包含有关模运算符和数组处理的注释,而不是sizeof(int)的多个数组。

答案 6 :(得分:0)

1)%表示“余数除以”,因此您希望rand() % 256表示char,否则您永远不会得到值为255的字符。类似于int情况,虽然这里无论如何都没有必要进行模数运算,因为你需要整个输出值范围。

2)rand通常一次只生成两个字节;检查RAND_MAX的值。

3)无论如何34都不能被4整除,所以你必须专门处理这个案例。

4)你想要转换指针,如果指针尚未对齐,它将无法工作。但是,一旦进行了强制转换,就不需要考虑迭代中的sizeof(int):指针算法会自动处理元素大小。

5)机会非常好,它不会产生明显的差异。如果将随机数据写入数组实际上是程序中的瓶颈,那么它无论如何都不会做任何有意义的事情。

相关问题