Passing array as parameter in C++ ERROR - c++

I tried to "select sort" an array. But instead of displaying the original array with just a "for loop", to go beyond the normal way and implement the stuffs I learned I decided to pass the original array to a function called "org_array" and tried to invoke it in the "void main()". But got couple of errors. I can't figure out what's the error I made in passing the parameters. Help please?
Code:
#include<iostream>
#include<conio.h>
using namespace std;
extern int s;
void org_array(int arr[30],int y);
void main()
{
int i,n,j,pos,a[30];
cout<<"Enter n: "<<endl;
cin>>n;
cout<<"\nEnter array: "<<endl;
for(i=0;i<n;i++){
cin>>a[i];
}
cout<<"Orginal Array: ";
org_array(a[30],n);
/*for(i=0;i<n;i++){
cout<<a[i]<<" | ";
}*/
for(i=0;i<n-1;i++)
{
int small=a[i];
pos=i;
for(j=i+1;j<n;j++)
{
if(a[j]<small)
{
small=a[j];
pos=j;
}
}
int temp=a[i];
a[i]=a[pos];
a[pos]=temp;
}
cout<<"\tSorted Array: ";
for(i=0;i<n;i++){
cout<<a[i]<<" | ";
}
getch();
}
void org_array(int arr[30],int y){
for(s=0;s<y;s++)
{
cout<<" "<<arr[s];
}
}

org_array(a[30],n);
is incorrect. It should be:
org_array(a,n);
And main should return int as per ISO. Further your declarations and definitions respectively should be this way:
void org_array(int [],int); // declaration - removed 30 since we might want to pass an array of larger size
void org_array(int arr[],int y) //definition
{
for(int s=0;s<y;s++) // You did not declare s as int
{
cout<<" "<<arr[s];
}
}
Just a side note:
An lvalue [see question 2.5] of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T because an array is not a "modifiable lvalue,"
(The exceptions are when the array is the operand of a sizeof or & operator, or is a literal string initializer for a character array.)

In your code:
cout<<"Orginal Array: ";
org_array(a[30],n);
Should pass just the name of array as argument. Arrays are passed as reference to address of block of memory. You are referring to a specific index in array in your call. http://www.cplusplus.com/doc/tutorial/arrays/
org_array(a,n);
In your code:
void org_array(int arr[30],int y){
for(s=0;s<y;s++)
{
cout<<" "<<arr[s];
}
}
for loop requires a type for variable s. I assume you want an integer.
for(int s=0; s<y; s++)
Your main function should also be of type int and return int value.

Related

c++ question:After assigning value to a variable,the other variable changed

Following codes are my own API for index prior queue.When I test insert function,I get wrong answer.Then I debug codes,I found that the value of array qp changed after executing sentence----item[k]=vwhich is in insert function.Why the value of array qp changed after assigning value to array item?
template <class T>
class IndexPriorQueue{
private:
int index;//the num of items
int size;//capacity
int* pq;//index binaryheap
int* qp;//qp[pq[i]]=pq[qp[i]]=i
T* item;//item array;
public:
IndexPriorQueue(int qsize){//constructor function
size=qsize;
index=0;
pq=new int(size+1);
qp=new int(size+1);
item=new T(size+1);
for(int i=0;i<size+1;i++)
qp[i]=-1;
}
void insert(int k,T v){
if(contain(k)){
cout<<"index is already in queue"<<endl;
return;
}
//cout<<"insert"<<endl;
item[k]=v;//debug,after excuting this sentence,the value of qp exchanged??
pq[++index]=k;
qp[k]=index;
swim(index);
}
bool contain(int k){
return qp[k]!=-1?1:0;
}
void swim(int j){
while(j>1){
if(item[pq[j/2]]<item[pq[j]]){
exch(j/2,j);
j=j/2;
}else{
break;
}
}
}
void exch(int m,int n){
int temp=pq[m];
pq[m]=pq[n];
pq[n]=temp;
qp[pq[m]]=m;
qp[pq[n]]=n;
}
void display(){
cout<<"item:";
for(int i=1;i<size+1;i++){
cout<<item[i]<<" ";
}
cout<<endl;
cout<<"pq:";
for(int i=1;i<size+1;i++){
cout<<pq[i]<<" ";
}
cout<<endl;
cout<<"qp:";
for(int i=1;i<size+1;i++){
cout<<qp[i]<<" ";
}
cout<<endl;
}
};
Following codes are main function
int main(){
cout<<"before insert:"<<endl;
IndexPriorQueue<char> ipq(10);
ipq.display();
ipq.insert(1,'a');
cout<<"after insert:"<<endl;
ipq.display();
return 0;
}
The problems is your allocations. Take for example
new T(size+1)
That allocates one object of type T and initializes it to the value size + 1 (i.e. it calls the T constructor with size + 1).
If you need to allocate an "array" you should use square brackets [] as in
new T[size+1]
That will allocate an array of size + 1 number of T objects.
A much better solution though, is to use std::vector instead of doing it all manually yourself.

