C++ float array initialization [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C and C++ : Partial initialization of automatic structure
While reading Code Complete, I came across an C++ array initialization example:
float studentGrades[ MAX_STUDENTS ] = { 0.0 };
I did not know C++ could initialize the entire array, so I've tested it:
#include <iostream>
using namespace std;
int main() {
const int MAX_STUDENTS=4;
float studentGrades[ MAX_STUDENTS ] = { 0.0 };
for (int i=0; i<MAX_STUDENTS; i++) {
cout << i << " " << studentGrades[i] << '\n';
}
return 0;
}
The program gave the expected results:
0 0
1 0
2 0
3 0
But changing the initialization value from 0.0 to, say, 9.9:
float studentGrades[ MAX_STUDENTS ] = { 9.9 };
Gave the interesting result:
0 9.9
1 0
2 0
3 0
Does the initialization declaration set only the first element in the array?

You only initialize the first N positions to the values in braces and all others are initialized to 0. In this case, N is the number of arguments you passed to the initialization list, i.e.,
float arr1[10] = { }; // all elements are 0
float arr2[10] = { 0 }; // all elements are 0
float arr3[10] = { 1 }; // first element is 1, all others are 0
float arr4[10] = { 1, 2 }; // first element is 1, second is 2, all others are 0

No, it sets all members/elements that haven't been explicitly set to their default-initialisation value, which is zero for numeric types.

Related

how to initialize a single value to whole array in cpp [duplicate]

This question already has answers here:
Initialization of all elements of an array to one default value in C++?
(12 answers)
Closed 3 months ago.
I'm trying to initialize a single value to whole array in c++.
For ex:- I want to initialize 1 in whole array by writing it by only once
I have tried to initializing 1 in whole array but it throws error , I'm expecting 1 in whole array.
ex- int array[5]={0};
output- 0 0 0 0 0
int array[5]={1};
output- 1 0 0 0 0
expecting- 1 1 1 1 1
if you want 1 value at very index you can do this by
int arr[5] = {1,1,1,1,1}; or
int arr[5];
arr[0] = 1;
arr[1] = 1;
arr[2] = 1;
arr[3] = 1;
arr[4] = 1;
otherwise if you write arr[5] = {1}; only first index will have value 1 rest will be assigned zero automatically like this {1,0,0,0,0}
or #include <iostream>
using namespace std;
int main()
{
int arr[5];
memset(arr, 1, sizeof(arr));
cout << arr;
return 0;
}
so type this code this memset function will fill all the index with value 1 by writing it only once.
hope this answer helps you.
Edited, try this code snippet working perfectly fine
#include <iostream>
#include <array>
int main () {
std::array<int,5> myarray;
myarray.fill(1);
std::cout << "myarray contains:";
for ( int& x : myarray) { std::cout << ' ' << x; }
std::cout << '\n';
return 0;
}

How to fill a random position of a size 10 1D array with 1s and 0s the rest

how i fill 10size 1d array randomly 1 and 0 the rest
like 0 0 0 0 0 1 0 0 0 0 or 0 0 0 1 0 0 0 0 0 0 or 0 1 0 0 0 0 0 0 0 0
#include <iostream>
#include<cstdlib>
#include<ctime>
#include<windows.h>
using namespace std;
int main() {
srand(time(NULL));
int x[10] = { 0, }, i;
while (true)
{
Sleep(500);
for (i = 0; i < 10; i++)
{
x[i] = rand() % 1 + 1;
cout << x[i];
}
system("cls");
}
system("pause");
}
I don't want 0 1 0 0 0 1 1 0 1 0 or 0 1 0 1 0 0 1 0 0 1
You are setting a new 1 every time your loop makes a lap. Eventually, you'll have all 1:s.
Either create a new zero-initialized array every loop or set the 1 back to 0 after you've printed the values in the array.
Sleep is not a standard C++ function. Use std::this_thread::sleep_for and std::chrono::milliseconds instead.
I also recommend using the new <random> library that was added in C++11:
Example setting it back to 0 after the result has been printed:
#include <array> // std::array, std::size
#include <chrono> // std::chrono::milliseconds
#include <iostream>
#include <random> // std::mt19937, std::uniform_int_distribution
#include <thread> // std::this_thread::sleep_for
auto& prng() {
// Create a static seeded PRNG to use everywhere in the program
thread_local std::mt19937 instance(std::random_device{}());
return instance;
}
int main() {
std::array<int, 10> x{}; // a nicer array
// Create a distribution for your random numbers to get random numbers
// in the range [0, 10)
std::uniform_int_distribution<unsigned> dist(0, std::size(x) - 1); // [0, 9]
for(int i = 0; i < 100; ++i) { // print 100 of these arrays
std::this_thread::sleep_for(std::chrono::milliseconds(500));
auto index = dist(prng()); // get a random index [0, 9]
x[index] = 1; // set the int at index to 1
// print the result
for(int v : x) std::cout << v;
std::cout << '\n';
x[index] = 0; // set it back to 0
}
}
Demo
Instatiate an array of int like int x[10] = {};, in this way you will get an array fill of zeros.
Than you can simply use rand() % 10, it will produce a random number in [0, 9], and it will be the position in the array where the 1 is:
srand(time(NULL));
int x[10] = {};
x[rand() % 10] = 1;
for (int i = 0; i < 10; i++) {
cout << x[i] << endl;
}

Creating multidimensional array on the heap

After some experiments I've come up with these four ways of creating multidimensional array on the heap (1 and 2 is kinda the same except that the result for 1 I wanted reference):
#include <memory>
#include <iostream>
template <typename T>
void printArr(T const &arr)
{
std::cout << typeid(T).name() << "\t";
for (int x = 0; x < 2; ++x)
for (int y = 0; y < 2; ++y)
for (int z = 0; z < 2; ++z)
std::cout << arr[x][y][z] << " ";
std::cout << std::endl;
}
int main()
{
int(&arr)[2][2][2] = reinterpret_cast<int(&)[2][2][2]>(*new int[2][2][2]{ { { 1,2 },{ 3,4 } }, { { 5,6 },{ 7,8 } } });
printArr(arr);
delete[] &arr;
int(*arr2)[2][2] = new int[2][2][2]{ { { 1,2 },{ 3,4 } },{ { 5,6 },{ 7,8 } } };
printArr(arr2);
delete[] arr2;
std::unique_ptr<int[][2][2]> arr3(new int[2][2][2]{ { { 1,2 },{ 3,4 } },{ { 5,6 },{ 7,8 } } });
printArr(arr3);
std::unique_ptr<int[][2][2]> arr4 = std::make_unique<int[][2][2]>(2);
printArr(arr4);
return 0;
}
Tested this on various online compilers without problems, so what I would like to know if they are valid ways as well?
Here is the demo https://ideone.com/UWXOoW and output:
int [2][2][2] 1 2 3 4 5 6 7 8
int (*)[2][2] 1 2 3 4 5 6 7 8
class std::unique_ptr<int [0][2][2],struct std::default_delete<int [0][2][2]> > 1 2 3 4 5 6 7 8
class std::unique_ptr<int [0][2][2],struct std::default_delete<int [0][2][2]> > 0 0 0 0 0 0 0 0
I think your first example is undefined behavior or at least would lead to undefined behavior as soon as you'd try to actually access the array through the reference arr.
new int[2][2][2] creates an array of two int[2][2]. It returns you a pointer to the first element of this array ([expr.new] ยง1). However, a pointer to the first element of an array and a pointer to the array itself are not pointer interconvertible. I'm not sure if there is a definitive answer yet to the philosophical question "does the act of dereferencing an invalid pointer itself already constitute undefined behavior?". But at least accessing the reference obtained from your reinterpret_cast should definitely violate the strict aliasing rule. The other three should be fine.
Edit:
As there still seems to be some confusion, here a more detailed explanation of my argument:
new int[2][2][2]
creates an array of two int[2][2] and returns a pointer to the first element of this array, i.e., a pointer to the first int[2][2] subobject within this array and not the complete array object itself.
If you want to get an int(*)[2][2][2] from new, you could, e.g., do
new int[1][2][2][2]

Generate a pattern for i-th order partial derivative in d-dimension

I am trying to work out a finite element code, where I need to compute the partial derivatives in d dimension. In finite element the basis function N(x,y,z)=N(x)N(y)N(z), so the first order derivatives are:
N(x)'N(y)N(z) N(x)N(y)'N(z) N(x)N(y)N(z)'
second order derivatives are
N(x)''N(y)N(z) N(x)'N(y)'N(z) N(x)'N(y)N(z)' N(x)N(y)''N(z) N(x)N(y)N(z)' N(x)N(y)N(z)''
I want to have a functions with input (i,d) to tell me these patterns in the table below:
I think there must be a simple algorithm to realize this goal. Can someone gives me some help? THx
This can be solved with nested loops:
int * part_deriv(int i, int d){
int *res;
int *curr;
int num_el = fact(i+d-1) / ( fact(i) * fact(d-1) ); //fact() is the factorial function
int el_size = d*sizeof(int);
int el;
res = calloc(num_el,el_size);
curr = calloc(d,sizeof(int));
*curr = i;
memcpy(res,curr,el_size); //put the first element in the array
el = 0;
while(el<num_el){
if(*curr != 0){
for( d_idx = 1 ; d_idx<d ; d_idx++, *cur++){
*curr--; // "move" one derivative from the first variable to 'd_idx' variable
*(curr+d_idx)++;
el++;
memcpy(res+(el*el_size),curr,el_size); //put the element in the array
}
*curr--;
} else{
break; //shouldn't be reached, but added to be sure
}
}
return res;
}
I havn't completely understood how you want to output the result, so you can parse the array I output in blocks of d.
Consider the pattern for i'th derivative as base-i+1 integers. Nice sequences emerge. For example, in a two-dimensional case, they are
0
2, 1
6, 4, 2
12, 9, 6, 3
20, 16, 12, 8, 4
etc.
I realized it by recursive by calling a function.
#include <vector>
#include <iostream>
using namespace std;
void func (int d, int i, vector<int> &k, int n, int start, vector<vector<int>> &a){
if (n==i)
{
vector<int> m;
int it=0;
for(int it1=0;it1<d;++it1){
int amount=0;
while(find(k.begin(),k.end(),it)!= k.end()){
amount++;
it++;
}
m.push_back(amount);
it++;
}
a.push_back(m);
}
else{
for(int jj=start;jj<d+i-(i-n);++jj){
k[n]=jj;
func(d,i,k,n+1,jj+1, a
);
}
}
}
vector<vector<int>> test(int d, int i){
vector<int> kk(i);
vector<vector<int>> a;
func(d,i,kk,0,0, a);
return a;
}
int main(){
auto f = test(4,2);
for(auto it1=f.begin();it1!=f.end();++it1){
for(auto it2= it1->begin();it2!=it1->end();++it2)
cout<<*it2<<" ";
cout<<endl;
}
}
Here is my result for i=2,d=4:
2 0 0 0
1 1 0 0
1 0 1 0
1 0 0 1
0 2 0 0
0 1 1 0
0 1 0 1
0 0 2 0
0 0 1 1
0 0 0 2

Evaluation order in initialization

In the following program:
#include <iostream>
struct I {
int i;
I(){i=2;}
I(int _i){i=_i;}
};
int a[3] = {a[2] = 1};
int aa[3][3] = {aa[2][2] = 1};
I A[3] = {A[2].i = 1};
I AA[3][3] = {AA[2][2].i = 1};
int main(int argc, char **argv) {
for (int b : a) std::cout << b << ' ';
std::cout << '\n';
for (auto &bb : aa) for (auto &b : bb) std::cout << b << ' ';
std::cout << '\n';
for (auto &B : A) std::cout << B.i << ' ';
std::cout << '\n';
for (auto &BB : AA) for (auto &B : BB) std::cout << B.i << ' ';
std::cout << '\n';
return 0;
}
The output is
1 0 0
1 0 0 0 0 0 0 0 1
1 2 2
1 2 2 2 2 2 2 2 2
from http://ideone.com/1ueWdK with clang3.7
but the result is :
0 0 1
1 0 0 0 0 0 0 0 1
1 2 2
1 2 2 2 2 2 2 2 2
on http://rextester.com/l/cpp_online_compiler_clang also with clang 3.7.
On my own ubuntu, gcc 6.2 givs an internal compiler error on the construct int aa[3][3] = {aa[2][2] = 1}.
I'm assuming this is undefined behavior, but cannot find a definitive statement in the standard.
The question is:
Whether the evaluation order of the side effects on the assignment in the initializer list (e.g. a[2] = 1) and initialization of the actual element of the array (e.g. a[2]) defined in the standard?
It is explicitly stated as defined or undefined? Or does it become undefined just because it is not explicitly defined?
Or does the construct has defined or undefined behavior due to other reason aside from the evaluation order?
Let's start with the simplest case:
I A[3] = {A[2].i = 1};
I AA[3][3] = {AA[2][2].i = 1};
Both of these are UB, due to a violation of [basic.life]. You are accessing the value of an object before its lifetime has begun. I does not have a trivial default constructor, and therefore cannot be vacuously initialized. Therefore, the object's lifetime only begins once a constructor has completed. The elements of the A array have not yet been constructed when you are accessing elements of that array.
Therefore, you are invoking UB by accessing a not-yet-constructed object.
Now, the other two cases are more complex:
int a[3] = {a[2] = 1};
int aa[3][3] = {aa[2][2] = 1};
See, int permits "vacuous initialization", as defined by [basic.life]/1. Storage for a and aa has been acquired. Therefore, int a[3] is a valid array of int objects, even though aggregate initialization has not yet begun. So accessing the object and even setting its state is not UB.
The order of operations here is fixed. Even pre-C++17, the initialization of the elements of the initializer list is sequenced before the aggregate initialization is invoked, as stated in [dcl.init.list]/4. Elements in the aggregate which are not listed in the initialization list here will be filled in as if by typename{} constructs. int{} means to value-initialize an int, which results in 0.
So even though you set a[2] and aa[2][2], they should immediately be overwritten via aggregate initialization.
Therefore, all of these compilers are wrong. The answer should be:
1 0 0
1 0 0 0 0 0 0 0 0
Now granted, this is all very stupid and you shouldn't do it. But from a pure language perspective, this is well-defined behavior.