Почему выводится следующая программа 84215045
?
int grid[110];
int main()
{
memset(grid, 5, 100 * sizeof(int));
printf("%d", grid[0]);
return 0;
}
Почему выводится следующая программа 84215045
?
int grid[110];
int main()
{
memset(grid, 5, 100 * sizeof(int));
printf("%d", grid[0]);
return 0;
}
memset
устанавливает каждый байт буфера назначения в указанное значение. В вашей системе int
- четыре байта, каждый из которых равен 5 после вызова memset
. Таким образом, grid[0]
имеет значение 0x05050505
(шестнадцатеричное), которое 84215045
в десятичной форме.
Некоторые платформы предоставляют альтернативные API для memset
, которые пишут более широкие шаблоны в буфер назначения; например, в OS X или iOS, вы можете использовать:
int pattern = 5;
memset_pattern4(grid, &pattern, sizeof grid);
чтобы получить поведение, которое вы, похоже, ожидаете. На какой платформе вы нацеливаетесь?
В С++ вы должны просто использовать std::fill_n
:
std::fill_n(grid, 100, 5);
memset(grid, 5, 100 * sizeof(int));
Вы устанавливаете 400 байт, начиная с (char*)grid
и заканчивая на (char*)grid + (100 * sizeof(int))
, на значение 5
(здесь необходимы приведения, потому что memset
имеет дело в байтах, тогда как арифметика указателя имеет дело с objects
.
84215045
в шестнадцатеричном состоянии 0x05050505
; поскольку int
(на вашей платформе/компилятор/etc.) представляется четырьмя байтами, когда вы печатаете его, вы получаете "четыре пятых".
memset
- это установка байтов, а не значений. Один из многих способов задания значений массива в С++ - std::fill_n
:
std::fill_n(grid, 100, 5);
Не используйте memset.
Вы устанавливаете каждый байт []
в памяти на значение 5. Каждый int имеет длину 4 байта [5][5][5][5]
, который компилятор правильно интерпретирует как 5 * 256 * 256 * 256 + 5 * 256 * 256 + 5 * 256 + 5 = 84215045. Вместо этого используйте цикл for, который также не требует sizeof(). В общем случае sizeof() означает, что вы делаете что-то трудное.
for(int i=0; i<110; ++i)
grid[i] = 5;
Ну, memset
записывает байты с выбранным значением. Поэтому int будет выглядеть примерно так:
00000101 00000101 00000101 00000101
который затем интерпретируется как 84215045.
Вы на самом деле не сказали, что хотите сделать своей программе.
Предполагая, что вы хотите установить каждый из первых 100 элементов grid
в 5 (и игнорировать несоответствие 100
vs. 110
), просто выполните следующее:
for (int i = 0; i < 100; i ++) {
grid[i] = 5;
}
Я понимаю, что вы обеспокоены скоростью, но ваша забота, вероятно, неуместна. С одной стороны, memset()
, вероятно, будет оптимизирован и, следовательно, быстрее, чем простой цикл. С другой стороны, оптимизация, вероятно, будет состоять из записи более одного байта за раз, что и делает этот цикл. С другой стороны, memset()
- это петля; запись цикла явно, а не захоронение в вызове функции не изменяет этого. С другой стороны, даже если цикл медленный, это вряд ли имеет значение; сосредоточиться на написании четкого кода и подумать об оптимизации, если фактические измерения указывают на существенную проблему с производительностью.
Вы потратили на несколько порядков больше времени на постановку вопроса, чем ваш компьютер проведет настройку grid
.
Наконец, прежде чем я выйду из рук (слишком поздно!), не имеет значения, насколько быстр memset()
, если он не делает то, что вы хотите. (Не устанавливать grid
вообще еще быстрее!)
Поскольку memset пишет байты, я обычно использую его для установки массива int равным нулю:
int a[100];
memset(a,0,sizeof(a));
или вы можете использовать его для установки массива char, так как char является в точности байтом:
char a[100];
memset(a,'*',sizeof(a));
что больше, массив int также может быть установлен на -1 с помощью memset:
memset(a,-1,sizeof(a));
Это потому, что -1 является 0xffffffff в int и равен 0xff в char (байт).
Этот код был протестирован. Вот способ memset массива Integer со значением от 0 до 255.
MinColCost=new unsigned char[(Len+1) * sizeof(int)];
memset(MinColCost,0x5,(Len+1)*sizeof(int));
memset(MinColCost,0xff,(Len+1)*sizeof(int));