c++ references array - c++

I wounder how i can make this code work?
#include <iostream>
using namespace std;
void writeTable(int (&tab)[],int x){
for(int i=0;i<x;i++){
cout << "Enter value " << i+1 <<endl;
cin >> tab[i] ;
}
}
int main(void){
int howMany;
cout << "How many elemets" << endl;
cin >> howMany;
int table[howMany];
int (&ref)[howMany]=table;
writeTable(ref,howMany);
return 0;
}
And here are the errors that I have:
|4|error: parameter ‘tab’ includes reference to array of unknown bound ‘int []’|
|18|error: invalid initialization of reference of type ‘int (&)[]’ from expression of type ‘int [(((unsigned int)(((int)howMany) + -0x00000000000000001)) + 1)]’|
|4|error: in passing argument 1 of ‘void writeTable(int (&)[], int)’|
Thanks for help

If you are intending to pass the size of the array, then remove the reference
void f(int a[])
is equivalent to
void f(int* a)
so no copying will be done, if that is the concern.
If you want to take an array by reference, then you MUST specify the dimension. e.g.
void f(int (&a)[10])
Naturally, the best of the two is the third solution, which is to use std::vector's and pass them by reference, reference to const or by value if needed. HTH

Here is a slightly more C++ style of doing it:
#include <iostream>
#include <vector>
void writeTable(std::vector<int> &tab)
{
int val;
for (unsigned int i=0; i<tab.size(); i++)
{
std::cout << "Enter value " << i+1 << std::endl;
if (std::cin >> val)
{
tab[i] = val;
}
}
}
int main()
{
int howMany;
std::cout << "How many elements?" << std::endl;
std::cin >> howMany;
std::vector<int> table(howMany);
writeTable(table);
return 0;
}

You need not specify the dimension of the array if you make writeTable a function template.
template <typename T,size_t N>
void writeTable(T (&tab)[N]) //Template argument deduction
{
for(int i=0 ; i<N ; i++){
// code ....
}
}
.
int table[howMany]; // C++ doesn't have Variable Length Arrays. `howMany` must be a constant
writeTable(table); // type and size of `table` is automatically deduced

Following Amardeep's answer, here is a C++11 way to do it:
#include <iostream>
#include <vector>
void writeTable(std::vector<int> &tab)
{
int val;
for (auto& cell : tab)
{
std::cout << "Enter value " << i+1 << std::endl;
if (std::cin >> val)
{
cell = val;
}
}
}
int main()
{
int howMany;
std::cout << "How many elements?" << std::endl;
std::cin >> howMany;
std::vector<int> table(howMany);
writeTable(table);
return 0;
}
Note the range-based for used in writeTable.

Arrays of references are illegal, if that is what you are trying to do. It's not 100% clear to me from the title.

Related

Sorting array of objects in c++

I'm a newbie and this is my first question. So I am working for a task organizer and I want to organize list of tasks by their "urgency" value. Here is my code:
#include <iostream>
#include <math.h>
#include <vector>
#include <stdlib.h>
#include <list>
using namespace std;
struct Task {
public:
string name;
float deadline, estimated;
int urgency;
int getUrgency() {
urgency = ceil(deadline - estimated);
return urgency;
}
};
void newTask(Task task[], int n1) {
for (int i = 0; i < n1; i++)
{
system("cls");
cout << "Input task name: ";
cin >> task[i].name;
cout << "Input task deadline (in hours): ";
cin >> task[i].deadline;
cout << "Input task estimated work time (in hours): ";
cin >> task[i].estimated;
}
}
void printAll(Task task[], int n1) {
system("cls");
cout << "Name\tDeadline\tEstimated\tUrgency\n";
for (int i = 0; i < n1; i++)
{
cout << task[i].name << "\t" << task[i].deadline << "\t\t" << task[i].estimated << "\t\t" << task[i].getUrgency() << endl;
}
}
int main() {
int n;
cout << "How many work do you have? ";
cin >> n;
//Create number of object based on input n
std::vector<Task> p(n);
newTask(p.data(), n);
std::list<Task> taskList;
printAll(p.data(), n);
cin.ignore();
return 0;
}
I want to add a function that sorts the list of tasks by their "urgency" value. What kind of function should I use?
In your case you can use the std::sort function, defined in <algorithm> header, on the p vector defining a custom compare function:
std::sort (p.begin(), p.end(), sortTaskByUrgency);
where sortTaskByUrgency() is defined as:
bool sortTaskByUrgency(const Task& lhs, const Task& rhs)
{
return lhs.getUrgency() < rhs.getUrgency();
}
Using the above function in your sample code getUrgency() must be const:
int getUrgency() const { return ceil(deadline - estimated); }
removing useless int urgency public member.
I would try using std::sort. It will sort in place any iterable object (array, vector, etc...). A common std::sort function call has the following arguments: The first argument is an iterator/pointer to the beginning of the collection, the second argument is an iterator/pointer to the end of that same collection, and the third argument is a function callback that determines how the data is sorted. You can see an example implementation here

