I have a variable k of type int to set the length of a dynamically allocated int array:
int *Numbers = new int[k];
But because of this I cannot iterate over the array, I get an error:
"no matching begin function was found required for this range-based for statement"
I also cannot get the length of the array using size();
Here's the complete code:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
for (int i : Numbers) {// (There is a error)
}
for (int i = 0; i < size(Numbers); i++) {
}
}
Prefer using a std::vector instead of a std::array. (Like #tadman mentioned.)
Here is your code using std::vector instead:
#include <iostream>
#include <vector>
int main()
{
int b, k;
std::cin >> b >> k;
std::vector<int> Numbers(b,k); // Fills the vector "Numbers" with nth number of elements with each element as a copy of val.
for (int i : Numbers)
std::cout << i << std::endl;
for (int i = 0; i < Numbers.size(); i++)
std::cout << Numbers[i] << std::endl;
return 0;
}
Say I want 10 elements with the number 5.
Output:
10
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
Also consider not using namespace std;.
The simple and recommended solution is to use std::vector, however if you really want a dynamically allocated array and to use iterator like features on it, you can use iterator_range from boost library, which allows you to create an iterator range for it thus making it usable in range based for loops and in functions like std::size.
Live demo
#include <iostream>
#include<boost/range.hpp>
int main()
{
int k = 5;
int *Numbers = new int[k]{1,4,5,7,8};
auto arr = boost::make_iterator_range(Numbers, Numbers + k);
for (int i : arr) { //range based loop
std::cout << i << " ";
}
std::cout << std::endl << "Size: " << arr.size(); //print size
//or std::size(arr);
}
Output:
1 4 5 7 8
Size: 5
Range-based for loops work with arrays, but not work with pointers. The Actual issue is that arrays is actually a pointer and not an array.try to use simple array.
Using pointers is problematic for many reasons. The simple solution to your problem is to use a vector
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
vector<int> Numbers(k);
for (int i : Numbers) {
cout << i << endl;
}
for (int i = 0; i < Numbers.size(); i++) {
cout << Numbers[i] << endl;
}
}
C array does not have default iterator and thus there is no begin() and end() functions that are used to iterate over array when you use statment like this:
for (int i : Numbers)
You can check range-for reference:
range_expression - any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.
Okay, so since the dynamic array does not have a default iterator, do not use the for-each loop, instead consider using the regular for loop.
Also, mind the the size function will not work for an array (or dynamic array) and you need to remember the size, since it's not possible to get the size from the pointer only. Hence, this code would work:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
const int SIZE = k;
for (int i = 0; i < SIZE; i++) {
cout << i << ' ';
}
}
You need to dereference *Numbers by using the * if you want to iterate over the array because *Numbers is a pointer to an integer which points to the first element of your array.For Example :
#include <iostream>
using namespace std;
int main()
{
int k = 10;
int *numbers = new int[k];
//filling the array
for(int i = 0 ; i < k ; ++i) {
*(numbers + i) = i ;
}
//output array element
for(int i = 0 ; i < k ; ++i) {
cout << numbers + i << " is the address of "<<*(numbers + i) << endl;
}
return 0;
}
The output is :
0x6f1750 is the address of 0
0x6f1754 is the address of 1
0x6f1758 is the address of 2
0x6f175c is the address of 3
0x6f1760 is the address of 4
0x6f1764 is the address of 5
0x6f1768 is the address of 6
0x6f176c is the address of 7
0x6f1770 is the address of 8
0x6f1774 is the address of 9
Unfortunatly, you can't get the size of your array with *Numbers because it's not an array but a pointer.
Related
Write a function, reverseArray, that when passed an int array of length greater than 0 will return a dynamically allocated array of the same length but with the elements in the reverse order. For example, if passed the array, {1,2,3,4,5,6,7,8,9,0} the function would return the array {0,9,8,7,6,5,4,3,2,1}.
Below is my code, but there is a bug in it.
This is my output.
1
2
3
4
5
6
4113
6
5
4
3
2
1
0x7fffe697ceb0
The 4113 and address are provided by the compiler.
#include <iostream>
using namespace std;
int * readNumbers() {
int * a = new int[6];
for (int i = 0; i < 6; i++) {
int x;
cin >> x;
a[i] = x;
}
// a++;
return a;
delete[] a;
}
int *reverseArray(int *numbers1,int length) {
for (int i = length; i >=0; i--) {
cout << numbers1[i] << endl;
}
return numbers1;
delete [] numbers1;
}
int main() {
int *arr1 = readNumbers();
cout << reverseArray(arr1,6) << endl;
return 0;
}
I think there may have been an issue with your wording. Assuming you want your function just to print the reverse of a passed array, you're off to a good start.
One issue is what was said in the comments: your for loop is indexing past your array. When you type int * a = new int[6]; you are creating a pointer 'a' which points to a location in memory. Since you chose size 6, the appropriate amount of memory is allocated. If you happen to index outside of that range, you will end up pointing to a random spot in memory, not allocated for your array. Hence why you are getting a weird number '4113'.
A fix for this could be:
int i = length changed to int i = length-1
Another issue is that your function returns an integer pointer, and you are trying to cout this pointer. As another commenter said, you have to think about what this does. If you try this code:
#include <iostream>
using namespace std;
int main() {
int arr[] = {1, 2, 3};
cout << arr << endl;
return 0;
}
your output would be something like 0xff09ba. This represents the location of the start of the array in memory. If you change arr to (arr + 1) you will get the location of the second index of the array.
So when you type cout << reverseArray(arr1,6) << endl; you are really just printing out the location of numbers1 in memory. This is why you are getting '0x7fffe697ceb0' in your output. To fix this, simply make your function
void reverseArray(int *numbers1,int length) {
for (int i = length; i >=0; i--) {
cout << numbers1[i] << endl;
}
}
and change your main to:
int main() {
int *arr1 = readNumbers();
reverseArray(arr1,6);
return 0;
}
Now, if you actually want to return this array, you would need to create a new array which holds the reverse numbers and then return that. An example of a function that does that is:
int* reverseArray(int *numbers1,int length) {
int j = 0;
int *numbers2 = new int[length];
for (int i = length-1; i >=0; i--) {
numbers2[j] = numbers1[i];
j++;
}
return numbers2;
}
There are probably better ways to do this, but this is just one solution. Regardless, you should always be careful when allocating memory yourself.
I'm learning pointers in but I'm stuck on dynamic allocation of arrays.
The code below provides a function to find the element with the lowest value.
A dynamically allocated array is passed as a parameter to it.
#include <cstdlib>
#include <iostream>
using namespace std;
int findMin(int *arr, int n);
int main()
{
int *nums = new int[5];
int nums_size = sizeof(*nums);
cout << "Enter 5 numbers to find the minor:" << endl;
for(int i = 0; i < nums_size; i++)
cin >> nums[i];
cout << "The minor number is " << findMin(*nums, nums_size);
delete [] nums;
return 0;
}
But it return this error:
error: invalid conversion from ‘int’ to ‘int*’ [-fpermissive]
How can I pass that array to the function?
Just for curiosity: why the for loop allows me to enter 4 value if my array is made up of 5 elements?
How can I pass that array to the function?
nums is already a type int*, you don't need to dereference it:
findMin(nums, nums_size);
why the for loop allows me to enter 4 value if my array is made up of 5 elements?
int nums_size = sizeof(*nums); does not do what you think it does. It's equivalent to sizeof(nums[0]), which is equivalent to sizeof(int), which happens to be equal to 4 at your machine.
There is no way to extract size of array allocated on the heap, you need to save the size on your own:
int nums_size = 5;
int* nums = new int[nums_size];
#include <cstdlib>
#include <iostream>
using namespace std;
int findMin(int *arr, int n){
int mn=INT_MAX;
for(int i=0;i<n;i++){
if(arr[i]<mn){
mn=arr[i];
}
}
return mn;
};
int main()
{
int nums_size = 5;
int *nums = new int[nums_size];
cout << "Enter 5 numbers to find the minor:" << endl;
for(int i = 0; i < nums_size; i++)
cin >> nums[i];
cout << "The minor number is " << findMin(nums, nums_size);
delete [] nums;
return 0;
}
The above code works fine. Your error was in passing the array to the function.
Also to add -
Your code made only 4 iterations coz sizeof(*nums) returned the size of base index element pointed by pointer, i.e ,sizeof(num[0]). So I made a minor change and now it works fine.
Task
You'll be given an array of N integers and you have to print the integers in the reverse order.
Constraints
1<=N<=1000
1<=A_i<=10000, where A_i is the ith integer in the array.
Input
4
1 2 3 4
Output
4 3 2 1
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N, y; //declaring N as the length of array
cin >> N; //intakes the length as an input
if (N>=1 && N<=1000){ //checks whether the length satisfies the rules
int a[N]; // makes an array containing N elements
for (int x =1; x<N; x++){ //starts transcription on the array
cin>>y; //temporarily assigns the input on a variable
if (y>=1&&y<=10000){ //checks if the input meets rules
a[x]=y; //copies the variable on the array
}
}
for (int z = N; z>1; z--){ //runs a loop to print in reverse
cout<<a[z]<<endl;
}
}
return 0;
}
Problem
Obtained output is
-1249504352
3
2
Indicating an error in transcription.
Question
Can somebody please tell me where I am making a mistake? Secondly, is it possible to directly check whether an input is meeting requirement rather than temporarily declaring a variable for it?
Here is a solution in idiomatic c++11, using std::vector, which is a dynamically resizable container useful for applications like this.
#include <vector>
#include <iostream>
#include <algorithm>
int main() {
int size;
std::cin >> size; // take in the length as an input
// check that the input satisfies the requirements,
// use the return code to indicate a problem
if (size < 1 || size > 1000) return 1;
std::vector<int> numbers; // initialise a vector to hold the 'array'
numbers.reserve(size); // reserve space for all the inputs
for (int i = 0; i < size; i++) {
int num;
std::cin >> num; // take in the next number as an input
if (num < 1 || num > 10000) return 1;
numbers.push_back(num);
}
std::reverse(numbers.begin(), numbers.end()); // reverse the vector
// print each number in the vector
for (auto &num : numbers) {
std::cout << num << "\n";
}
return 0;
}
A few things to note:
using namespace std is considered bad practice most of the time. Use (e.g.) std::cin instead for things which come from the std namespace.
numbers.reserve(size) is not necessary for correctness, but will make the program faster by reserving space in advance.
for ( auto &num : numbers ) uses a range-based for loop, available in c++11 and later versions.
You could make your for loop indices go from high to low:
for (int i = N-1; i > 0; --i)
{
std::cout << a[i] << "\n"; // Replace '\n' with space for horizontal printing.
}
std::cout << "\n";
This would apply with std::vector as well.
With std::vector, you can use a reverse iterator. There are other techniques available (as in other answers).
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++) {
// ...
}
// ...
}
Is there such a thing as a jagged array in C or C++?
When I compile this:
int jagged[][] = { {0,1}, {1,2,3} };
I get this error:
error: declaration of `jagged' as multidimensional array must have bounds for all dimensions except the first
In C I would use an array of pointers.
For instance:
int *jagged[5];
jagged[0] = malloc(sizeof(int) * 10);
jagged[1] = malloc(sizeof(int) * 3);
etc etc.
There's a bunch of ways to do it. Here's another way:
int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};
int *jagged[] = { jagged_row0, jagged_row1 };
If you just want to initialise it, you can say:
int jagged[][3] = { {0,1}, {1,2,3} };
but the array will still have the shape [2][3]. If you want a true jagged array, you will have to create it dynamically. And if you do that, and are using C++, you should use a std::vector, as friol suggests.
In C++ (not compiled, and probably there's a more compact syntax):
std::vector<std::vector<int> > myArray;
myArray.push_back(std::vector<int>());
myArray.push_back(std::vector<int>());
myArray[0].push_back(0);
myArray[0].push_back(1);
myArray[1].push_back(1);
myArray[1].push_back(2);
myArray[1].push_back(3);
So now you can access the elements with, for example, myArray[0][0], etc.
In C99 you can do the following:
int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};
int (*jagged[])[] = { &jagged_row0, &jagged_row1 }; // note the ampersand
// also since compound literals are lvalues ...
int (*jagged2[])[] = { &(int[]){0,1}, &(int[]){1,2,3} };
The only difference here (as compared to rampion's answer) is that the arrays don't decay to pointers and one has to access the individual arrays via another level of indirection - (e.g. *jagged[0] - and the size of each row has to be recorded - i.e. sizeof(*jagged[0]) will not compile) - but they're jagged-appearing to the bone ;)
The reason you got the error is that you must specify the bounds for at least the outer dimension; i.e.
int jagged[][3] = {{0,1},{1,2,3}};
You cannot have jagged[0] be a 2-element array of int and jagged[1] be a 3-element array of int; an N-element array is a different type from an M-element array (where N != M), and all elements of an array must be the same type.
What you can do is what the others have suggested above and create jagged as an array of pointers to int; that way each element can point to integer arrays of different sizes:
int row0[] = {0,1};
int row1[] = {1,2,3};
int *jagged[] = {row0, row1};
Even though row0 and row1 are different types (2-element vs. 3-element arrays of int), in the context of the initializer they are both implicitly converted to the same type (int *).
With C++11 initializer lists this can be written more compactly:
#include <vector>
#include <iostream>
int main() {
// declare and initialize array
std::vector<std::vector<int>> arr = {{1,2,3}, {4,5}};
// print content of array
for (auto row : arr) {
for (auto col : row)
std::cout << col << " ";
std::cout << "\n";
}
}
The output is:
$ g++ test.cc -std=c++11 && ./a.out
1 2 3
4 5
For reference:
http://en.cppreference.com/w/cpp/utility/initializer_list
You can also use the compound literals in c to initialize a truly jagged array which is contiguous in memory as follows:
int (*arr[]) = { (int []) {0, 1}, (int []){ 2, 3, 4}, (int []){5, 6, 7, 8} }
This will be laid out contiguously in memory.
By using dynamic allocation in cpp we can create jagged arrays.
For example:
#include<iostream>
using namespace std;
int main(){
int n;
cout<<"Enter n:";
cin>>n;
cout<<"Enter elements:";
int **p = new int *[n];
for(int i=0;i<n;i++){
p[i] = new int[i+1];
for(int j=0;j<(i+1);j++){
cin>>p[i][j];
}
}
cout<<"Jagged Array:"<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<(i+1);j++){
cout<<p[i][j]<<" ";
}
cout<<endl;
}
for(int i=0;i<n;i++){
delete []p[i];
}
delete []p;
}
For n=3, we have created a jagged array in the following look:
Enter n: 3
Enter elements:
1
1 2
1 2 3
Jagged Array:
1
1 2
1 2 3
//
//jaggedArrays.cpp
//
//program to implement jagged arrays in c++
//
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int rows, i, j;
cout << endl << "Enter no of rows : ";
cin >> rows;
int columnsSizeOfEachRow[rows];
cout << endl;
for( i = 0 ; i < rows ; i++ )
{
cout << "Enter column size for row no " << i + 1 << " : ";
cin >> columnsSizeOfEachRow[i];
}
int *jaggedArray[rows];
for (i = 0 ; i < rows ; i++)
jaggedArray[i] = new int[columnsSizeOfEachRow[i]];
cout << endl;
for(i = 0 ; i < rows ; i++)
{
for ( j = 0 ; j < columnsSizeOfEachRow[i] ;j++)
{
cout << "Array[" << i + 1 << "][" << j + 1 << "] << ";
cin >> jaggedArray[i][j];
}
cout << endl;
}
cout << endl << endl << "Jagged array is as follows : " << endl;
for( i = 0 ; i < rows ; i++)
{
for ( j = 0 ; j < columnsSizeOfEachRow[i] ;j++)
cout << setw(3) <<jaggedArray[i][j] << " ";
cout << endl;
}
return 0;
}
The jagged arrays do exist in c++/c but the syntax is quite complex and you have to handle many things.
There are two types of jagged arrays in c++.
1) STATIC JAGGED ARRAY(A 2d array in which the size will be a constant number and there will be different number of columns in each row).
2) DYNAMIC JAGGED ARRAY(A 2d array in which the size will be any number taken from user and there will be different number of columns in each row)
1)STEPS OF IMPLEMENTING STATIC JAGGED ARRAY
Using array and a pointer
1) Declare 1-D arrays with the number of rows you will need
2) The size of each array(array for the elements in the row) will be the number of columns (or elements) in the row
3) Declare a 1-D array of pointers that will hold the addresses of the arrows
4) The size of the 1-D array is the number of rows you want in the jagged array
#include<iostream>
#include<string>
using namespace std;
int main()
{
int row0[4] = { 1,2,3,4 };
int row1[2] = { 5,6 };
int* jagged[2] = { row0,row1 };
int Size[2] = { 4,2 }, k = 0;
for (int i = 0; i < 2; i++)
{
int* ptr = jagged[i];
for (int j = 0; j < Size[k]; j++)
{
cout << *ptr << "";
ptr++;
}
cout << endl;
k++;
jagged[i]++;
}
return 0;
}
The output is as follows
123456
1)STEPS OF IMPLEMENTING DYNAMIC JAGGED ARRAY
Using an array of pointer
1) Declare an array of pointers(jagged array)
2) The size of this array will be the number of rows required in the jagged array
3) For each pointer in the array allocate memory for the number of elements you want in this row.
#include<iostream>
#include<string>
using namespace std;
int main()
{
//2 rows
int* jagged[2];
//Allocate memeory for the elements in the row 0
jagged[0] = new int[1];
//Allocate memory for the elements in row 1
jagged[1] = new int[5];
//Array to hold the size of each row
int Size[2] = { 1,5 },k = 0, number = 100;
//User enters the numbers
for (int i = 0; i < 2; i++)
{
int* p = jagged[i];
for (int j = 0; j < Size[k]; j++)
{
*p = number++;
//move the pointer
p++;
}
k++;
}
k = 0;
//Display elements in Jagged array
for (int i = 0; i < 2; i++)
{
int* q = jagged[i];
for (int j = 0; j < Size[k]; j++)
{
cout << *q << "";
//move the pointer to the next element
q++;
}
cout << endl;
k++;
//move the pointer to the next row
jagged[i]++;
}
delete[] jagged[0];
delete[] jagged[1];
return 0;
}
The output is as follows
100
101102103104105
No, there are no jagged multidimensional arrays in C nor C++. You can create various constructs that perform similar function at some memory cost (like array of pointers to arrays), but not an actual C-style multidimensional array.
The reason is that C-style arrays, no matter how many dimensions, occupy contiguous memory area with no metadata. So, memory-wise, they're all single-dimensional. It's only the cleverness of pointer arithmetic (striding the pointer by the size of a row) that gives you the functionality of extra dimensions. A jagged array laid out serially has different row sizes, so it cannot be strode by a constant value, so it requires additional storage depending on data size, thus is impossible to express in C type system.
It becomes clearer when you consider to what pointer multidimensional array decay to: Array to pointer decay and passing multidimensional arrays to functions
And that's why you see the error message must have bounds for all dimensions except the first, because all dimensions except the first are necessary to stride the array.