Array Initialization problems: Unexpected behavior

The following program builds perfectly. However, during execution, no matter what value of degree I provide, the program takes only 2 array elements as input. I suppose there might be a problem with the redeclaration of the arrays f[] and fDash[]. In JAVA, arrays can be easily redeclared using the new keyword. Is that possible in c++ too? If not, what is the alternative?
P.S. I am using CodeBlocks 13.12 and compiler settings are standard.
#include <iostream>
#include <cmath>
using namespace std;
class Polynomial
{
public:
void input(void);
void expression(void);
void derivative(void);
double value(double var);
double der(double var);
private:
int f[];
int fDash[];
int degree;
};
void Polynomial::input()
{
cout<<"Enter degree of polynomial:\t";
cin>>degree;
f[degree+1];
fDash[degree];
for(int i=0;i<=degree;i++)
{
cout<<"Enter coefficient of x^"<<i<<":\t";
cin>>f[i];
}
for(int i=0;i<degree;i++)
{
fDash[i]=f[i+1]*(i+1);
}
}
void Polynomial::expression()
{
cout<<f[0];
for(int i=1;i<=degree;i++)
{
cout<<" + "<<f[i]<<"*x^"<<i;
}
}
void Polynomial::derivative()
{
cout<<fDash[0];
for(int i=1;i<degree;i++)
{
cout<<" + "<<fDash[i]<<"*x^"<<i;
}
}
double Polynomial::value(double var)
{
double val=0.0;
for(int i=0;i<=degree;i++)
{
val+=f[i]*pow(var,i);
}
return val;
}
double Polynomial::der(double var)
{
double val=0.0;
for(int i=0;i<degree;i++)
{
val+=fDash[i]*pow(var,i);
}
return val;
}
int main()
{
double lb,ub,step,var,accum=0.0,rms;
int counter=0;
Polynomial p;
p.input();
cout<<"\n\n\nPolynomial is:\nf(x) = ";
p.expression();
cout<<"\n\n\nDerivative is:\nf'(x) = ";
p.derivative();
cout<<"\n\n\nEnter x0,x1,Step:\t";
cin>>lb;
cin>>ub;
cin>>step;
cout<<"\n\n\n====================================";
cout<<"\n\nx\t|\tf\t|\tf'\n\n\n";
var=lb;
while(var<=ub)
{
cout<<var<<"\t|\t"<<p.value(var)<<"\t|\t"<<p.der(var)<<"\n";
accum+=pow(p.value(var),2.0);
var+=step;
counter++;
}
cout<<"\n====================================";
accum/=counter;
rms=sqrt(accum);
cout<<"\nRMS energy of f(x) = "<<rms;
return 0;
}
This does not compile on clang, it fails with "error: field has incomplete type 'int []' int f[];" and likewise for fDash.
Let's see how you declared these fields:
int f[];
int fDash[];
In C++, you can declare arrays with statically defined sizes like so:
int f[5];
int fDash[6];
If you want dynamic arrays, which you need in this case, you'd have to declare
int* f;
int* fDash;
and allocate memory for them with
f = new int[5];
You also must release that memory somewhere like so
delete [] f;
But beware - managing your own memory like this is error prone and should be avoided. You should just use std::vector instead, which is the equivalent of java.util.ArrayList:
std::vector<int> f;
std::vector<int> fDash;
And modify your input function like so:
void Polynomial::input()
{
cout<<"Enter degree of polynomial:\t";
cin>>degree;
int input;
for(int i=0;i<=degree;i++)
{
cout<<"Enter coefficient of x^"<<i<<":\t";
cin>>input;
f.push_back(input);
}
for(int i=0;i<degree;i++)
{
fDash.push_back(f[i+1]*(i+1));
}
}
You don't use arrays correctly. You need to allocate memory if you want to use array of variable length. How use arrays in c++ see this and this, or use std::vector

