How do I stop my array from printing address? - c++

I have a header, cpp and main class.
//Arr.h
class Arr
{
public:
void setArr();
void printArr();
private:
int x[5];
};
//Arr.cpp
#include "Arr.h"
#include <iostream>
using namespace std;
void Arr::setArr()
{
int x[5] = { 2, 3, 5, 7, 11 };
}
void Arr::printArr()
{
for (int i = 0; i < 5; i++)
{
cout << x[i] << "\n";
}
}
//main.cpp
int main()
{
Arr a;
a.setArr();
a.printArr();
}
However, when I run the code, a.printArr() prints out array address and not the values contained in the array. Is there a way to fix this?

Your code will print not address but some indeterminate value generated via default-initializing. Initialize the member array instead of the local array to throw away.
void Arr::setArr()
{
x[0] = 2;
x[1] = 3;
x[2] = 5;
x[3] = 7;
x[4] = 11;
}

Your problem is here:
void Arr::setArr()
{
int x[5] = { 2, 3, 5, 7, 11 };
}
the declaration int x[5] defines a new array of 5 elements which will be destroyed on exiting that function; and the name x hides the data member Arr::x.
One way you can do it is this:
void Arr::setArr()
{
/*static*/ auto arr = { 2, 3, 5, 7, 11 };
std::copy(arr.begin(), arr.end(), x);
}
Full code:
#include <iostream>
#include <algorithm>
class Arr
{
public:
void setArr();
void printArr();
private:
int x[5];
};
using namespace std;
void Arr::setArr()
{
/*static*/ auto arr = { 2, 3, 5, 7, 11 };
std::copy(arr.begin(), arr.end(), x);
}
void Arr::printArr()
{
for (int i = 0; i < 5; i++)
{
cout << x[i] << "\n";
}
}
//main.cpp
int main()
{
Arr a;
a.setArr();
a.printArr();
}

Your code is not printing array address. Maybe you saw some unexpected numbers and assumed it was an address, but in fact it is undefined behaviour caused by outputting uninitialized variables.
Your code int x[5] = .... failed because this declares a new local variable x, it doesn't modify the class member x.
Perhaps you tried:
x = { 2, 3, 5, 7, 11 };
and got compilation errors. This is because C-style arrays may not be assigned. This annoying rule is a hangover from C++'s past. To avoid this problem and many others, you can try to avoid using C-style arrays. In this case use a C++ array:
private:
std::array<int, 5> x;
Then the suggested assignment will work.

