char str[]="beautiful earth";
memset(str,'*',6);
printf("%s",str);
output:
******ful earth
1)上記のmemsetの使用と同様に、以下に示すように、少数の整数配列インデックス値のみを1に初期化できますか?
int arr[15];
memset(arr,1,6);
いいえ、このようにmemset()
を使用することはできません。 manpage は(emphasis mine)と言います:
memset()
関数は、n
が指すメモリ領域の最初のs
bytesを埋めます。定数バイトc
を使用します。
int
は通常4バイトなので、これはカットしません。
もし(incorrectly !!)これを試してください:
_int arr[15];
memset(arr, 1, 6*sizeof(int)); //wrong!
_
配列の最初の6 int
sは、実際には0x01010101 = 16843009に設定されます。
バイト以外のデータ型でデータの「ブロブ」を上書きすることが本当に受け入れられるのは、memset(thing, 0, sizeof(thing));
が構造体/配列全体を「ゼロアウト」することだけです。これは、NULL、0x00000000、0.0がすべて完全にゼロであるため機能します。
解決策は、for
ループを使用して自分で設定することです。
_int arr[15];
int i;
for (i=0; i<6; ++i) // Set the first 6 elements in the array
arr[i] = 1; // to the value 1.
_
短い答え、NO。
長い答え、memset
はバイトを設定し、単一バイトであるため文字に対して機能しますが、整数はそうではありません。
Memsetの3番目の引数はバイトサイズです。したがって、合計バイトサイズを_arr[15]
_に設定する必要があります
_memset(arr, 1, sizeof(arr));
_
ただし、おそらく、arrの要素全体に値1を設定する必要があります。その後、ループで設定する方が良いでしょう。
_for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
arr[i] = 1;
}
_
memset()
は各バイトに1を設定するためです。だからそれはあなたの期待ではありません。
Linux、OSX、およびオペレーティングシステムのような他のUNIXでは、_wchar_t
_は32ビットであり、wmemset()
の代わりにmemset()
を使用できます。
_#include<wchar.h>
...
int arr[15];
wmemset( arr, 1, 6 );
_
MS-Windowsの_wchar_t
_は16ビットであるため、このトリックは機能しない場合があります。
いいえ、目的のターゲット値が0
でない限り、その目的で[ポータブル] memset
を使用することはできません。 memset
は、ターゲットメモリ領域をint
sの配列ではなく、バイトの配列として扱います。
メモリ領域を繰り返しパターンで埋めるためのかなり人気のあるハックは、実際にはmemcpy
に基づいています。 memcpy
がデータを順方向にコピーするという期待に大きく依存しています
int arr[15];
arr[0] = 1;
memcpy(&arr[1], &arr[0], sizeof arr - sizeof *arr);
もちろん、これはかなりprettyいハックです。なぜなら、ソースとデスティネーションのメモリ領域がオーバーラップするときの標準のmemcpy
の振る舞いは未定義だからです。ただし、memcpy
の独自のバージョンを作成して、データを順方向にコピーし、上記の方法で使用することができます。しかし、それは本当に価値がありません。単純なサイクルを使用して、配列の要素を目的の値に設定するだけです。
Memsetは1バイトのデータ型に値を設定しますが、整数には4バイト以上ありますので、機能せず、ガベージ値を取得します。主にchar型とstring型を使用しているときに使用されます。
誰も言及していないので...
Memsetを使用して整数を値1
で初期化することはできませんが、canを値-1
で初期化し、代わりに負の値で動作するようにロジックを変更します。
たとえば、配列の最初の6つの数字を-1
で初期化するには、次のようにします。
memset(arr,-1,6*(sizeof int));
さらに、この初期化を一度だけ行う必要がある場合は、コンパイル時に値1
で始まる配列を実際に宣言できます。
int arr[15] = {1,1,1,1,1,1};
理想的には、memsetを使用して、すべてを1に設定することはできません。
memsetはバイトに対して機能し、すべてのバイトを1に設定するためです。
memset(hash, 1, cnt);
そのため、一度読み取ると、表示される値16843009 = 0x01010101 = 1000000010000000100000001
Not x00000001
ただし、requiremntがboolまたはバイナリ値のみの場合は、CライブラリのC99標準を使用して設定できます
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> //Use C99 standard for C language which supports bool variables
int main()
{
int i, cnt = 5;
bool *hash = NULL;
hash = malloc(cnt);
memset(hash, 1, cnt);
printf("Hello, World!\n");
for(i=0; i<cnt; i++)
printf("%d ", hash[i]);
return 0;
}
出力:
こんにちは世界!
1 1 1 1 1
私は次のプログラムを試してみましたが、-1と0のみでmemset()を使用して配列を初期化できるようです
#include<stdio.h>
#include<string.h>
void printArray(int arr[], int len)
{
int i=0;
for(i=0; i<len; i++)
{
printf("%d ", arr[i]);
}
puts("");
}
int main()
{
int arrLen = 15;
int totalNoOfElementsToBeInitialized = 6;
int arr[arrLen];
printArray(arr, arrLen);
memset(arr, -1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 0, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, -2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
return 0;
}