Heapsort using Priority queue C++

My code works for putting data into the array but when I print it out, it always crashes after first number. There must be something wrong with my bubbledown function, could you point out what is wrong with it? Thank you in advance.
#include<iostream>
#include <string>
#include<fstream>
using namespace std;
void bubbleup(int pq[], int back);
void bubbledown(int pq[], int front, int back);
void swap(int &a, int &b);
int main(){
ifstream infile;
ofstream outfile;
string input, output;
int size,number;
int front=1, back=0;
int *pq=new int[size]; // dynamically allocate array
cout<<"What's the input file name?"<<endl;
getline(cin, input); // get the input name
infile.open(input.c_str());// open the input file
while(!(infile.eof())){
infile>>number; // infile to an integer type variable first instead of an array. this is why your program doesn't work!!!!!
back++;
pq[back]=number;
bubbleup(pq,back);
for(int i=1;i<=back;i++)
cout<<pq[i]<<" ";
cout<<endl;
}
cout<<"what's the output file name?"<<endl;
getline(cin, output);
outfile.open(output.c_str());
while(back!=0){
cout<< pq[front]<<endl;
outfile<< pq[front]<<endl;
pq[front]=pq[back];
back--;
bubbledown(pq,front,back);
}
}
//bubbleup function
void bubbleup(int pq[], int back)
{
int fatherindex=back/2;
while(!(pq[back]>=pq[fatherindex])||!(back==1)){
if(pq[back]<pq[fatherindex])
swap(pq[back],pq[fatherindex]);
back=fatherindex;
fatherindex=back/2;
}
}
//bubbledown function
void bubbledown(int pq[], int front, int back){
int fatherindex=front,kidindex;
while(2*fatherindex+1 <= back){
kidindex=2*fatherindex+1;
if((kidindex+1<back) && (pq[kidindex]<pq[kidindex+1])){
kidindex++;
}
if(pq[fatherindex] > pq[kidindex]){
swap(pq[fatherindex],pq[kidindex]);
fatherindex=kidindex;
}
else
return;
}
}
//swap function
void swap(int &a, int &b){
int t=a;
a=b;
b=t;
}
A few problems to look at
You don't initialize size before using it, so your pq memory could be any size at all.
You are using 1-based access to your arrays, so make sure you allocate one more than you need.
while(!back==0) will work, but it is doing boolean logic on an int, then comparing the result with an int. while(back!=0) is a lot easier to read and will produce fewer compiler warnings.
Edit: also your bubbleDown function has an infinite loop when neither if test is triggered.

Sending an array between two functions C++

