Simple array understanding - c++

I have a simple array in c++ which show me a strange result for default values of array.
#include <iostream>
using namespace std;
int arr [] = {2,3};
int main ()
{
for ( int n=0 ; n<10 ; ++n ) {
cout<< arr[n]<<",";
}
}
The result of which I should receive is 2,3,0,0,0,0,0,0,0,0, but get this result 2,3,0,0,0,0,0,0,809998728,32588, can someone explain to me why?

Declare the array the following way
int arr [10] = {2,3};
Otherwise when it is declared like this
int arr [] = {2,3};
it has only two elements.
In any case the program would look better if it was written like
#include <iostream>
int main()
{
const size_t N = 10;
int arr[N] = { 2, 3 };
for ( size_t n = 0 ; n < N ; ++n ) std::cout << arr[n] << ",";
std::cout << std::endl;
}

Related

How do I print the following array to show number 1 - 1000000

I want to initialize an array and fill it from 1-1000000. How do I then print the array?
#include<iostream>
using namespace std;
const int holder = 1000000;
int main()
{
int i = 0;
int nums[holder] = {0};
for( int i = 0; i < holder; i++)
{
nums[i] = i+1;
}
return 0;
}
How about something like this:
// First create a vector containing holder elements
std::vector<int> nums(holder);
// Then set each element to the number from 1 to holder, inclusive
std::iota(begin(nums), end(nums), 1);
Then to print it:
// Print each number in the vector, separated by newlines
for (auto num : nums)
{
std::cout << num << '\n';
}
Many parts of this answer should really be part of any decent beginners book. The only "new" thing would be the std::iota call.

Why am I getting zero in the output?