Invalid conversion from int* to int even though I delimit the pointer

I've received the following error:
NQueens.cpp:35:19: error: invalid conversion from 'int*' to 'int' [-fpermissive]
solution[i].y = *(possibilities + i);
I believe I delimited the pointer so that I can apply the value being pointed to the y coordinate for the n-queens problem. Am I missing anything, or is my compiler being dumb?
My header file:
#pragma once
#ifndef QUEEN
#define QUEEN
struct Queen {
int x, y;
};
#endif // !QUEEN
My C++ code:
#include "Queen.h"
#include <iostream>
#include <vector>
using namespace std;
bool isDiag(int, int, int, int);
bool solutionFinder(int, int, vector<int*>);
int main()
{
int n;
cout << "Enter a number n for the n-queen problem:\n";
cin >> n;
vector<int*> possibilities;
for (int i = 0; i < n; i++)
{
int arrayInt[n];
arrayInt[0] = i + 1;
for (int j = 1; j < n; j++)
{
arrayInt[j] = 0;
}
possibilities.push_back(arrayInt);
}
if (!solutionFinder(1, n, possibilities))
{
cout << "No Solution.\n";
}
Queen solution[n];
for (int i = 0; i < n; i++)
{
solution[i].x = i + 1;
solution[i].y = *(possibilities.begin() + i);
}
cout << "Solution: [(" << solution[0].x << "," << solution[0].y << ")";
for (int i = 1; i < n; i++)
cout << ", (" << solution[i].x << "," << solution[i].y << ")";
cout << "]\n";
return 0;
}
UPDATE:
I've tried the fix that mch suggested and now it compiles fine. However, I've ran into a new problem. When trying to print the coordinates for the queens, I'm getting what I believe are the locations of the values in memory.
Example:
Enter a number n for the n-queen problem:
4
Solution: [(1,1163548928), (2,32764), (3,1163548704), (4,32764)]
There are multiple issues with this code, but your immediate problem stems from this:
vector<int*> possibilities;
...
for (...)
{
int arrayInt[n];
...
possibilities.push_back(arrayInt);
}
...
solution[i].y = *(possibilities.begin() + i);
You have a vector of int* pointers, which are pointing at int[] arrays which you are creating inside a loop (and will be destroyed at the end of each loop iteration, thus leaving the vector holding dangling pointers to invalid memory).
You are then iterating through the vector, extracting each int* pointer and trying to assign it as-is to a single int, thus the compiler error. You would need to instead dereference the int* to get individual int values from the array, eg:
int *arr = *(possibilities.begin() + i);
solution[i].y = arr[someIndex];
Based on what you have shown, I think you have implemented your solutionFinder() incorrectly (but you didn't show how you actually implemented it). Rather than outputting a vector of int[] arrays, it would be better to have it output a vector of Queens instead, eg:
#include "Queen.h"
#include <iostream>
#include <vector>
using namespace std;
bool isDiag(int, int, int, int);
bool solutionFinder(int, int, vector<Queen>&);
int main()
{
int n;
cout << "Enter a number n for the n-queen problem:\n";
cin >> n;
vector<Queen> solution;
solution.reserve(n);
if (!solutionFinder(1, n, solution))
{
cout << "No Solution.\n";
return 0;
}
cout << "Solution: [(" << solution[0].x << "," << solution[0].y << ")";
for (int i = 1; i < n; ++i)
cout << ", (" << solution[i].x << "," << solution[i].y << ")";
cout << "]\n";
return 0;
}
bool isDiag(int, int, int, int)
{
// ...
}
bool solutionFinder(int, int, vector<Queen> &solution)
{
// populate solution with Queen's as needed...
for (...)
{
Queen q;
q.x = ...;
q.y = ...;
solution.push_back(q);
}
...
}
Contrary to the various comments you /can/ do can do arithmetic on "random access" iterators.
The issue is that you declared you have a vector of pointers.
You access the iterator like a pointer using operator * to indirect, but then you would would need to indirect again (another *) to follow the pointer held in the cell of the vector.
It is simper to use the array index syntax with vector poss[i] rather than *(poss.begin()+i) but you still need to do that extra indirection if you do indeed have a vector of pointers, *(poss[i]) which looks a bit ugly.

C++ Error: no viable conversion from returned value of type

I am trying to pass a vector to a function as an argument/parameter in order to print/return contents of that list/array/vector but when I compile the code I'm facing this error:
here's the code:
#include <iostream>
#include <vector>
using namespace std;
int printVector(vector<int> vec_name){
return copy(vec_name.begin(), vec_name.end(), ostream_iterator<int>(cout," ")); // returning contents of the array/vector
}
int main(){
vector<int> array;
for(int i=0;i<=10;i++){
array.push_back(i); // inserting values to the array
}
printVector(array); // Printing the vector array
}
PROBLEM SOLVED:
used for loop in order to print each value from the vector:
void printVector(vector<int> &vec_name){
for(int i=0; i<vec_name.size(); i++){
cout << vec_name[i] << " ";
}
}
void printVector(vector<int> const & vec_name)
{
for(size_t i = 0; i<vec_name.size(); i++){
cout << vec_name[i] << " ";
}
cout << "\n";
}

C++ simple class declaration program

I got a program to create in C++ in our introduction to C++ class in school. I am doing everything as I got in examples, but still getting errors.
w4x.cpp was given and I have to create Molecule.h and Molecule.cpp. I did that, but I am getting errors because my variables were not declared in scope, but I can't understand why.
// w4x.cpp
#include <iostream>
using namespace std;
#include "w4x.h"
#include "Molecule.h"
int main() {
int n = MAX_MOLECULES;
Molecule molecule[MAX_MOLECULES];
cout << "Molecular Information\n";
cout << "=====================" << endl;
for (int i = 0; i < MAX_MOLECULES; i++) {
if (!molecule[i].read()) {
n = i;
i = MAX_MOLECULES;
}
cout << endl;
}
cout << "Structure Name Mass\n";
cout << "==================================================" << endl;
for (int i = 0; i < n; i++)
molecule[i].display();
}
//Molecule.h
const int MAX_STRUCT = 10;
const int MAX_NAME = 20;
class Molecule {
char name[MAX_STRUCT];
char rate[MAX_NAME];
double weight;
public:
Molecule();
void read(const char*, const char*, double);
void display() const;
~Molecule();
};
//Molecule.cpp
#include <iostream>
#include <cstring>
using namespace std;
#include "Molecule.h"
Molecule::Molecule(){
name[0]= '\0';
rate[0]= '\0';
weight = 0;
}
void::read(const char* n, const char* r, double w) {
weight = w;
strncpy (name, n, MAX_STRUCT);
name[MAX_STRUCT]='\0';
strncpy (rate, r, MAX_NAME);
rate[MAX_NAME]='\0';
cout << "Enter structure : ";
cin.getline (n, MAX_CHARS);
cout << "Enter full name : ";
cin.getline (r, MAX_NAME);
cout << "Enter weight : ";
cin >> w;
}
void::display() const
{
int x;
for ( x=0; x<i; x++)
cout << n << " " << r << " " << w << endl;
}
My first question is, how can I pass char name[MAX_STRUCT]; char rate[MAX_NAME]; double weight; from Molecule.h to Molecule.cpp
The problem with your definitions is here:
void::read(const char* n, const char* r, double w)
and here
void::display() const
What :: says here, is that you are implementing a function within a class. So you need to specify which class and which function! What you are telling it now, is that you are implementing a function inside class void, which is nonexistent.
You should convert them to:
void Molecule::read(const char* n, const char* r, double w)
void Molecule::display() const
Your other question regarding passing class members:
The functions of a class have access to its variables, therefore, you don't need to concern yourself with that. Just use the variables.
Also, if you notice in your w4x.cpp, the function Molecule::read() is called without parameters, so your TAs ask you to implement it without parameters. Indeed, since you have access to Molecule::name, Molecule::rate and Molecule::weight directly, you should read data and write to those variables instead of asking for parameters. Therefore, your read function would look like this:
void Molecule::read()
{
// read into name, rate and weight
}
Furthermore, w4x.cpp expects read to report whether it has been successful or not. This means that you should do error checking in Molecule::read and return 0 if no errors or -1 (for example) in case of errors.

Error in using vector pointer in a function

I have this code, but it won't compile and i can't understand what is wrong - i guess the pointering of the vector is not correct.
My idea was to collect some numbers in main() and store them in a vector and array, and then pass the memory address of them to a function, and using a pointers to print the data stored.
I came up with this when i read something about pointers which said that i should use them in order to save memory, so IMO the code below will not copy the contents of the vector and the array but use a pointer to access their location in memory - that's what i want to do.
#include <iostream>
#include <vector>
using namespace std;
void function(vector<int>* a, int *s)
{
cout << "function starts.." << endl;
for(int i=0;i<a->size();i++)
{
cout << a[i] << endl;
cout << s[a[i]] << endl;
}
cout << "function ends..." << endl;
}
int main(void)
{
vector<int> m;
int s[102];
for(int i=0;i<10;i++)
{
m.push_back(i*i);
s[i*i] = i-2;
}
function(&m, &s);
return 0;
}
I receive several errors on compiling, something is wrong.
Please tell me what's wrong with my code and how to fix it. thank you...
You should pass the vector by reference, not by pointer:
void function(vector<int>& a, int *s)
And then
function(m, ...);
Using [] on a pointer to a vector would certainly cause strange problems because it behaves as if a pointed to an array of std::vectors (while it actually only points to one). The vectors itself are never indexed by that. You could also use (*a)[...] to index the vector by the pointer.
if you insist in parsing by pointer then the correct syntax shoulld be:
void function(vector<int>* a, int *s[])
{
cout << "function starts.." << endl;
for(int i=0;i<a->size();i++)
{
cout << (*a)[i] << endl;
cout << (*s)[(*a)[i]] << endl;
}
cout << "function ends..." << endl;
}
First of all in the main program s is a pointer to an int, while m is a vector. Thus the function call should be as follows:
function(&m, s);
Secondly in the function a is a pointer to a vector, so should be indexed as follows: (*a)[i].
However you should really be using const references to pass your vector around:
void function(const vector& a, int *s)
{
..
cout << a[i] << endl;
..
}
And call it like:
function(m, s);
(corrected)
&s is in fact int(*)[102]: pointer to a pointer to an array of 102 items.
You should just say
function(&m, s);
This is because by old C legacy rule, an array is essentially a const pointer to its item with index 0. So s is already int*
This version works:
#include <iostream>
#include <vector>
using namespace std;
void function(const vector<int>& a, int s [102])
{
cout << "function starts.." << endl;
for(int i=0;i<(int)a.size();i++)
{
cout << a [i] << endl;
cout << s[a [i]] << endl;
}
cout << "function ends..." << endl;
}
int main(void)
{
vector<int> m;
int s[102];
for(int i=0;i<10;i++)
{
m.push_back(i*i);
s[i*i] = i-2;
}
function(m, s);
return 0;
}