I was trying to learn about memset
function and I read an article that we cannot initialise int
array to 1 using memset
. But I have declared a bool
array and initialised it to true using memset
function.
On printing the array elements the array elements are 1 1 1
rather than true. If initialised to false it gives 0 0 0
.
Also I declared an int
variable x
and set its value to a[0] a[1]
and on printing x
it gives me 2
. I am using c on devc . Can anyone explain me the reason?
bool a[3]
memset( a,true,3*sizeof(bool))
cout << a[i]; // 1 1 1
int x = a[0] a[1]; // 2
CodePudding user response:
sizeof( bool )
in C or sizeof( _Bool )
in C are implementation defined but usually they are equal to 1
that is to the value of sizeof( char )
and the value true is stored as 1 and the value false is stored as 0.
For example (the C Standard, 6.2.5 Types)
2 An object declared as type _Bool is large enough to store the values 0 and 1
So this call of memset
memset( a,true,3*sizeof(bool));
set all elements of the array a to 1.
This statement
cout « a[i];
outputs boolean values equal to true as integer constants 1. If you want to output as a string you need to use the manipulator std::boolalpha
. For example
cout « std::boolalpha << a[i];
In this declaration
int x = a[0] a[1];
the operand a[2]
and a[1]
yield the value 1
. So their sum is equal to 2
.
CodePudding user response:
When you print out your bool
s, the stream has a boolalpha
flag to determine whether they print out as true
/false
or as 1
/0
. If you want them to print out as true
/false
, you can do something like:
std::cout << std::boolalpha << a[i];
I wrote an answer some time ago that goes into more detail about this: https://stackoverflow.com/a/15960054/179910
For the sake of compatibility with C, C defined implicit conversions from int
to bool
and bool
to int
, so 0
converts to false
and any other value to true
, while false
converts to 0
and true
converts to 1
. So when you do a[2] a[1]
, it converts each bool
to the corresponding int
, then adds those together. Not always the behavior you'd want, but something that's used in enough C code that they apparently thought it necessary to maintain anyway (and I think they were right).
Getting back to memset
, the problem with setting int
s to non-zero values is that memset
always treats the data you give it as an array of char
, regardless of the type of data that's actually there. Each char
(by definition) occupies a single byte. For example, let's assume you have 4-byte int
s on your implementation. In this case, if you use memset
to set those int
s to 1
, what you're going to get is each int
set to the value 0x01010101
(which in decimal will be 16,843,009).
In C , std::fill
or std::fill_n
tends to work out better as a rule. It's implemented as a template so its behavior is tailored to the type being written, so if you use it to fill an array of int
with 1
, each int
will actually have the value 1
.