I need method, that return numbers of non empty elements of array of ints. sizeof(arr)/sizeof(type), like below:
int table[255]={1,2,3,'a','b'};
cout << "size of: " << sizeof(table)/sizeof(int) << endl;
returns 255, but I need to count elements so the result will be 5.
Shall I make my own while loop or is there any embedded function (I use Visual Studio 2010)?
Assuming that a non-empty element for T array[N] = {}; is the one that is default-initialized - T t{};, the answer is: yes, there is a standard algorithm for counting elements that match a given pattern, or satisfy a given condition, which is std::count
// include header file where the algorithm is defined:
#include <algorithm>
// use std::count to count 0 elements, which is a default value all elements
// are initialized with for int tab[N] = {};
// and subtract this value from the total number of elements of array
int howMany = 255 - std::count(table, table + 255, 0);
// table and table+255 specify the ranges the algorithm operate on
If you are using C++, why not using C++ containers like std::vector and use <algorithm> ?
Anyway, sizeof() will ALWAYS return 255 * sizeof(int) here because the table will contains 255 ints in memory.
8.5.1.7
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member
not explicitly initialized shall be initialized from an empty initializer list. For int, expression of the form int(),that is, 0.
You could use std::count from algorithm but there is one issue
int table[255]={1,0 <<< this value were stetted by user and it is not an 'empty',3,'a','b'};
So how to distinct 0 assigned by default initializer and 0 that comes as actual value? As a solution you probably should use some INVALID_VALUE definition to set values for elements in your array because 0 is not a greatest choice to mark value as unassigned. And init your array as
memset(table, INVALID_VALUE, table_size);
It can be done by writing own function's template, like this:
template<typename It>
unsigned count_non_val(It first, It last, const decltype(*first)& val){
unsigned result=0;
for(It i=first; i!=last; ++i)
if(*i!=val)
++result;
return result;
}
//Usage:
std::cout<<count_non_val(table, table+255, 0)<<'\n';
Related
If I were to create an array with int* array = new int[10]; and fill part of the array with values, how can I check how much of the array is filled? I want to loop through and check if each value is the default value but I'm not sure what the default value of each array element is. Would it be null 0 or garbage values?
This is how to set a default value in C++ when making an array.
int array[100] = {0};
Now every element is set to 0. Without doing this every element it garbage and will be undefined behavior if used.
Not all languages are like this. Java has default values when declaring a data structure but C++ does not.
There is no default value so it's garbage.
You can't do what are you hoping to, not when the type is int.
The uninitialized elements of the array will have unpredictable values. In addition, accessing those elements is cause for undefined behavior.
You can initialize the elements of the array to a sentinel value at the time of allocation using:
int* ptr = new int[10]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
Use whatever sentinel value works for you if -1 does not.
The default value of array is indeterminate means garbage.
how can I check how much of the array is filled?
You cannot check, C/C++ has no array bounds check. You have to do it yourself.You need to keep track of the data inserted by a user. When your counter reaches the size of the array, the array is full
You can solve your problem by a more C++ way. You can create struct or class, which contain your value and bool flag. Bool flag must be set to false in default constructor and set to true in operator=. There is ready implementation of such class - boost.optional. std::optional will be in C++17.
#include <boost/optional.hpp>
#include <iostream>
int main()
{
const size_t nArr = 100;
auto pArr = new boost::optional<int>[nArr];
const size_t nInit = 30;
for (size_t i = 0; i < nInit; ++i)
{
pArr[i] = i; //initialize nInit first values of pArr
}
size_t n = 0;
for (; n < nArr; ++n)
{
if (!pArr[n].is_initialized()) break;
// or more compact form:
//if(!pArr[n]) break;
assert(*pArr[n] == n);
}
std::cout << "nInit = " << nInit << ", n = " << n << std::endl;
assert(nInit == n);
delete[] pArr;
}
It should be pointed out the default is uninitialized only for basic types like int. classes will use their defined parameterless constructor. Here is a MWE that wraps an int in such a class. OP also asked about checking the values so that is here too:
#include <iostream>
struct Element {
int Value;
Element() : Value{42} {}
};
struct Array {
Element Values[10];
};
int main() {
Array array;
for(Element element: array.Values)
std::cout << element.Value << " ";
}
Note: POD (or record) classes, which have no custom constructor, will remain uninitialised. Non-POD classes that have no parameterless constructor cannot usually be held in arrays.
I don't know if this helps but in c++17 onwards there's the std::array class that can be used. In this class you have the option to use class functions such as std::array.fill(...)
std::array<int, 10> arr;
arr.fill(-1);
cpp docs: cpp-docs
This get's you closer to the experience from other languages such as Java and Python both having Arrays.fill(arr, -1); and arr = [-1]*N respectively to fill the array with non-default values.
By default, the objects allocated by new are default initialized. This mean when you wrote:
int* array = new int[10]; //block of 10 uninitialized ints
Here, all of the 10 ints are uninitialized. That is, they have indeterminate value.
It is possible to value initialize the elements by adding an empty pair of parenthesis as shown below:
int* array = new int[10](); //block of 10 ints value initialized to 0
Here all of the 10 ints are initialized to 0.
But note that although we can use empty parentheses to value initialize the elements of an array, we cannot supply an element initializer inside the parentheses. This means for example,
int* array = new int[10](55); // INVALID
The above statement is invalid because we cannot supply an element initializer inside the parenthesize.
You can use std::fill_n instead of supplying an element initializer inside the parentheses as shown below:
int* array = new int[10]; //block of 10 uninitialized ints
std::fill_n(array, 10, 55); // all elements will now hold 55
If I were to create an array with int* array = new int[10]; and fill part of the array with values, how can I check how much of the array is filled? I want to loop through and check if each value is the default value but I'm not sure what the default value of each array element is. Would it be null 0 or garbage values?
This is how to set a default value in C++ when making an array.
int array[100] = {0};
Now every element is set to 0. Without doing this every element it garbage and will be undefined behavior if used.
Not all languages are like this. Java has default values when declaring a data structure but C++ does not.
There is no default value so it's garbage.
You can't do what are you hoping to, not when the type is int.
The uninitialized elements of the array will have unpredictable values. In addition, accessing those elements is cause for undefined behavior.
You can initialize the elements of the array to a sentinel value at the time of allocation using:
int* ptr = new int[10]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
Use whatever sentinel value works for you if -1 does not.
The default value of array is indeterminate means garbage.
how can I check how much of the array is filled?
You cannot check, C/C++ has no array bounds check. You have to do it yourself.You need to keep track of the data inserted by a user. When your counter reaches the size of the array, the array is full
You can solve your problem by a more C++ way. You can create struct or class, which contain your value and bool flag. Bool flag must be set to false in default constructor and set to true in operator=. There is ready implementation of such class - boost.optional. std::optional will be in C++17.
#include <boost/optional.hpp>
#include <iostream>
int main()
{
const size_t nArr = 100;
auto pArr = new boost::optional<int>[nArr];
const size_t nInit = 30;
for (size_t i = 0; i < nInit; ++i)
{
pArr[i] = i; //initialize nInit first values of pArr
}
size_t n = 0;
for (; n < nArr; ++n)
{
if (!pArr[n].is_initialized()) break;
// or more compact form:
//if(!pArr[n]) break;
assert(*pArr[n] == n);
}
std::cout << "nInit = " << nInit << ", n = " << n << std::endl;
assert(nInit == n);
delete[] pArr;
}
It should be pointed out the default is uninitialized only for basic types like int. classes will use their defined parameterless constructor. Here is a MWE that wraps an int in such a class. OP also asked about checking the values so that is here too:
#include <iostream>
struct Element {
int Value;
Element() : Value{42} {}
};
struct Array {
Element Values[10];
};
int main() {
Array array;
for(Element element: array.Values)
std::cout << element.Value << " ";
}
Note: POD (or record) classes, which have no custom constructor, will remain uninitialised. Non-POD classes that have no parameterless constructor cannot usually be held in arrays.
I don't know if this helps but in c++17 onwards there's the std::array class that can be used. In this class you have the option to use class functions such as std::array.fill(...)
std::array<int, 10> arr;
arr.fill(-1);
cpp docs: cpp-docs
This get's you closer to the experience from other languages such as Java and Python both having Arrays.fill(arr, -1); and arr = [-1]*N respectively to fill the array with non-default values.
By default, the objects allocated by new are default initialized. This mean when you wrote:
int* array = new int[10]; //block of 10 uninitialized ints
Here, all of the 10 ints are uninitialized. That is, they have indeterminate value.
It is possible to value initialize the elements by adding an empty pair of parenthesis as shown below:
int* array = new int[10](); //block of 10 ints value initialized to 0
Here all of the 10 ints are initialized to 0.
But note that although we can use empty parentheses to value initialize the elements of an array, we cannot supply an element initializer inside the parentheses. This means for example,
int* array = new int[10](55); // INVALID
The above statement is invalid because we cannot supply an element initializer inside the parenthesize.
You can use std::fill_n instead of supplying an element initializer inside the parentheses as shown below:
int* array = new int[10]; //block of 10 uninitialized ints
std::fill_n(array, 10, 55); // all elements will now hold 55
When I divide a valarray by its first element, only the first element becomes 1 and others keep their original value.
#include <iostream>
#include <valarray>
using namespace std;
int main() {
valarray<double> arr({5,10,15,20,25});
arr=arr/arr[0]; // or arr/=arr[0];
for(int value:arr)cout << value << ' ';
return 0;
}
The actual output is:
1 10 15 20 25
The expected output is:
1 2 3 4 5
Why is the actual output not as expected?
I use g++(4.8.1) with -std=c++11
This one works:
#include <iostream>
#include <valarray>
using namespace std;
int main() {
valarray<double> arr({5,10,15,20,25});
auto v = arr[0];
arr=arr/v; // or arr/=arr[0];
for(int value:arr)cout << value << ' ';
return 0;
}
The problem is that you are trying to use a value (arr[0]) from an array that you are modifying at the same time (arr).
Intuitively, once you have updated arr[0] by doing arr[0]/arr[0], what value does it contain?
Well, that's the value that will be used from now on to divide the other values...
Please, note that the same applies for arr/=arr[0] (first of all, arr[0]/arr[0] takes place, than all the others, in a for loop or something like that).
Also note from the documentation that operator[] of a std::valarray returns a T&. This confirms the assumption above: it is turned to 1 as the first step of your iteration, then all the other operations are useless.
By simply copying it solves the issue, as in the example code.
The details of why this happens are due to implementation tricks used in valarray to improve performance. Both libstdc++ and libc++ use expression templates for the results of valarray operations, rather than performing the operations immediately. This is explicitly allowed by [valarray.syn] p3 in the C++ standard:
Any function returning a valarray<T> is permitted to return an object of another type, provided all the
const member functions of valarray<T> are also applicable to this type.
What happens in your example is that arr/arr[0] doesn't perform the division immediately, but instead it returns an object like _Expr<__divide, _Valarray, _Constant, valarray<double>, double> which has a reference to arr and a reference to arr[0]. When that object is assigned to another valarray the division operation is performed and the result stored directly into the left-hand side of the assignment (this avoids creating a temporary valarray to store the result and then copying it into the left-hand side).
Because in your example the left-hand side is the same object, arr, it means that the reference to arr[0] stored in the expression template refers to a different value once the first element in arr has been updated with the result.
In other words, the end result is something like this:
valarray<double> arr{5, 10, 15, 20, 25};
struct DivisionExpr {
const std::valarray<double>& lhs;
const double& rhs;
};
DivisionExpr divexpr = { arr, arr[0] };
for (int i = 0; i < size(); ++i)
arr[i] = divexpr.lhs[i] / divexpr.rhs;
The first iteration of the for-loop will set arr[0] to arr[0] / arr[0] i.e. arr[0] = 1, and then all subsequent iterations will set arr[i] = arr[i] / 1 which means the values don't change.
I'm considering making a change to the libstdc++ implementation so that the expression template will store a double directly instead of holding a reference. This would mean arr[i] / divexpr.rhs will always evaluate arr[i] / 5 and not use the updated value of arr[i].
I am trying specify a condition by saying that if an array is not equal to an array run loop. So for example:
array1 [1,2,3]
array2 [1,2,3]
Here array1 does equal array2 as the elements in 0 in both arrays are the same, the elements in 1 in both arrays are the same and so on...
The code I have so far doesn't seem to work. Is there a way of comparing two arrays and if all elements in one match all the elements in the second one the condition is true.
Here is my test code:
int C1Mean[3];
int C2Mean[3];
int prv_mean1[3];
int prv_mean2[3];
while (C1Mean[3] = prv_mean1[3] && C2Mean[3] = prv_mean2[3])
{
//code
}
Thanks chaps.
As commented you access your arrays out of bounds, and you are using assignments (single =) instead or comparisons (==).
To compare your arrays (element by element), you can use std::equal :
while(std::equal(std::begin(C1Mean), std::end(C1Mean), std::begin(prv_mean1))
&& std::equal(std::begin(C2Mean), std::end(C2Mean), std::begin(prv_mean2)))
{
...
}
Or without c++11 :
while(std::equal(C1Mean, C1Mean + sizeof C1Mean / sizeof *C1Mean, prv_mean1)
&& std::equal(C2Mean, C2Mean + sizeof C2Mean / sizeof *C2Mean, prv_mean2))
{
...
}
In c++11, you may use std::array, and use ==:
std::array<int, 3> C1Mean;
std::array<int, 3> C2Mean;
std::array<int, 3> prv_mean1;
std::array<int, 3> prv_mean2;
while (C1Mean == prv_mean1 && C2Mean == prv_mean2)
{
//code
}
You are not using comparison operator (==) but assignment (=), so you change the value of CMean[i] in the condition and the condition would be false only when one of prv_mean2 would be equal to zero. And no, you can't compare the whole arrays.
If you are able to use c++11 you can use a generic function. The generic function is:
bool equal(beginIterator, endIterator, beginIterator Other);
This generic function will compare all values in a range. Note that the second array must be at least as long as the first array.
Since an array is nog an object you cannot use arr.begin () and you should use std::begin(arr) and std::end(arr). These functions come with #include.
Furthermore, if you can use c++11 you can also use the standad container std::array or std::vector. Then you can just state arr1 == arr2.
Note: I wrote this on my mobile and didn't check whether the generic function actually works on arrays. I will check this when at home again and eventually remove my post.
You can create a function to compare the two arrays that will return 1 if they are equal and 0 otherwise. Say, for example,
while(areEqual(C1Mean,prv_mean1) && areEqual(C2Mean,prv_mean2))
{
//Perform your task
}
where
int areEqual(int array1[],int array2[])
{
//compare them and return 1 if equal else return 0;
}
It seems like you need a double equals("=="). Try:
while (C1Mean[3] == prv_mean1[3] && C2Mean[3] == prv_mean2[3])
{
//code
}
This question already has answers here:
Initialization of all elements of an array to one default value in C++?
(12 answers)
Closed 4 months ago.
I'm trying to initialize an int array with everything set at -1.
I tried the following, but it doesn't work. It only sets the first value at -1.
int directory[100] = {-1};
Why doesn't it work right?
I'm surprised at all the answers suggesting vector. They aren't even the same thing!
Use std::fill, from <algorithm>:
int directory[100];
std::fill(directory, directory + 100, -1);
Not concerned with the question directly, but you might want a nice helper function when it comes to arrays:
template <typename T, size_t N>
T* end(T (&pX)[N])
{
return pX + N;
}
Giving:
int directory[100];
std::fill(directory, end(directory), -1);
So you don't need to list the size twice.
I would suggest using std::array. For three reasons:
1. array provides runtime safety against index-out-of-bound in subscripting (i.e. operator[]) operations,
2. array automatically carries the size without requiring to pass it separately
3. And most importantly, array provides the fill() method that is required for
this problem
#include <array>
#include <assert.h>
typedef std::array< int, 100 > DirectoryArray;
void test_fill( DirectoryArray const & x, int expected_value ) {
for( size_t i = 0; i < x.size(); ++i ) {
assert( x[ i ] == expected_value );
}
}
int main() {
DirectoryArray directory;
directory.fill( -1 );
test_fill( directory, -1 );
return 0;
}
Using array requires use of "-std=c++0x" for compiling (applies to the above code).
If that is not available or if that is not an option, then the other options like std::fill() (as suggested by GMan) or hand coding the a fill() method may be opted.
If you had a smaller number of elements you could specify them one after the other. Array initialization works by specifying each element, not by specifying a single value that applies for each element.
int x[3] = {-1, -1, -1 };
You could also use a vector and use the constructor to initialize all of the values. You can later access the raw array buffer by specifying &v.front()
std::vector directory(100, -1);
There is a C way to do it also using memset or various other similar functions. memset works for each char in your specified buffer though so it will work fine for values like 0 but may not work depending on how negative numbers are stored for -1.
You can also use STL to initialize your array by using fill_n. For a general purpose action to each element you could use for_each.
fill_n(directory, 100, -1);
Or if you really want you can go the lame way, you can do a for loop with 100 iterations and doing directory[i] = -1;
If you really need arrays, you can use boosts array class. It's assign member does the job:
boost::array<int,N> array; // boost arrays are of fixed size!
array.assign(-1);
It does work right. Your expectation of the initialiser is incorrect. If you really wish to take this approach, you'll need 100 comma-separated -1s in the initialiser. But then what happens when you increase the size of the array?
use vector of int instead a array.
vector<int> directory(100,-1); // 100 ints with value 1
It is working right. That's how list initializers work.
I believe 6.7.8.10 of the C99 standard covers this:
If an object that has automatic
storage duration is not initialized
explicitly, its value is
indeterminate. If an object that has
static storage duration is not
initialized explicitly, then:
if it has pointer type, it is initialized to a null pointer;
if it has arithmetic type, it is initialized to (positive or unsigned)
zero;
if it is an aggregate, every member is initialized (recursively) according
to these rules;
if it is a union, the first named member is initialized (recursively)
according to these rules.
If you need to make all the elements in an array the same non-zero value, you'll have to use a loop or memset.
Also note that, unless you really know what you're doing, vectors are preferred over arrays in C++:
Here's what you need to realize about containers vs. arrays:
Container classes make programmers more productive. So if you insist on using arrays while those around are willing to use container classes, you'll probably be less productive than they are (even if you're smarter and more experienced than they are!).
Container classes let programmers write more robust code. So if you insist on using arrays while those around are willing to use container classes, your code will probably have more bugs than their code (even if you're smarter and more experienced).
And if you're so smart and so experienced that you can use arrays as fast and as safe as they can use container classes, someone else will probably end up maintaining your code and they'll probably introduce bugs. Or worse, you'll be the only one who can maintain your code so management will yank you from development and move you into a full-time maintenance role — just what you always wanted!
There's a lot more to the linked question; give it a read.
u simply use for loop as done below:-
for (int i=0; i<100; i++)
{
a[i]= -1;
}
as a result as u want u can get
A[100]={-1,-1,-1..........(100 times)}
I had the same question and I found how to do, the documentation give the following example :
std::array<int, 3> a1{ {1, 2, 3} }; // double-braces required in C++11 (not in C++14)
So I just tried :
std::array<int, 3> a1{ {1} }; // double-braces required in C++11 (not in C++14)
And it works all elements have 1 as value. It does not work with the = operator. It is maybe a C++11 issue.
Can't do what you're trying to do with a raw array (unless you explicitly list out all 100 -1s in the initializer list), you can do it with a vector:
vector<int> directory(100, -1);
Additionally, you can create the array and set the values to -1 using one of the other methods mentioned.
Just use this loop.
for(int i =0 ; i < 100 ; i++) directory[i] =0;
the almighty memset() will do the job for array and std containers in C/C++/C++11/C++14
The reason that int directory[100] = {-1} doesn't work is because of what happens with array initialization.
All array elements that are not initialized explicitly are initialized implicitly the same way as objects that have static storage duration.
ints which are implicitly initialized are:
initialized to unsigned zero
All array elements that are not initialized explicitly are initialized implicitly the same way as objects that have static storage duration.
C++11 introduced begin and end which are specialized for arrays!
This means that given an array (not just a pointer), like your directory you can use fill as has been suggested in several answers:
fill(begin(directory), end(directory), -1)
Let's say that you write code like this, but then decide to reuse the functionality after having forgotten how you implemented it, but you decided to change the size of directory to 60. If you'd written code using begin and end then you're done.
If on the other hand you'd done this: fill(directory, directory + 100, -1) then you'd better remember to change that 100 to a 60 as well or you'll get undefined behavior.
If you are allowed to use std::array, you can do the following:
#include <iostream>
#include <algorithm>
#include <array>
using namespace std;
template <class Elem, Elem pattern, size_t S, size_t L>
struct S_internal {
template <Elem... values>
static array<Elem, S> init_array() {
return S_internal<Elem, pattern, S, L - 1>::init_array<values..., pattern>();
}
};
template <class Elem, Elem pattern, size_t S>
struct S_internal<Elem, pattern, S, 0> {
template <Elem... values>
static array<Elem, S> init_array() {
static_assert(S == sizeof...(values), "");
return array<Elem, S> {{values...}};
}
};
template <class Elem, Elem pattern, size_t S>
struct init_array
{
static array<Elem, S> get() {
return S_internal<Elem, pattern, S, S>::init_array<>();
}
};
void main()
{
array<int, 5> ss = init_array<int, 77, 5>::get();
copy(cbegin(ss), cend(ss), ostream_iterator<int>(cout, " "));
}
The output is:
77 77 77 77 77
Just use the fill_n() method.
Example
int n;
cin>>n;
int arr[n];
int value = 9;
fill_n(arr, n, value); // 9 9 9 9 9...
Learn More about fill_n()
or
you can use the fill() method.
Example
int n;
cin>>n;
int arr[n];
int value = 9;
fill(arr, arr+n, value); // 9 9 9 9 9...
Learn More about fill() method.
Note: Both these methods are available in algorithm library (#include<algorithm>). Don't forget to include it.
Starting with C++11 you could also use a range based loop:
int directory[10];
for (auto& value: directory) value = -1;