As WhiZTiM has already pointed out, your problem is at the setArr function in your class. The reason for this is because in C++ you cannot assign values to the array in the "normal fashion" i.e. using x = {blah, blah, blah}; (unless you use std::array<int, ARRAYSIZE>). In setArr you are creating another array named x and then this array is deleted once it is out of scope, and in printArr you are printing an array with no values in it yet.
Each value in the array must be set individually in C styled arrays (as shown in MikeCAT's answer).
One solution to this is to create a temporary array with the values you want and assigning the values to your class array through a for loop, i.e.:
void Arr::setArr() {
const int ARRAYSIZE = 5;
int tmp[ARRAYSIZE] = {2, 3, 5, 7, 11};
for (int i = 0; i < ARRAYSIZE; ++i) {
x[i] = tmp[i];
}
}
As M.M also pointed out, can simply change int x[5] in your private variables in Arr to std::array<int, 5> x and then in setArr simply have the statement: x = {2, 3, 5, 7, 11}; which is the better option in my opinion and easier to read, but it's also good to know how to use C arrays 😊

Related

Copying one int array to another C++

Was trying to write a program which converts the value`s from one assigned array to another unassigned one. The code i wrote:
#include "stdafx.h";
#include <iostream>;
using namespace std;
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int j[10];
int copy_array(int *p1, int n);
int *p2, *p2;
int main() {
for (int l = 0; l < 10; l++) {
cout << a[l] << endl;
}
copy_array(a, 10);
for (int i = 0; i < 10; i++) {
j[i] = &p2;
cout << j[i] << endl;
}
system("PAUSE");
return 0;
}
int copy_array(int *p1, int n) {
while (n-- > 0) {
*p1 = *p2;
*p1++;
*p2++;
}
}
Im using the Microsoft visual studio platform and the error i got was "There is no context in which this conversion is possible". Why i cant use this int convert path? how can i fix and connect the 2 arrays using int type conversion(if its possible)?
What i tried was manipulating the local function copy_array so it makes the conversion using the addresses of the j[10] array integers, but this gave me another error. Any support and advice would be appreciated.
These are some notes on your code:
you have redundant p2 declaration:int *p2, *p2;. Also you need to initialize it. so make it: int *p2 = j; (in fact, you don't actually need to use this global variable - you can achieve the same effect by passing j as necessary).
Inside your copy function, your assignment should be in reverse:
*p2 = *p1; not *p1 = *p2; - the right-hand side is assigned to the left hand side.
When printing j, you do not need j[i] = &p2; which alters j's contents.
It is better to define the arrays inside the function not in the general scope.
Correct them and your code should work fine.
However, You do not need pointers to do this at all.
Consider the following code and compare it to yours:
#include <iostream>
using namespace std;
void copy_array(int [], int [], int);
void print_array(int [], int);
int main() {
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int j[10];
print_array(a,10);
copy_array(a, j, 10);
print_array(j,10);
return 0;
}
void copy_array(int s[], int d[], int n) {
for (int i = 0; i < n; i++)
d[i] = s[i];
} // s for source & d for destination
void print_array(int arr[], int n) {
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << "\n\n";
}
You don't need p2 to be global.
Just add parameter to copy_array.
like this:
void copy_array(int *p1, int *p2, int n) {
while (n-- > 0) {
*p1 = *p2;
p1++;
p2++;
}
}
and call like this:
copy_array(j, a, 10);
Also: to print the copy you just do:
for (int i = 0; i < 10; i++) {
cout << j[i] << endl;
}
I want to build on #Shadi's answer, which you should upvote, and make the code more C++-idiomatic.
In C++, we don't need to explicitly return 0; from main; it is implied, if you haven't returned anything else.
It's better to use names in a similar scheme for similar variables. Specifically, i and j are common variable names for integer scalars, e.g. counters - not arrays. I'd suggest you use a and b for the arrays, or values and copy_of_values etc.
The C++ standard library has an array-like container class named std::vector. It's not exactly the same as an array; for example, it uses dynamically-allocated memory, and can grow or shrink in size. The reason you might want to use it is that it allows you to perform plain assignment, and use other standard library facilities with it.
Thus Shadi's program becomes:
#include <iostream>
#include <vector>
void print_vector(const std::vector<int>& vec);
int main() {
std::vector<int> a { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> b;
print_vector(a);
b = a;
print_vector(b);
}
void print_vector(const std::vector<int>& vec) {
// this next line uses syntax from the 2011 version of
// the C++ language standard ("C++11").
for(int x : vec) {
std::cout << x << " ";
}
std::cout << "\n\n";
}
You can also avoid the loop in print_vector entirely, using std::for_each or std::for_each_n, but that would require some knowledge of iterators and lambda functions, which may be a bit advanced for a beginner, so I won't go into that. But better yet, you could define a out-streaming operator for std::vector's, as seen here, with which you could write std::cout << a; and have that work.

Using arithmetic with arrays

Two quantities u and v are said to be at right angles if
nuv = u1v1 + u2v2 + u3v3 + u4v4 +………… + unvn = 0
Write a function that computes whether u and v are at right angles. You may use arrays if you wish. The function can assume that the vectors have the same dimension (n, say), but this number should be passed as a parameter to the function.
I have a few errors in my program. I'd appreciate some help, as I'm a beginner. The errors are telling me:
In function 'void function(int*,int*)'
cpp 26: error expected ';' before '}' token
cpp 29: error ;value required as left operand of assignment
#include <iostream>
using namespace std;
const int n = 5;
void function(int array[n],int array2[n]);
int main(){
int array[n] = {5, 3 , -4, 2, 8};
int array2[n] ={-7, -9, 5, 2, 9};
function(array, array2);
return 0;
}
void function(int array[n], int array2[n]){
int multiple;
for(int i=0; i <=5, i++)
{
(array[i]*array2[i]) + (array[i+1]*array2[i+1]) = multiple;
}
cout << multiple << endl;
}
Your for loop is malformed. You need to use < instead of <=, use n instead of 5, and use ; instead of ,.
Your assignment of multiple is backwards. The value on the right-side of the = operator is assigned to the variable on the left-side of =. You are trying to assign the value of multiple (which is uninitialized) to a dynamically computed value that has no explicit variable of its own. You should be assigning the computed value to multiple instead.
Also, you didn't follow the "this number [array dimensions] should be passed as a parameter to the function" requirement of your instructions.
Try this:
#include <iostream>
using namespace std;
const int n = 5;
void function(const int *array1, const int *array2, const int size);
int main()
{
int array1[n] = { 5, 3, -4, 2, 8};
int array2[n] = {-7, -9, 5, 2, 9};
function(array1, array2, n);
return 0;
}
void function(const int *array1, const int *array2, const int size)
{
int multiple = 0;
for(int i = 0; i < size; i++)
{
multiple += (array1[i] * array2[i]);
}
cout << multiple << endl;
}
Syntax error is where you are using the for loop in this fashion:
for(int i=0;i<=5,i++)
Use this instead:
for(int i=0; i <= 5; i++)
The function can assume that the vectors have the same dimension (n,
say), but this number should be passed as a parameter to the
function.
This function declaration
void function(int array[n],int array2[n]);
does not include a parameter that specifies the dimension of the arrays.
The above declaration is equivalent to
void function(int *array,int *array2);
because arrays passed by value are implicitly converted to pointers to their first elements.
There are a typo and a bug in this for statement
for(int i=0; i <=5, i++)
^^^^^^
There shall be
for ( int i=0; i < n; i++)
The variable multiple
int multiple;
is not initialized and this assignment
(array[i]*array2[i]) + (array[i+1]*array2[i+1]) = multiple;
does not have sense and has nothing common with the condition
nuv = u1v1 + u2v2 + u3v3 + u4v4 +………… + unvn = 0
It seems what you mean is the following
#include <iostream>
bool function( const int array[], const int array2[], size_t n )
{
long long int product = 0;
for ( size_t i = 0; i < n; i++)
{
product += array[i] * array2[i];
}
return product == 0;
}
int main()
{
const size_t N = 5;
int array[N] = { 5, 3 , -4, 2, 8 };
int array2[N] = { -7, -9, 5, 2, 9 };
std::cout << "array and array2 are "
<< (function(array, array2, N) ? "" : "not ")
<< "at right angles"
<< std::endl;
return 0;
}
These arrays
int array[N] = { 5, 3 , -4, 2, 8 };
int array2[N] = { -7, -9, 5, 2, 9 };
are not a right angles,
But these arrays
int array[N] = { 5, 3 , -4, 1, 9 };
int array2[N] = { -7, -9, 5, 1, 9 };
are at right angles. Try them.
Alternative: try the C++ way. Use std::array that knows it's length. Use algorithms provided by the standard library like std::inner_product.
#include <iostream>
#include <algorithm>
#include <array>
#include <numeric>
int main()
{
using arr_t = std::array<int,5>;
arr_t arr1 = {5, 3 , -4, 2, 8};
arr_t arr2 = {-7, -9, 5, 2, 9};
int mult = std::inner_product( begin(arr1), end(arr1), begin(arr2), 0,
std::plus<>(), std::multiplies<>() );
std::cerr << mult << "\n";
}

C++: Change value of variable using its pointer

Let's say I have the following funciton:
void part(T* arr){
//some function
int x[5] = {1,2,3,4,5};
arr = x;
}
where original:
int arr[5] = {0,0,0,0,0}
I would like to know, how can I change the value of original arr inside the function to be some other value (lets say x)?
Thanks
To achieve this, you would need to copy elements from the array x to arr:
std::copy(x, x + sizeof(x) / sizeof(x[0]), arr);
However, as a general advice, don't use raw pointers to represent an array of objects. You could use std::array instead and then you can use it's operator= to copy all elements.
#include <iostream>
#include <array>
void part(std::array<int, 5>& arr)
{
std::array<int, 5> x {{1, 2, 3, 4, 5}};
arr = x;
}
int main()
{
std::array<int, 5> arr;
part(arr);
for (const auto& val : arr) {
std::cout << val << " ";
}
}
LIVE
You were close.
void part(T* arr){
//some function
int x = 5;
*arr = x;
}
You just need to add a * in front of arr which means the value pointed to by that pointer. If you just say arr that means the actual address which you do not want to be changing.
Looks like you changed the question while I was writing my answer.
In this case you need a loop.
void part(T* arr){
//some function
int x[5] = {1,2,3,4,5};
for(int i = 0; i < 5; i++)
{
arr[i] = x[i];
}
}

Passing array to function with dynamic declaration of array in C/C++

I want to pass array to function in C/C++ without declaring and assigning it previously.
As in C# we can:
fun(new int[] {1, 1}); //this is a function call for void fun(int[]) type function
I am not very sure about the correctness of the above code. But I had done something like this in C#.
How can we pass array to function using dynamic declaration (on the spot declaration)??
I'd tried it using following way. But no luck
fun(int {1,1});
fun(int[] {1,1});
fun((int[]) {1,1});
can't we do so..??
In C99 and later, this:
foo((int[]){2,4,6,8});
is approximately the same as this:
int x[] = {2,4,6,8};
foo(x);
Prior to C99, this is not possible. C++ does not support this syntax either.
In C++11, you can use an initializer list:
#include <initializer_list>
#include <iostream>
void fun(std::initializer_list<int> numbers)
{
for (int x : numbers)
std::cout << x << ' ';
std::cout << '\n';
}
int main()
{
fun( {2, 3, 5, 7, 11, 13, 17, 19} );
}
This is possible in ANSI C99 and C11, but not in C89.
May I suggest using a variable argument list?
The declaration syntax would be as follows:
void Function(int Count, ...) {
va_list va;
va_start(va, Count);
for(int i = 0; i < Count; ++i) {
int nextVar = va_arg(va, int);
//Do some stuff with the array element
}
va_end(va);
}
This function is called with:
Function(4, 2, 3, 1, 5);
2, 3, 1 and 5 are the 'array elements'.
Alternatively, if you 'need' an array to go through within that function, it's easy to move the variable list to a proper (dynamic) array, by using new and delete.
Within the va-function:
int *Array = new int[Count];
for(int i = 0; i < Count; ++i) {
Array[i] = va_arg(va, int);
}
//Do Stuff with Array
delete[] Array;

Why won't this array initialize?

This is essentially what I'm trying to do, but not the actual source code.
namespace namespace {
int array [3];
}
namespace::array={1,2,3}
my gcc asks for an expression, and I'm not sure of what to do. Must I namespace::array[1]; each individual element?
You can only use an initializer list in a definition:
int array[3] = { 1, 2, 3 };
If you use:
int array[3];
then you need to initialize the array in a function, using
array[0] = 1;
array[1] = 2;
array[2] = 3;
Although it an odd mixture of C99 and C++, gcc allows this:
#include <string.h>
int a[3];
int main()
{
memcpy(a, (int[3]){ 1, 2, 3}, sizeof(a));
}
!
How about namespace ns { int array[3] = {1, 2, 3}; }?
There are several ways:
1) Explicitly set values for each element:
namespace ns {
int array [3];
}
ns::array[0]=1;
ns::array[1]=2;
ns::array[2]=3;
\\ or if they should contain consequtive values:
\\ for (size_t i = 0; i < 3; ++i)
\\ ns::array[i] = i + 1;
2) If you want initialize static array in place of its declaration, then you could move it initializer list as follows:
namespace ns {
int array[3] = {1, 2, 3};
}
3) Use typedef:
namespace ns {
typedef int array_t[3];
}
ns::array_t array = {1, 2, 3};
3) Also you can make some research of std::tr1::array, which may be used as such:
std::tr1::array<int, 3> arr = {1, 2, 3};