Pointing to an element of an array - c++

Below is the cluttered version of my code that shows only the basic structure.
I'm just trying to use a pointer to an element of an array in a function but
I constantly get
C:\Users\whale\Desktop\20_Pay2.cpp:4:45: error: expected ',' or '...' before 'money'
but I still have no clue what I'm missing. Any help is appreciated!
#include<stdio.h>
#include<stdlib.h>
void pay_amount (int *dollars, int k, int *money[k]);
int main(void)
{
int dollars=180, i=1, a[4]={20,10,5,1};
pay_amount (&dollars, i, &a[i] );
return 0;
}
void pay_amount (int *dollars, int k, int *money[k])
{
printf("functions");
}

The problem is that the parameter list you're using (int k, int *money[k]) is not valid C++ syntax. Unfortunately g++ produces a less than helpful message for this.
The good news is that you don't want this anyway: It would declare money to be an array of k pointers to int. What you actually want is just a pointer to int:
void pay_amount(int *dollars, int k, int *money);
a is an array of int, a[i] is a single int, so &a[i] is a pointer to an int, int *.

Here :
pay_amount (&dollars, i, &a[i] );
The third parameter you pass is a pointer to a integer.
But in your function declaration, you have that :
void pay_amount (int *dollars, int k, int *money[k]);
int *money[k] as a function parameter does not seems correct.
You may want to do that :
void pay_amount (int *dollars, int k, int *money);
Here, money is a pointer to an integer

Related

how to convert 'std::vector<double>' to 'double' in initialization