So I'm trying to swap two numbers without using a third variable. I pass the two numbers I'm trying to swap by reference. When the same number is to be swapped (like 1 is to be swapped with 1), I get an output of zero. I know how to fix this, but I'm unable to understand as to why I keep getting 0 when a and b are the same.
Can anyone explain why I'm getting zero instead of the swapped numbers?
void swap(int *a,int *b)
{
//if(a==b)
// return;
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
int main()
{
int n=3,x=0,y=0;
int a[n][n];
for(int i=0;i<n;i++)
swap(&a[x][i],&a[i][y]);
return 0;
}
It seems you are trying to swap elements of the first row with elements of the first column.
For starters variable length arrays is not a standard C++ feature. Though some compilers have their own language extensions you should avoid their using.
Also the swap function can have undefined behavior because when there is an overflow of a signed integer then the result is undefined. It is better to use the standard C++ function std::swap.
And in your program you are using an uninitialized array.
Here is a demonstrative program that shows how you could write the code
#include <iostream>
#include <utility>
int main()
{
const size_t N = 3;
int a[N][N];
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
a[i][j] = i * N + j;
}
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
for ( size_t i = 0; i < N; i++ )
{
std::swap( a[0][i], a[i][0] );
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
Its output is
0 1 2
3 4 5
6 7 8
0 3 6
1 4 5
2 7 8
If you want to write your own swap function then write it like
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
and use it in the program like
::swap( &a[0][i], &a[i][0] );
As far as i understood your code. You are trying to swap first row elements with its corresponding elements in the first column..
You are getting 0 at position a[0][0] in the matrix.
The reason is simple..
Look at this steps in your code
*b=*a-*b;
*a=*a-*b;
You are substracting same from that value..
Obviously result will be 0.
And yeh the idea of swapping row with column is really creative 👍👍👍

Finding the highest number in an array of length 5

This should be really simple, but I'm used to higher level languages and am missing something. I'm just trying to make sure the input is five numbers long, and then find the highest number. Unfortunately, something goes wrong in that second part.
#include <iostream>
#include <string>
bool isFiveDigits(int num) {
if (std::to_string(num).length() == 5) {
return true;
} else {
return false;
}
}
int highestInArr(int *nums) {
int highest = nums[0];
for (int i = 1; i < sizeof(nums); i++) {
int temp = nums[i];
if (temp > highest) {
highest = temp;
}
}
return highest;
}
int main() {
using namespace std;
int num;
int nums [5];
cout << "Enter a five digit number!\n";
cin >> num;
if (!isFiveDigits(num)) {
cout << "Not five digits, can you even count?";
return 1;
}
string numstr = to_string(num);
for (int i = 0; i < numstr.length(); i++) {
cout << numstr[i] << " ";
nums[i] = (int)numstr[i];
}
cout << "\n" << highestInArr(nums);
}
When this runs, I get:
Enter a five digit number!
12345
1 2 3 4 5
1424080487
Of course, 1,424,080,487 is not in [1, 2, 3, 4, 5].
You cannot pass a pointer into a function and get the size of it without template deduction. At runtime, all the function receives is a pointer. When you call sizeof(nums), you are not getting the size of the original array. You are simply getting the size of the pointer, which is the same as saying sizeof(int_ptr). Instead, you should be using a std::vector when using collections whose sizes are dynamic.
Now, you CAN receive the size by doing something like this:
#include <iostream>
template<typename num_t, size_t N>
num_t max_num(num_t(&arr)[N]) {
num_t m = (num_t)0;
for (size_t i = 0; i < N; ++i)
if (arr[i] > m)
m = arr[i];
return m;
}
int main(){
int foo[] = { 1, 5, 2, 4, 3 };
int m = max_num(foo);
std::cout << m << std::endl;
std::cin.get();
return 0;
}
However, this is not necessarily preferred and assumes that the array was created on the caller's stack. It does not work for dynamically allocated arrays that were created with new[]. If you do this multiple times with different sizes, you will have multiple implementations of the same function (that's what templates do). The same goes for using an std::array<int, N>. If you use N as a size_t template parameter, it will do the same thing.
There are two preferred options:
Send the size of the array into the function so that the caller is responsible for the size.
Use a different container such as std::vector so the callee is responsible for the size.
Example:
#include <vector>
#include <iostream>
#include <algorithm>
int main(){
std::vector<int> vec{ 1, 5, 2, 4, 3 };
int m = *std::max_element(std::cbegin(vec), std::cend(vec));
std::cout << m << std::endl;
std::cin.get();
return 0;
}
As for the is_5_digits, you should use the base-10 logarithm function.
#include <cmath>
// ...
int i = 12345;
size_t length = (i > 0 ? (int)log10(i) : 0) + 1;
std::cout << length << std::endl; // prints 5;
First of all, you can't simply convert a char to int just like (int)numstr[i] assuming that it will return the digit which it contains.
See, if you have a char '0', it means it's ASCII equivalent is stored, which is 48 in case of 0, 49 in case of '1' and so on.
So in order to get that digit (0,1,2,...,9), you've to substract 48 from the ASCII value.
So change this line:
nums[i] = (int)numstr[i];
to:
nums[i] = (int)numstr[i] - 48; // or nums[i] = (int)numstr[i] - '0';
And another thing, in your highestInArr function, you're getting a pointer as parameter, and in the function, you're using sizeof to determine the size of the array. You can't simply do that, the sizeof will return the size of int*, which is not the size of the array, so you've to pass size as the second argument to the function, and use it in the loop.
Like this:
int highestInArr(int *nums, int size) {
// ...
for (int i = 1; i < size; i++) {
// ...
}
// ...
}

Not sorting of struct using arrays

It seems to be a simply exercise, but something doesn't work with the following qsort algorithmus. The struct abcSort correctly shows all assigned values. Unfortunately, the qsort is not sorting anything.
typedef int(*compfn)(const void*, const void*);
struct ABCSort
{
int svSort[10];
string itemSort[10];
};
struct ABCSort abcSort;
int compare(struct ABCSort*, struct ABCSort*);
void mainSort()
{
for (int i = 0; i < 10; i++)
{
abcSort.svSort[i] = 100 - i;
abcSort.itemSort[i] = arrayREAD[i][2];
}
qsort( (void*)&abcSort, 10, sizeof(struct ABCSort), (compfn)compare );
}
int compare(struct ABCSort *elem1, struct ABCSort *elem2)
{
if (elem1->svSort< elem2->svSort)
return -1;
else if (elem1->svSort > elem2->svSort)
return 1;
else
return 0;
}
You have build two arrays of integer and strings and you want to sort them by the numbers, keeping the initial pairing. That's the first problem, you should have created one array of structs, each struct containg a number and a string and a function that compares the integer member of that struct to obtain the sort order.
You also tagged this question as C++ but you are using qsort, arrays and function pointers like C, so I'll present two complete C programs that solve your problem.
Let's see, using an array of structs, what your code could be like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 6
#define CMAX 15
typedef int(*cmp_fn)(const void*, const void*);
typedef struct {
int num;
char str[CMAX];
} numABC;
int comp_struct(const numABC *lhs, const numABC *rhs ) {
if ( lhs->num < rhs->num )
return -1;
if ( lhs->num > rhs->num )
return 1;
return 0;
}
int main(void) {
numABC myArray[MAX] = { {6, "cat"}, {4, "dog"}, {8, "panter"},
{2, "red fish"}, {1, "hawk"}, {6, "snake"} };
int i;
// sort the array of structs by int member
qsort(myArray, MAX, sizeof(numABC), (cmp_fn)comp_struct);
// print out the sorted array
printf("\nSort by numbers:\n");
for ( i = 0; i < MAX; ++i ) {
printf("%d %s\n",myArray[i].num,myArray[i].str);
}
return 0;
}
If you want to use this code, but you have a couple of arrays instead, one option is to convert those arrays:
int nums[MAX] = {6,4,8,2,1,3};
char str[MAX][CMAX] = {"cat","dog","panter","red fish","hawk","snake"};
int i;
// create the array of structs from the two arrays
numABC myArray[MAX];
for ( i = 0; i < MAX; ++i ) {
myArray[i].num = nums[i];
strcpy(myArray[i].str, str[i]);
}
Another option to sort two different arrays (mantaining the pairing or alignment between the two) is to use a more complicated method which consists in sorting an array of indeces instead. to keep the relationships between the two original arrays I'll have to use global variables which can be accessed inside the compare function(s). Once the indeces are sorted, the original arrays are changed accordingly.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 6
#define CMAX 15
const size_t I_DIM = MAX * sizeof(int);
const size_t SS_DIM = MAX * sizeof(char*);
const size_t S_DIM = MAX * CMAX;
// global variables needed to perform comparisons
int *pg_int;
char **pg_str;
typedef int(*cmp_fn)(const void*, const void*);
int comp_num(const int *lhs, const int *rhs ) {
if (pg_int[*lhs] < pg_int[*rhs])
return -1;
if (pg_int[*lhs] > pg_int[*rhs])
return 1;
return 0;
}
int comp_str(const int *lhs, const int *rhs ) {
return strcmp(pg_str[*lhs],pg_str[*rhs]);
}
int main(void) {
int nums[MAX] = {6,4,8,2,1,3};
char str[MAX][CMAX] = {"cat","dog","panter","red fish","hawk","snake"};
int i;
// create an array of indeces
int index[MAX];
for ( i = 0; i < MAX; ++i ) {
index[i] = i;
}
// set global copies
pg_int = malloc(I_DIM);
memcpy(pg_int,nums,I_DIM);
pg_str = malloc(SS_DIM);
pg_str[0] = malloc(S_DIM);
memcpy(pg_str[0],str[0],S_DIM);
for ( i = 1; i < MAX; i++ ) {
pg_str[i] = pg_str[0] + i * CMAX;
}
// sort the indeces ordering by ints
qsort(index, MAX, sizeof(int), (cmp_fn)comp_num);
//update the two arrays
for ( i = 0; i < MAX; ++i ) {
nums[i] = pg_int[index[i]];
strcpy(str[i],pg_str[index[i]]);
}
// print out sorted couples
printf("Sort by numbers:\n");
for ( i = 0; i < MAX; ++i ) {
printf("%d %s\n",nums[i],str[i]);
}
// sort the indeces ordering by strings
qsort(index, MAX, sizeof(int), (cmp_fn)comp_str);
//update the two arrays
for ( i = 0; i < MAX; ++i ) {
nums[i] = pg_int[index[i]];
strcpy(str[i],pg_str[index[i]]);
}
// print out sorted couples
printf("\nSort by strings:\n");
for ( i = 0; i < MAX; ++i ) {
printf("%d %s\n",nums[i],str[i]);
}
free(pg_int);
free(pg_str[0]);
free(pg_str);
return 0;
}
The output (sorry for the silly example) is:
Sort by numbers:
1 hawk
2 red fish
3 snake
4 dog
6 cat
8 panter
Sort by strings:
6 cat
4 dog
1 hawk
8 panter
2 red fish
3 snake
If you want to accomplish the same task in C++ you should take advantage of the Standard Library and use std::vector as a container and std::sort as algorithm:
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::string;
using std::cout;
struct numABC {
double num;
string str;
// instead of a compare function I can overload operator <
friend bool operator<( const numABC &lhs, const numABC &rhs ) {
return lhs.num < rhs.num;
}
};
// or use a lambda
auto cmp_str = []( const numABC &lhs, const numABC &rhs ) -> bool {
return lhs.str < rhs.str;
};
int main() {
vector<numABC> my_data = { {3.6, "cat"}, {5.7, "dog"}, {7.1, "panter"},
{0.2, "red fish"}, {1.8, "hawk"}, {1.1, "snake"}};
std::sort(my_data.begin(), my_data.end());
std::cout << "Sort by numbers:\n";
for ( auto & s : my_data ) {
std::cout << s.num << ' ' << s.str << '\n';
}
std::sort(my_data.begin(), my_data.end(), cmp_str);
// passing a lambda to specify how to compare ^^
std::cout << "Sort by strings:\n";
// if you don't like c++11 range for:
for ( int i = 0; i < my_data.size(); ++i ) {
std::cout << my_data[i].num << ' ' << my_data[i].str << '\n';
}
return 0;
}
Note that I have initialized my_data as a vector of objects of type numABC. If you have to start from two arrays, you can create the vector like this:
vector<double> nums = {3.6, 5.7, 7.1, 0.2, 1.8, 1.1};
vector<string> str = {"cat", "dog", "panter", "red fish", "hawk", "snake"};
vector<numABC> my_data;
for ( int i = 0; i < nums.size(); ++i ) {
my_data.push_back(numABC{nums[i],str[i]});
}
After sorting, if you have to extract the two vectors again (instead of simply looping through my_data) you can do something like this:
for ( int i = 0; i < my_data.size(); ++i ) {
nums[i] = my_data[i].num;
str[i] = my_data[i].str;
}
Alternatively you could implement an algorithm similar to the one I used before and sort the two vectors nums and srt using an auxiliary vector of indeces:
vector<double> nums = {3.6, 5.7, 7.1, 0.2, 1.8, 1.1};
vector<string> str = {"cat", "dog", "panter", "red fish", "hawk", "snake"};
// create the vector of indeces
vector<int> idx(nums.size());
std::iota(idx.begin(),idx.end(),0); // fill the vector, require #include <numeric>
// thanks to the lambda variable capture you don't need globals
auto cmp_ind = [ &nums ]
( const int &lhs, const int &rhs ) -> bool {
return nums[lhs] < nums[rhs];
};
// sort indeces
std::sort(idx.begin(), idx.end(),cmp_ind);
// create sorted arrays. It could be done in place but it's more difficult
vector<double> sorted_nums(nums.size());
vector<string> sorted_str(str.size());
for ( int i = 0; i < nums.size(); ++i ) {
sorted_nums[i] = nums[idx[i]];
sorted_str[i] = str[idx[i]];
}
std::cout << "Sort by numbers:\n";
for ( int i = 0; i < nums.size(); ++i ) {
std::cout << sorted_nums[i] << ' ' << sorted_str[i] << '\n';
}
You seem to intend to sort an array of integers (your compare function looks like that). But what you are actually handing over to qsort for sorting is a pointer to a structure that holds, among other stuff, an array.
So what you are actually trying to sort is one single struct ABCSort which is initialized and 9 other, uninitialized structures. This must fail.
Your qsort line should look like so:
qsort ((void*)&(abcsort.svsort), 10, sizeof (int), (compfn)compare);
Also, you should change the compare function so that it takes and works on two pointers to integers:
int compare (int * e1, int * e2) {
return *e1 - *e2;
}
EDIT:
After you have explained a bit better what you want, have a look at the following:
typedef int(compfn)(const void, const void*);
#define MAXCARS 5
struct car {
int sortKey;
double displacement;
char name[15]; /* Note I have decided this should be C */
};
/* This time we have an array of structs */
struct car cars [MAXCARS] = {
{ 0, 1.9, "BMW" },
{ 0, 6.3, "Audi" },
{ 0, 0.5, "Fiat" },
{ 0, 25.0, "Humvee" },
{ 0, 0.05, "Minibike" }
};
int compare(struct car*, struct car*);
void main(int argc, char *argv []) {
int i;
for (i = 0; i < MAXCARS; i++)
cars[i].sortKey = 100 - i;
qsort((void *)&cars, MAXCARS, sizeof(struct car), (compfn)compare);
}
/* Note we are comparing struct car-s in here, based on their displacement */
int compare(struct car *elem1, struct car *elem2) {
return elem1->sortKey - elem2->sortKey;
}

Storing values of individual components of arrays in functions using static

I had a quick question with regard to arrays in c++.
Let's say that for the program I wanted to store a specific value for each of the individual subscript components of the array. I wanted to create a function to do it and the problem here is I want a way of storing the individual values and remembering it. Since a local variable in a function will get its memory erased, I know we need to employ a static variable but I don't know how to do it.
Thanks
Varun G.
Let's say I have the function
int calculate(int array[], int size)
{
int i;
for(i=0; i<10; i++)
{
array[i]=0;
}
if(size >= 0 && size <=9)
{
array[size] = array[size]+1;
}
}
Here I want to basically create the array with the 10 numbers all being 0 and then if it falls in the range between 0 and 9 I want to add 1 to the specific position I want to also remember the position and the value so I can repeat it next time
For example if I enter 9 2 times I will get the array[size] to be 1 when I want it to be 2
Do you mean like this?
#include <iostream>
int f(int i) {
static const int data[8] = { 1, 1, 2, 3, 5, 8, 13, 21 };
return data[i];
}
int main() {
std::cout << f(4) << std::endl;
return 0;
}
#include <iostream>
#include <cstdlib>
#include <ctime>
void init( int a[], size_t n )
{
std::srand( ( unsigned int )std::time( 0 ) );
for ( size_t i = 0; i < n; i++ ) a[i] = std::rand() % n;
}
int main()
{
const size_t N = 10;
int a[N];
init( a, N );
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
}
Another way
#include <iostream>
#include <array>
void init( std::array<int, 10> &a )
{
a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
}
int main()
{
std::array<int, 10> a;
init( a );
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
}
If the size of the array has to be changed inside the function then it is better to use class std::vector instead of the array
I think you are looking for something along these lines:
int calculate( int size )
{
static int a[10] = { 0 };
if ( size >= 0 && size < 10 )
{
++a[size];
return a[size];
}
return -1;
}
The array will only be initialized once and will preserve its values between calls.