2009-06-24 13 views
9

Jest to kod, który chcę spróbować napisać:C: Używanie funkcji memset

#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <string.h> 
#include <malloc.h> 

int main(int argc, char *argv[]) 
{ 
    float arry[3] = {0}; 

    memset(arry, (int) 10.0, 3*sizeof(float)); 

    return 0; 
} 

Mój problem jest, że chcę, aby sprawdzić, czy jest możliwe użycie memset, aby każdy wpis tablicy być liczba inna niż 0. Jednak po przejściu przez tę linię zawartość tablicy zmienia się na bardzo małą liczbę (0). Zastanawiam się, co robię źle w tym przypadku przy użyciu funkcji memset(). Mam nadzieję, że nie jest to duplikat postu, bo nie wydaje mi się, aby żadne z sugerowanych powiązanych pytań, jakie wpisuję.

Odpowiedz

9

Oddanie podwójnego do int powoduje właśnie utworzenie liczby binarnej 00001010 (10 w binarnym) i jest to wartość, która jest memset'ed. Ponieważ jest to znak char, każdy z twoich elementów pływających otrzymuje wzór bitowy 00001010 00001010 00001010 00001010.

+0

tj. Ma sens tylko użyć go do zresetowania wpisów tablicy do zera, praktycznie mówiąc? – stanigator

+0

To lub jeśli konfigurujesz tablicę znaków, która ma inną istotną wartość. –

+0

Lub dowolna wartość jednobajtowa. Najpopularniejszy jest prawdopodobnie 0, ale najprawdopodobniej będzie również często używany 0xFF. –

7

Nr memset zajmuje jeden bajt i zapisuje go w tablicy. Pływak jest typem wielobajtowym.

EDYCJA: Tak, wiem, że memset ma int. Ale do wypełnienia wykorzystuje tylko niepodpisany znak char (pojedynczy bajt).

15

Memset przyjmuje int, ale rzuca na niepodpisany znak, a następnie wypełnia każdy bajt float (sizeof (float) prawdopodobnie 4) z tym bitowym wzorem. Jeśli jest to C++, wolą fill zamiast:

#include <algorithm> 
using namespace std; 

//... 

fill (arry,arry+3,10.0); 
+0

Świetna sugestia. Przyjrzę się, jak go użyć. – stanigator

+1

A jeśli jesteś w C, nie w C++, to poszukaj specyficznych dla platformy wariantów memetów, które zapisują większe wzory niż pojedynczy znak. Jest na przykład memset_pattern4, jeśli ją masz. Lub instrukcje SIMD. –

2

Właściwie twoja próba jest trochę mylący, memset działa na bajtów .. faktycznie przy użyciu pacy do wartości memset nie ma sensu!

Format float ma po prostu 23 + 1 bitów dla mantysy i 8 bitów dla wykładnika .. podczas zapisywania wartości surowych bajtów (przy użyciu memsetu) w float nie wiesz, co otrzymujesz, ponieważ ustawiasz wartości, które będą interpretowane w inny sposób!

W twoim fragmencie przekopujesz go również do (int) obracając 4-bajtowy float zawierający 10.0f w 4-bajtowej liczbie całkowitej zawierającej wartość 10 .., ale jak powiedziano wcześniej, jeśli ustawisz wartość float z 10 (= 0x0a) w końcu otrzymasz 0x0A0A0A0A, który nie jest 10.0f w formacie float, może to być dowolna wartość (także coś bardzo zbliżonego do 0, jak w twoim przypadku).

Właściwie memset jest przydatna, gdy chcesz zainicjować tablicę znaków (ponieważ można uzyskać skutecznie tę wartość dla każdego char, ponieważ są one 1 bajt długości) lub gdy chcesz ustawić wszystko na 0 (null), który działa dla każdego podstawowego rodzaju danych ..

3

Dlaczego nie tylko prosta pętla for?

+3

Potrzeba prędkości jest jedną odpowiedzią. – EvilTeach

+0

Właściwie cały punkt mojego pytania. – stanigator

+0

Wszystko, co zrobi memset to ustawić bajt jednego bajtu na raz. Pętla for zapisze jeden bajt sizeof (arry) sizeof (float) na raz. I bez narzutu wywołania funkcji! –