I have got a small problem with 1D array in c++. I have got a function line this:
void func(int (&array)[???])
{
// some math here;
"for" loop {
array[i] = something;
}
}
I call the functions somewhere in the code, and before I made math I'm not able to know dimension of the array. The array goes to the function as a reference!, because I need it in the main() function. How I can allocate array like this?, so array with ?? dimension goes to the function as reference then I have to put the dimension and write to it some values.
Since you're using C++, why not use a std::vector<> instead?
Other have mentioned that you should use std::vector in C++ and they are right.
But you can make your code work by making func a function template.
template <typename T, size_t N>
void func(T (&array)[N])
{
// some math here;
"for" loop {
array[i] = something;
}
}
Use a pointer, not a reference:
void func(int *a, int N);
Or, easier, use a vector:
void func(std::vector<int> &a);
Vectors can be allocated by simply saying
std::vector<int> a(10);
The number of elements can be retrieved using a.size().
If the array you pass to func is a stack array, and not a pointer, you can retain its size by using a function template:
template <class T, size_t N>
void func(T(&array)[N])
{
size_t array_length = N; // or just use N directly
}
int main()
{
int array[4];
func(array);
}
That said, as others have already pointed out, std::vector is probably the best solution here.
As well as vector which has been suggested you could possibly use valarray which is also part of STL and is intended specificially to handle mathematical collections.
What you have to realize, is that arrays are pointers. A definition like int array[5] will allocate space for 5 integers on the stack and array will be the address of the first value. Thus, to access the first value in the array, you can write
array[0] or *array (which is the same as *(array + 0))
In the same way to retrieve the address of the third element, you can write
&array[2] or array + 2
Since arrays are pointers, you don't have to worry about the runtime size of your array if you would like to pass it to a function, simply pass it as a pointer:
void func(int *array)
{
int size;
//compute size of the array
for (int i = 0; i < size; ++i)
{
//do whatever you want with array[i]
}
}
Related
#include <iostream>
using namespace std;
int* reverse(int arr[],int n){
int rev[100];
int j =0;
for(int i=n-1;i>=0;i--){
rev[j]=arr[i];
j++;
}
return rev;
}
int main() {
int n;
cin>>n;
int arr[100];
for(int i=0;i<n;i++){
cin>>arr[i];
}
cout<<reverse(arr,n);
}
I am trying reverse an array using loops but don't know what the error was it was returning some bin value.
Your rev temporary resides in automatic storage. It means that the object will be gone after the function returns. While C++ allows you to decay rev to an int* and then return said pointer, it does not mean that this returns the object itself. You merely get a pointer to an already destroyed object. Not very useful. In fact, doing anything with this pointer will cause undefined behaviour.
Usually what you want to do is reverse things in-place. That's also how std::reverse works.
So, there are two options. If you have a completely filled c-style array, you could write a reverse function like this:
template <std::size_t N>
void reverse(int (&a)[N]) {
// reverse a from 0 to N-1
}
reverse(a);
Or, if you have an only partially filled array, take a page out of the standard library and reverse a range, denoted by two iterators.
void reverse(int* begin, int* end) {
/* begin points to the first entry, end points one past the last */
}
reverse(a, a+n);
Of course, instead of using c-style arrays, you could use a dynamically growing array such as std::vector, which carries the actual size of the array around for you.
I am trying to write a function that prints out the elements in an array. However when I work with the arrays that are passed, I don't know how to iterate over the array.
void
print_array(int* b)
{
int sizeof_b = sizeof(b) / sizeof(b[0]);
int i;
for (i = 0; i < sizeof_b; i++)
{
printf("%d", b[i]);
}
}
What is the best way to do iterate over the passed array?
You need to also pass the size of the array to the function.
When you pass in the array to your function, you are really passing in the address of the first element in that array. So the pointer is only pointing to the first element once inside your function.
Since memory in the array is continuous though, you can still use pointer arithmetic such as (b+1) to point to the second element or equivalently b[1]
void print_array(int* b, int num_elements)
{
for (int i = 0; i < num_elements; i++)
{
printf("%d", b[i]);
}
}
This trick only works with arrays not pointers:
sizeof(b) / sizeof(b[0])
... and arrays are not the same as pointers.
Why don't you use function templates for this (C++)?
template<class T, int N> void f(T (&r)[N]){
}
int main(){
int buf[10];
f(buf);
}
EDIT 2:
The qn now appears to have C tag and the C++ tag is removed.
For C, you have to pass the length (number of elements)of the array.
For C++, you can pass the length, BUT, if you have access to C++0x, BETTER is to use std::array. See here and here. It carries the length, and provides check for out-of-bound if you access elements using the at() member function.
In C99, you can require that an array an array has at least n elements thusly:
void print_array(int b[static n]);
6.7.5.3.7: A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. If the keyword static also appears within the [ and ] of the
array type derivation, then for each call to the function, the value of the corresponding
actual argument shall provide access to the first element of an array with at least as many
elements as specified by the size expression.
In GCC you can pass the size of an array implicitly like this:
void print_array(int n, int b[n]);
You could try this...
#include <cstdio>
void
print_array(int b[], size_t N)
{
for (int i = 0; i < N; ++i)
printf("%d ", b[i]);
printf("\n");
}
template <size_t N>
inline void
print_array(int (&b)[N])
{
// could have loop here, but inline forwarding to
// single function eliminates code bloat...
print_array(b, N);
}
int main()
{
int a[] = { 1, 2 };
int b[] = { };
int c[] = { 1, 2, 3, 4, 5 };
print_array(a);
// print_array(b);
print_array(c);
}
...interestingly b doesn't work...
array_size.cc: In function `int main()':
array_size.cc:19: error: no matching function for call to `print_array(int[0u])'
JoshD points out in comments below the issue re 0 sized arrays (a GCC extension), and the size inference above.
In c++ you can also use a some type of list class implemented as an array with a size method or as a struct with a size member(in c or c++).
Use variable to pass the size of array.
int sizeof_b = sizeof(b) / sizeof(b[0]); does nothing but getting the pre-declared array size, which is known, and you could have passed it as an argument; for instance, void print_array(int*b, int size). size could be the user-defined size too.
int sizeof_b = sizeof(b) / sizeof(b[0]); will cause redundant iteration when the number of elements is less than the pre-declared array-size.
The question has already some good answers, for example the second one. However there is a lack of explanation so I would like to extend the sample and explain it:
Using template and template parameters and in this case None-Type Template parameters makes it possible to get the size of a fixed array with any type.
Assume you have such a function template:
template<typename T, int S>
int getSizeOfArray(T (&arr)[S]) {
return S;
}
The template is clearly for any type(here T) and a fixed integer(S).
The function as you see takes a reference to an array of S objects of type T, as you know in C++ you cannot pass arrays to functions by value but by reference so the function has to take a reference.
Now if u use it like this:
int i_arr[] = { 3, 8, 90, -1 };
std::cout << "number f elements in Array: " << getSizeOfArray(i_arr) << std::endl;
The compiler will implicitly instantiate the template function and detect the arguments, so the S here is 4 which is returned and printed to output.
How am I supposed to pass static 2d array to function in cpp as an argument? I tried something like that:
void foo(int (&tab)[N][N]) {
// function body
}
int main() {
int n;
cin >> n;
int tab[n][n];
foo(tab); // doesn't work
return 0;
}
I get "no matching function error" when I try to call foo.
I need static arrays, because vectors are too slow for my needs. I would like to avoid declaring array with 10000 rows and columns, too. Moreover, I would want to use functions, because it will make my code readable. Is there any solution for this problem which will meet my expectations?
With cin >> n;int tab[n][n];, you declare a variable length array (i.e. an array which's dimensions are not compile-time-constants).
You have two problems here: First, they are not supported by standard C++, and second they are not compatible with fixed size array parameters you introduced.
If you declare your array with compile time known size, however, it will work:
#define N 10
void foo(int (&tab)[N][N]) {
cout << tab[1][1] << endl;
}
int main() {
int tab[N][N] = {};
tab[1][1]=15;
foo(tab);
return 0;
}
The classical C++ solution would involve using vectors of vectors. If it's not suitable (because you want more speed or more control over memory), you can define your own class for a square 2-D array.
One idea I used in my code is, implement it using an underlying 1-D vector, with accessor method returning a pointer.
struct My_2D_Array
{
explicit My_2D_Array(size_t n):
m_size(n),
m_data(n * n)
{
}
int* operator[](size_t i)
{
return m_data.data() + i * m_size;
}
size_t m_size;
std::vector<int> m_data;
};
This not only lacks all sanity checks, and also makes bound-checked access impossible (because the accessor returns a bare pointer), but will work as a quick-and-dirty solution.
Usage in your code:
int foo(My_2D_Array& matrix)
{
// example
return matrix[2][3] + matrix[3][2];
}
int main()
{
int n;
cin >> n;
My_2D_Array tab(n);
foo(tab);
return 0;
}
This idea is highly customizable - you can make the code for My_2D_Array as simple or as clever as you want. For example, if you still don't like usage of vector, even though it's 1-D, you can manage (allocate/deallocate) your memory separately, and store int*, instead of vector<int>, in My_2D_Array.
Just use a vector<> of vector<int>. No need for mucking around with non-standard arrays.
I was wondering.. Whenever I deal with arrays, when I have to cut it, or sort it, or anything, and then return it, I pass it to the void function like f(array, length, newarray) and in the function declaration I have void f(T *array, int length, T *&new array).
Is there a better way to do this?
Here's some code, I want to remove repeats from an array:
template<class T>
void eliminate(T *niz, int duzina, T *&podniz)
{
int ind;
podniz = new T[duzina];
for (int i = 0; i<duzina; i++)
{
ind = 0;
for (int j = i; j<duzina; j++)
{
if (niz[i] == niz[j])ind++;
}
if (ind == 1)podniz[nova++] = niz[i];
}
}
As already noted in the comments, you really want std::vector.
The main problem with your code is that there is no way to tell how many of the output elements are actually initialized. And accessing uninitialized elements is Undefined Behavior, so you are returning a time bomb to the caller.
With std::vector<T> eliminate(std::vector const&), there's no such doubt. The returned vector has exactly .size() elements.
Vector is also exception-safe. Your code will leak memory if the copy constructor of T throws, e.g. on a std::bad_alloc.
Sure. You can use pointers and pass the array by reference to the function.
Then manipulate the array and return from the function with void type i.e no need of returning the array as it is passed by reference.
Is there an effective or analogous way to perform this task in C++?
void function(int n) {
int array[n] = {};
}
I'm trying to implement the merge sort algorithm in C++ and it's a little trickier than its implementation in Java. It essentially relies on the ability to declare an array in this manner.
The syntax
int array[n] = {};
isn't supported as part of standard c++. There are compiler extensions though supporting array allocation on the stack.
The correct way doing this in c++ is
void function(int n) {
std::vector<int> array(n);
}
See std::vector<> reference documentation for more info.
In C++, std::vector is used for cases like this:
#include <vector>
// ...
void function(int n) {
std::vector<int> array(n);
}
It allocates an array of size n for you, and automatically manages its memory.
Simple allocation is OK if you don't need the vector:
void function(int n) {
std::unique_ptr<int[]> array (new int[n]);
// for (int i=0; i<n; ++i) array[i] = i;
}
std::unique_ptr will delete the array in the destructor (of course).