I am trying to send a array of 15 integers between two functions in C++. The first enables the user to enter taxi IDs and the second functions allows the user to delete taxi IDs from the array. However I am having an issue sending the array between the functions.
void startShift ()
{
int array [15]; //array of 15 declared
for (int i = 0; i < 15; i++)
{
cout << "Please enter the taxis ID: ";
cin >> array[i]; //user enters taxi IDs
if (array[i] == 0)
break;
}
cout << "Enter 0 to return to main menu: ";
cin >> goBack;
cout << "\n";
if (goBack == 0)
update();
}
void endShift ()
{
//need the array to be sent to here
cout << "Enter 0 to return to main menu: ";
cin >> goBack;
cout << "\n";
if (goBack == 0)
update();
}
Any help is great valued. Many thanks.
Since the array has been created on the stack, you would just need to pass the pointer to the first element, as an int*
void endshift(int* arr)
{
int val = arr[1];
printf("val is %d", val);
}
int main(void)
{
int array[15];
array[1] = 5;
endshift(array);
}
Since the array is created on the stack, it will no longer exist once the routine in which it was created has exited.
Declare the array outside of those functions and pass it to them by reference.
void startShift(int (&shifts)[15]) {
// ...
}
void endShift(int (&shifts)[15]) {
// ...
}
int main() {
int array[15];
startShift(array);
endShift(array);
}
This isn't exactly pretty syntax or all that common. A much more likely way to write this is to pass a pointer to the array and its length.
void startShift(int* shifts, size_t len) {
// work with the pointer
}
int main() {
int array[15];
startShift(array, 15);
}
Idiomatic C++ would be different altogether and use iterators to abstract away from the container, but I suppose that is out of scope here. The example anyway:
template<typename Iterator>
void startShift(Iterator begin, Iterator end) {
// work with the iterators
}
int main() {
int array[15];
startShift(array, array + 15);
}
You also wouldn't use a raw array, but std::array.
It won't work to use a local array in the startShift() function. You are best off to do one or more of the following:
Use an array in the function calling startShift() and endShift() and pass the array to these functions, e.g.:
void startShift(int* array) { ... }
void endShift(int* array) { ... }
int main() {
int arrray[15];
// ...
startShift(array);
// ...
endShift(array);
// ...
}
Don't use built-in arrays in the first place: use std::vector<int> instead: that class automatically maintains the current size of the array. You can also return it from a function altough you are probably still best off to pass the objects to the function.
void endShift (int* arr)
{
arr[0] = 5;
}

How to sort a 2d array according to the second column using stl sort function?

How to sort a 2d array according to the second column using stl sort function ?
For eg
If we have an array a[5][2] and we want to to sort according to the ar[i][1] entry , how do we do it using the stl sort function. I understand we have to use a boolean function to pass as the third parameter but I am not able to design the appropriate boolean function ?
The stl sort requires the rvalue of the iterator being passed as the arguments. If you wanna use the sort function, you will have to compile in c++11 and use the array stl to store the array. The code is as follows
#include "bits/stdc++.h"
using namespace std;
bool compare( array<int,2> a, array<int,2> b)
{
return a[0]<b[0];
}
int main()
{
int i,j;
array<array<int,2>, 5> ar1;
for(i=0;i<5;i++)
{
for(j=0;j<2;j++)
{
cin>>ar1[i][j];
}
}
cout<<"\n earlier it is \n";
for(i=0;i<5;i++)
{
for(j=0;j<2;j++)
{
cout<<ar1[i][j]<<" ";
}
cout<<"\n";
}
sort(ar1.begin(),ar1.end(),compare);
cout<<"\n after sorting \n";
for(i=0;i<5;i++)
{
for(j=0;j<2;j++)
{
cout<<ar1[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}
Compiling in c++11 can be done by g++ -std=c++11 filename.cpp -o out.
In case you do not want to use c++11 or use the "array" stl, use the std::qsort function. With this you can use the traditional way to define the arrays like int a[10][2]. The code is as follows
#include "bits/stdc++.h"
using namespace std;
int compare( const void *aa, const void *bb)
{
int *a=(int *)aa;
int *b=(int *)bb;
if (a[0]<b[0])
return -1;
else if (a[0]==b[0])
return 0;
else
return 1;
}
int main()
{
int a[5][2];
cout<<"enter\n";
for(int i=0;i<5;i++)
{
for(int j=0;j<2;j++)
{
cin>>a[i][j];
}
//cout<<"\n";
}
cout<<"\n\n";
qsort(a,5,sizeof(a[0]),compare);
for(int i=0;i<5;i++)
{
for(int j=0;j<2;j++)
{
cout<<a[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}
Make your own compare function.
See the Beginners guide to std::sort().
http://www.cplusplus.com/articles/NhA0RXSz/