I'm currently doing a program which calculates the scalarProduct (Dot Product) using templates and I've run into a problem with two things.
One being: How to declare a template and call it from main.
Two being: How to pass Arrays to functions.
Any help is appreciated, thanks
// scalarProduct.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <math.h> /* sqrt */
using namespace std;
template<typename T>
void scalarProduct(T a[], T b[])
{
T a[3];
T b[3];
this->a[] = a;
this->b[] = b;
T axb;
T roota;
T rootb;
T result;
axb = ((a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]));
roota = sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2])); // the formula for the Euclidean length of the vector A.
rootb = sqrt((b[0] * b[0]) + (b[1] * b[1]) + (b[2] * b[2])); // the formula for the Euclidean length of the vector B.
result = axb / roota * rootb;
cout << "Result: " << result;
};
int main()
{
int a[3];
int b[3];
cout << "Enter A: " << endl; // Vector A Input
cout << "X:";
cin >> a[0];
cout << "Y:";
cin >> a[1];
cout << "Z:";
cin >> a[2];
cout << "Ennter B: " << endl; // Vector B Input
cout << "X:";
cin >> b[0];
cout << "Y:";
cin >> b[1];
cout << "Z:";
cin >> b[2];
scalarProduct(a[], b[]);
system("pause");
return 0;
}
For the template part of the question:
Heres the format for declaring and defining a template function:
template<compileTimeParameters>
returnType functionName(functionParameters) {
...;
}
and invoke it like this:
functionName<compileTimeParameters>(functionParameters);
For example, if you wanted a function that printed with cout whatever you gave it, go like this:
template<typename T>
void println(T value) {
std::cout << value << std::endl;
}
and invoke like this:
int main() {
//string
println<std::string>("yo yo yo print a newline");
//integer
println<int>(420);
//some other random type
println<myType>(someInstanceOfMyType);
}
And if the compiler can deduce the template parameters by the function parameters, you don't have to specify anything explicitly inside the <> brackets. For example:
int main() {
//compiler deduces that you are passing a const char[]
println("the compiler can figure out what I mean");
}
In scalarProduct() get rid of your local arrays a and b -- you are getting them from the parameters passed into the function. Also, scalarProduct is a function, not the method of a class, so there is no "this" to reference.
In main() just call:
scalarProduct(a, b);
It should work then.
Your problem is not with templates, but with C++ basics, like passing array to a function.
// scalarProduct.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <math.h> /* sqrt */
using namespace std;
template<typename T>
void scalarProduct(T a[], T b[])
{
/*
* remove this
T a[3];
T b[3];
this->a[] = a;
this->b[] = b;
*/
T axb;
T roota;
T rootb;
T result;
axb = ((a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]));
roota = sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2])); // the formula for the Euclidean length of the vector A.
rootb = sqrt((b[0] * b[0]) + (b[1] * b[1]) + (b[2] * b[2])); // the formula for the Euclidean length of the vector B.
result = axb / roota * rootb;
cout << "Result: " << result;
};
int main()
{
int a[3];
int b[3];
cout << "Enter A: " << endl; // Vector A Input
cout << "X:";
cin >> a[0];
cout << "Y:";
cin >> a[1];
cout << "Z:";
cin >> a[2];
cout << "Ennter B: " << endl; // Vector B Input
cout << "X:";
cin >> b[0];
cout << "Y:";
cin >> b[1];
cout << "Z:";
cin >> b[2];
//scalarProduct(a[], b[]);
scalarProduct(a, b);
system("pause");
return 0;
}
Also if you dealing with three dimensional points I think it would be a good idea to create struct Point or class Point. If you want your functions to deal with vectors, then use pointers or better std::vector.
Related
In the programming textbook I'm using (Programming: Principles and Practice using C++ by Bjarne Stroustrup), I'm trying to do one of the exercises found in the very early chapters (before the introduction of arrays or anything), but I can only solve it using an algorithm that looks quite weird and "backwards" to me. The exercise is to read from the console 3 integers and to sort them according to size, separated by commas. Here is what I wrote:
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
cout << "Enter three integers: ";
cin >> a >> b >> c;
if (a <= b and a <= c) {
cout << a << ", ";
if (b < c)
cout << b << ", " << c;
else
cout << c << ", " << b;
return 0;
}
if (b <= a and b <= c) {
cout << b << ", ";
if (a < c)
cout << a << ", " << c;
else
cout << c << ", " << a;
return 0;
}
if (c <= a and c <= b) {
cout << c << ", ";
if (a < b)
cout << a << ", " << b;
else
cout << b << ", " << a;
return 0;
}
return 0;
}
I know it's very long, but I can't think of any other way to do it with the tools at my disposal (if statements). Can you please help me and show me if there is any other way to do it? Thanks!
Depends on what you mean by "better". There is a shorter way to do that, just like most other things in C++:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <cstdio>
int main() {
std::istream_iterator<int> it{std::cin};
int a[]{ *it++, *it++, *it++ };
std::sort(std::begin(a), std::end(a));
std::printf("%d, %d, %d\n", a[0], a[1], a[2]);
}
Whether or not shorter is better is another discussion.
You can also do this without invoking std::sort, sorting by hand:
// Put the smallest number in a.
if (b < a)
std::swap(a, b);
if (c < a)
std::swap(a, c);
// Arrange the other two numbers.
if (c < b)
std::swap(b, c);
std::cout << a << ", " << b << ", " << c << '\n';
Hope this helps:
#include <iostream>
using namespace std;
int main()
{
int a, b, c, x, mid, max;
cout << "Enter three integers: ";
cin >> a >> b >> c;
if (a<b){
x = a;
max = b;
}
else {
x = b;
max = a;
}
if (c < x){
mid = x;
x = c;
}
if (c > max){
mid = max;
max = c;
}
else
mid = c;
cout << x << ", " << mid <<", "<<max;
}
This question already has answers here:
How does the function pow work?
(2 answers)
Closed 4 years ago.
I'm doing algorithm for solving Quadratic equation.
I type for A = 4, B = 10, C = 4 which gives value of 36 for delta.
My issue is that
int delta;
returns value of 35, and
double delta;
returns value of 36.
I'm using Atom text editor, rest of code is below.
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int a,b,c;
int delta;
int x1, x2;
cout << "Rownanie kwadratowe w postaci ax^2 + bx + c = 0" << endl;
cout << "Podaj wartosc A" << endl;
cin >> a;
cout << "Podaj wartosc B" << endl;
cin >> b;
cout << "Podaj wartosc C" << endl;
cin >> c;
delta = pow(b,2) - (4 * a * c);
cout << "Delta = " << delta << endl;
return 0;
}
It works for me. Bellow code is much shorter and better for the Minimum example, isn't it?
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int a = 4, b = 10, c = 4;
int delta = pow(b,2) - (4 * a * c);
cout << "Delta = " << delta << endl;
return 0;
}
If you use integral arithmetic then use integral not floating point operations. The problem consists of floats. Result of pow(b, 2) may be like 99.99999999997, that rounded down to int is 99.
#include <iostream>
using namespace std;
int main()
{
int a = 4, b = 10, c = 4;
int delta = b * b - (4 * a * c);
cout << "Delta = " << delta << endl;
return 0;
}
My program runs. However, it seems that the do-while loop won't loop. This is because the output always declare "...was obtained after 1 iterations". I mean it should take more than 1 iterations. I would like to ask for help for I am facing a brick wall right now. Thanks!
#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
int main()
{
int i,j,n,iter1=0,iter2=0;
double L,t,q,E,v,h,D,error,e;
cout << "\nUse length, L (m): ";
cin >> L;
cout << "\nUse thickness, t (m): ";
cin >> t;
cout << "\nUse uniform load, q (N/m^2): ";
cin >> q;
cout << "\nUse Young's modulus, E (N/m^2): ";
cin >> E;
cout << "\nUse Poisson's ratio, v: ";
cin >> v;
D=(E*pow(t,3))/(12*(1-pow(v,2)));
cout << "\nUse uniform interval, n: ";
cin >> n;
double u[n+1][n+1],r[n+1][n+1],w[n+1][n+1];
h = L/n;
cout << "\nUse tolerance, e: ";
cin >> e;
//PERFORM THE ITERATIONS!
cout << "* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" ;
cout.precision(5);
cout.setf(ios::fixed);
for (i=0;i<=n;i++)
for (j=0;j<=n;j++)
{
u[i][j]=0;
r[i][j]=0;
w[i][j]=0;
}
//Set the boundary conditions
for (i=0;i<=n;i++)
{
u[i][0]=0;
u[i][n]=0;
u[0][i]=0;
u[0][i]=0;
}
//Solving for the u-matrix
do
{
error=0;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
{
r[i][j]=0.25*(u[i-1][j]+u[i+1][j]+u[i][j-1]+u[i][j+1]-4*u[i][j]-pow(h,2)*(q/D));
u[i][j]+=r[i][j];
}
iter1++;
if (abs(r[i][j])>error)
error = abs(r[i][j]);
}
while (error>e);
//Solving for the w-matrix
do
{
error=0;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
{
r[i][j]=0.25*(w[i-1][j]+w[i+1][j]+w[i][j-1]+w[i][j+1]-4*w[i][j]-pow(h,2)*(u[i][j]));
w[i][j]+=r[i][j];
}
iter2++;
if (abs(r[i][j])>error)
error = abs(r[i][j]);
}
while (error>e);
//RESULTS!
cout << "\nThe matrix of deflection w was obtained after " << iter2 << " iterations" << endl;
cout << "\n(The matrix of variable u was obtained after " << iter1 << " iterations" << endl;
cout << "\n";
cout << "\nFor the matrix of deflection w, open the generated Excel file.\n";
return 0;
}
A better solution is to use a container, which will transparently manage assignment, copy, destruction, etc. without memory leaks.
There are plenty of implementations, here is a basic one
template<typename T>
class Matrix {
private:
unsigned int m_rows, m_cols;
std::vector<T> m_data;
public:
Matrix(unsigned int r, unsigned int c) // constructor
: m_rows{r}
, m_cols{c}
, m_data(r * c) // size of the vector
{}
T * operator[](int r) // address of first element of row r
{
return & m_data[ r * m_cols ];
}
};
Example of how to use it
Matrix<int> m(3,4); // declare a matrix
for (int r = 0; r < 3; r++)
for (int c=0; c<4; c++)
m[r][c] = 10*r + c; // usual notation
for (int r = 0; r < 3; r++) {
for (int c=0; c<4; c++) {
std::cout << m[r][c] << "\t";
}
std::cout << std::endl;
}
You can't declare arrays like that double u[n+1][n+1],r[n+1][n+1],w[n+1][n+1]; because variable n isn't known the time when array is declared. I guess it can't be declared that way even if the n is known during run time. It's possible only if the n is known during compilation.
The arrays should be declared as double **u; and when variable n is known use malloc or new.
int n;
double **u;
double **r;
double **w;
cout << "\nUse uniform interval, n: ";
cin >> n;
// C style of allocation, requires additional library, I think it's cstdlib
u = (double**)malloc(sizeof(double*)*(n+1));
for(int i = 0; i <= n; ++i) {
u[i] = (double*)malloc(sizeof(double)*(n+1));
}
// C++ style of allocation
r = new double*[n+1];
for(int i = 0; i <= n; ++i) {
r[i] = new double[n+1];
}
// C++11 or newer - compile with --c++11 flag
w = new double[n+1][n+1];
// Don't forget to clear memory
// C style
free(u);
// C++ style
delete r;
delete w;
I've been working for a couple hours trying to figure out what I'm doing wrong. All I need to do is find one root from a polynomial represented by an array using Newton's method. The two functions (polyval and polyder) seem to be giving me the right answers, and I feel that the main code is correctly doing Newton's method. I was hoping someone experienced could give me some advice.
#include <iostream>
#include <cmath>
using namespace std;
float polyval(float*, int, float);
void polyder(float*, int, float*);
int main(void) {
int n;
float x=-1,f;
float tol=pow(10,-5);
cout << "Enter polynomial order:" << endl;
cin >> n;
float* p=new float[n+1];
float* dp=new float[n];
cout << "Enter coefficients, starting with the highest power:" << endl;
for (int k=0;k<n+1;k++) {
cin >> p[k];
}
polyder(p,n,dp);
f=polyval(p,n,x);
while (fabs(f)>tol) {
x=x-f/polyval(dp,n,x);
f=polyval(p,n,x);
cout << x << endl;
cout << f << endl;
}
cout << "A real root is at x= " << x << endl;
cout << "To verify: p(" << x << ") = " << polyval(p,n,x) << endl;
return 0;
}
float polyval(float* p, int n, float x) {
float px;
px=0;
for (int k=0;k<n+1;k++) {
px=px+p[k]*pow(x,n-k);
}
return px;
}
void polyder(float* p, int n, float* dp) {
for(int k=0;k<n;k++) {
dp[k] = p[k+1] * (k+1);
}
}
Your call to polyval(dp,n,x) will access beyond the allocated space for dp, which has n entries and not the requred n+1.
#include <iostream>
using namespace std;
void reset(int *a, int *b){
int sum = *a + *b;
*a = (sum / 2.0 - sum / 2) >= 0.5 ? sum / 2 + 1 : sum / 2;
*b = *a;
cout << hex << (void *)a<<endl;
cout << hex << b<<endl;
}
int main(){
int a, b;
cin >> a >> b;
reset(&a, &b);
cout << a <<' '<< b << endl;
}
I use the code to reset two variable,but after I print the pointers of variable,the data changed.When I commente the two cout statement.It works.
Looks like this:
You should return to dec, because you changed the output to hex
#include <iostream>
using namespace std;
void reset(int *a, int *b){
int sum = *a + *b;
*a = (sum / 2.0 - sum / 2) >= 0.5 ? sum / 2 + 1 : sum / 2;
*b = *a;
cout << hex; //set hex for output stream
cout << (void *)a<<endl;
cout << b<<endl;
cout << dec; // return to dec system
}
int main(){
int a, b;
cin >> a >> b;
reset(&a, &b);
cout << a <<' '<< b << endl;
}
Variables are not modified, you change basefield format flag after using std::hex here:
cout << hex << (void *)a << endl;
cout << hex << b << endl;
That's why commenting this out "fixes" this "problem".
You can uncomment this call, but modify you reset() function, so it will restore original stream state:
void reset(int *a, int *b)
{
int sum = *a + *b;
*a = (sum / 2.0 - sum / 2) >= 0.5 ? sum / 2 + 1 : sum / 2;
*b = *a;
cout.setf(std::ios::hex); //Print as hexadecimal numbers
cout << (void *)a << endl;
cout << b << endl;
cout.setf(std::ios::dec); //Restore to decimal
}
I modified your reset to set hex only once instead of doing << hex every time you print something (although it is not necessary, because, as you noticed, stream is modified permanently - that's why I prefer explicit functions call).
Further read: std::ios_base::setf.