I'm trying to make quicksort program. I just couldn't understand why and how this error is coming. I've tried every method online but I'm unable to catch the issue. If I'm doing this with array in place of vector, I'm getting correct output but with vector error is coming.
My errors are:
.\quicksort.cpp:7:28: error: cannot convert 'std::vector<double>' to 'double' in initialization
double pivot = values[end];
.\quicksort.cpp:10:19: error: no match for 'operator<=' (operand types are 'std::vector<double>' and 'double')
if (values[i] <= pivot) {
How to convert the vector<double> to double then?
Here's my code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int partition(vector<double> *values, int start, int end) {
double pivot = values[end];
int pIndex = start;
for (int i=start; i<end; i++) {
if (values[i] <= pivot) {
swap(values[i], values[pIndex]);
pIndex++;
}
}
swap(values[pIndex], values[end]);
return pIndex;
}
void quicksort(vector<double> *values, int start, int end) {
if (start<end) {
int pIndex;
pIndex = partition(values, start, end);
quicksort(values, start, pIndex-1);
quicksort(values, pIndex+1, end);
}
}
int main() {
int n;
cin >> n;
vector<double> values(n);
for (int i = 0; i < n; i++) {
cin >> values[i];
}
quicksort(values, 0, n-1);
for (int j=0; j<n; j++) {
cout<<values[j]<<" ";
}
return 0;
}
How to rectify these errors?
References not pointers
int partition(vector<double>& values, int start, int end) {
void quicksort(vector<double>& values, int start, int end) {
If you used a pointer (but you shouldn't) the correct code would be
double pivot = (*values)[end];
Pointers are not the same as the things they are pointing to, you have to use * or -> to get at the object that a pointer points to. You don't have to do this with references.
You have a C++ compiler so use it, send Reference to your object instead of pointer:
void quicksort(vector<double> &values, const int start, const int end);
int partition(vector<double> &values, const int start, const int end)
And your compile time error gone, with pointer to the object you need to call your function like this:
quicksort(&values, 0, n - 1);
Because you need it's address (actually your pointer need it).
And you need to use operator[] of std::vector which is first need to get std::vector object from pointer to it:
double pivot = (*values)[end];
As you see it's ugly and could be complex, So it's better to use References instead of pointer in those situations.
Your partition and quicksort functions take pointers as parameters not reference values.
Your functions should be declared as such:
int partition(vector<double> &values, int start, int end)
void quicksort(vector<double> &values, int start, int end)
The reason you are getting the error is that since the values parameter is a pointer when you use the array accessor ([i]) it assumes that values is an array of vectors and returns a vector not a double.
you should pass vector<double>& to your function instead of vector<double>*, i.e. pass by reference instead of pass by pointer. If passing by pointer, then you need to access the elements of the vector with ->[index].

what's the meaning of the function parameter declaration?

I have see this in the http://en.cppreference.com/w/cpp/language/function
int f(int a, int *p, int (*(*x)(double))[3]);
what's the meaning of int (*(*x)(double))[3]?
(*x) ensure x is a pointer then (*x)(double) will give us a function pointer whose parameter is a double and the next is (*(*x)(double)) which means the function will return a pointer p and p is depicted by int int (*p)[3] which in the end gives us a pointer pointing to an array of int[3]
So all in all, what we have here is a pointer pointing to a function whose single parameter is a double and the function returns a pointer pointing to an array of int[3].
Here is a simple example to demonstrate it, hope it can be helpful.
#include <iostream>
using namespace std;
typedef int int3[3];
int arr3[3]{1, 2, 3};
int3 * get3Int(double x){
int (*arr)[3] = &arr3;
return arr;
}
int testFunctionPointer(int (*(*x)(double))[3]){
int (*arr)[3] = x(1.0);
for(auto n: *arr)
cout<<n<<endl;
return 0;
}
int main(){
testFunctionPointer(get3Int);
return 0;
}

template function to find subarray in C++

#include <iostream>
#include <string>
using namespace std;
template <class T> int IsSubArr(T& a, int a_len, T& b, int b_len)
{
int i,j;
bool found;
int k;
T& s=a,l=b;
int s_len = (a_len < b_len) ? a_len : b_len; // find the small array length
if (s_len == a_len) // check to set pointers to small and long array
{
s = a;
l = b;
}
else
{
s = b;
l = a;
}
for (i = 0; i <= a_len-s_len; i++) //loop on long array
{
found = true;
k=i;
for (j=0; j<s_len; j++) // loop on sub array
{
if (s[j] != l[i])
{
found = false;
break;
}
k++;
}
}
if (found)
return i;
else
return -1;
}
/******* main program to test templates ****/
int main()
{
int array[5] = {9,4,6,2,1};
int alen = 5;
int sub_arr[3] = {6,2,1};
int slen = 3;
int index= 0;
index = IsSubArr(array,alen,sub_arr,slen);
cout << "\n\n Place of sub array in long array: " << index;
cout << endl;
return 0;
}
for this line of code:
index = IsSubArr(array,alen,sub_arr,slen);
i get error:
Error 1 error C2782: 'int IsSubArr(T &,int,T &,int)' : template parameter 'T' is ambiguous
please help to resolve this issue ?
Since array[a] and array[b] where a != b are 2 different types, you'll need 2 type templates args.
A work around would be to use pointers.
+ template <class T> int IsSubArr(T* a, int a_len, T* b, int b_len)
+ T* s = a; T*l = b;
You defined the first and the third parameters as references
template <class T> int IsSubArr(T& a, int a_len, T& b, int b_len)
^^^^ ^^^^
and pass as arguments for these parameters two arrays with different types
int array[5] = {9,4,6,2,1};
int sub_arr[3] = {6,2,1};
//...
index = IsSubArr(array,alen,sub_arr,slen);
^^^^^ ^^^^^^^
The first argument has type int[5] and the third argument has type int[3]
So the compiler is unable to deduce the referenced type T.
If you are going to use arrays with the function then you could declare it like
template <class T, size_t N1, size_t N2>
int IsSubArr( T ( &a )[N1], T ( &b )[N2] );
Or you could use pointers instead of the references to arrays
template <class T> int IsSubArr( T *a, size_t a_len, T *b, size_t b_len );
Take into account that this declaration within the function
T& s=a,l=b;
is also wrong. It is equivalent to the following declarations
T& s=a;
T l=b;
That is the first declaration declares a reference to an array while the second declaration declares an array and tries to initialize it with another array. However arrays do not have a copy constructor and the compiler will issue one more error. And you may not reassign a reference.
You should know that there is standard algorithm std::search declared in header <algorithm> that can do the job you want to do with your function.
It's because array and sub_arr are two different types. array is of type int[5] while sub_arr is of type int[3]. The array dimensions are part of the type.
Either change the function to use two different templates arguments, one for each array, or use pointer (e.g. T*)
There's also another error, that you will continue to have if you keep using arrays and two different template arguments, and that is that you can't change references. Once you have assigned to the variable s and l in the function, those can't be made to reference anything else. The latter assignments of the s and l variables will fail because there you try to assign the arrays to each other, which you can not do, you can only copy arrays.
If you use pointers instead, then this won't be a problem.

what is wrong with the function parameter?

#include <iostream>
using namespace std;
template<class Type>
void Knapsack(Type *v,int *w,int c,int n,Type **m)
{
int i,j;
int jMax=max(w[n]-1,c);
for(j=0;j<=jMax;j++)
m[n][j]=0;
for(j=w[n];j<=c;j++)
m[n][j]=v[n];
for(i=n-1;i>1;i--)
{
for(j=0;j<=w[i]-1;j++)
m[i][j]=m[i+1][j];
for(j=w[i];j<=c;j++)
{
m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
}
}
m[1][c]=m[2][c];
if(c>=w[1])
m[1][c]=max(m[2][c],m[1][c-w[1]]+v[1]);
}
template <class Type>
void TrackBack(Type **m,int *w,int c,int n,int *x){
for(int i=1;i<=n;i++)
{
if(m[i][c]==m[i+1][c])
x[i]=0;
else
x[i]=1;
}
}
int main()
{
int m[101][101]={0};
int x[101];
int n=5;
int c=10;
int w[5]={2,2,6,5,4};
int v[5]={6,3,5,4,6};
Knapsack(v,w,c,n,m);
return 0;
}
I an writing the algorithm of 01 Knapsack problem.
my Xcode says "No matching function for call to 'Knapsack' "
I am stumbled by the red alarm.
I'm confused for passing arguments.
Is there anyone can help me? Thanks a lot:)
This is not a valid conversion:
int m[101][101]
...
Knapsack(v,w,c,n,m);
// ^-- expects a Type **m
m can decay to type "pointer to array of 101 ints", but no further.
At least type of argument
int m[101][101]={0};
is not equivalent to T ** where T is int.
When this array is passed by value as an argument it is implicitly converted to pointer to its first element and has type int ( * )[101]
Take into account that in any case this function is invalid. For example argument for second parameter w has 5 elements.
int w[5]={2,2,6,5,4};
The valid range of indices for it is [0,4]. n in the function call is equal to 5.
So this statement
int jMax=max(w[n]-1,c);
has undefined behaviour because you are using inadmissible index equal to 5.
template<class Type>
void Knapsack(Type *v,int *w,int c,int n,Type **m)
{
int i,j;
int jMax=max(w[n]-1,c);
//...
You a little bit wrong with definition of functions
template < class Type>
void Knapsack(Type *v,int *w,int c,int n,Type m[][101])
template < class Type>
void TrackBack(Type m[][101],int *w,int c,int n,int *x)

C++ passing an array pointer as a function argument

I'm trying to use pointers of arrays to use as arguments for a function which generates an array.
void generateArray(int *a[], int *si){
srand(time(0));
for (int j=0;j<*si;j++)
*a[j]=(0+rand()%9);
} //end generateArray;
int main() {
const int size=5;
int a[size];
generateArray(&a, &size);
return 0;
} //end main
But when I compile this this message appears:
cannot convert `int (*)[5]' to `int**' for argument `1' to `void generateArray(int**, int*)'
You're over-complicating it - it just needs to be:
void generateArray(int *a, int si)
{
for (int j = 0; j < si; j++)
a[j] = rand() % 9;
}
int main()
{
const int size=5;
int a[size];
generateArray(a, size);
return 0;
}
When you pass an array as a parameter to a function it decays to a pointer to the first element of the array. So there is normally never a need to pass a pointer to an array.
int *a[], when used as a function parameter (but not in normal declarations), is a pointer to a pointer, not a pointer to an array (in normal declarations, it is an array of pointers). A pointer to an array looks like this:
int (*aptr)[N]
Where N is a particular positive integer (not a variable).
If you make your function a template, you can do it and you don't even need to pass the size of the array (because it is automatically deduced):
template<size_t SZ>
void generateArray(int (*aptr)[SZ])
{
for (size_t i=0; i<SZ; ++i)
(*aptr)[i] = rand() % 9;
}
int main()
{
int a[5];
generateArray(&a);
}
You could also take a reference:
template<size_t SZ>
void generateArray(int (&arr)[SZ])
{
for (size_t i=0; i<SZ; ++i)
arr[i] = rand() % 9;
}
int main()
{
int a[5];
generateArray(a);
}
You do not need to take a pointer to the array in order to pass it to an array-generating function, because arrays already decay to pointers when you pass them to functions. Simply make the parameter int a[], and use it as a regular array inside the function, the changes will be made to the array that you have passed in.
void generateArray(int a[], int si) {
srand(time(0));
for (int j=0;j<*si;j++)
a[j]=(0+rand()%9);
}
int main(){
const int size=5;
int a[size];
generateArray(a, size);
return 0;
}
As a side note, you do not need to pass the size by pointer, because you are not changing it inside the function. Moreover, it is not a good idea to pass a pointer to constant to a parameter that expects a pointer to non-constant.
I'm guessing this will help.
When passed as functions arguments, arrays act the same way as pointers. So you don't need to reference them. Simply type:
int x[]
or
int x[a]
. Both ways will work. I guess its the same thing Konrad Rudolf was saying, figured as much.
This is another method . Passing array as a pointer to the function
void generateArray(int *array, int size) {
srand(time(0));
for (int j=0;j<size;j++)
array[j]=(0+rand()%9);
}
int main(){
const int size=5;
int a[size];
generateArray(a, size);
return 0;
}