Q.Write a program which will print all the pairs of prime numbers whose sum equals the number entered by the user. ( suggested by Aniseed ) (Intermediate)

#include<iostream.h>
#include<conio.h>
#include<math.h>

int prime(int);
void main()
{
 int i,j,c1,c2,num,f1,f2;
 clrscr();
 cout<<"Enter the number-";
 cin>>num;
 for(i=2,j=num-2;i<=num/2;i++,j--)
 {
  f1=prime(i);
  if(f1) 
   { 
    f2=prime(j);
	if(f2)
    cout<<"Pair:"<<i<<" + "<<j<<endl;	
   }
 }  
 getch();
}	  
int prime(int a)
{
 int i;
 for(i=2;i<=sqrt(a);i++) 
  if(a%i==0)
   return 0;
  else 
   continue;	
 return 1;
}

Plz verify it. Any suggestions,comments or recommendations are welcomed.

> #include<iostream.h>
This is old. The correct form is #include <iostream>
If you (or your compiler) don't know about namespaces, then it's time you looked into it, or upgraded your compiler. namespaces have been standard issue since 1998, so there's really no excuse any more.

> #include<conio.h>
This is non-standard. If you can write your code without it, do so.

> #include<math.h>
In a namespace enabled compiler, this would be #include <cmath>

> void main()
This is just wrong. main returns an int.

Your prime() function could be more efficient, especially for large numbers.
How many even primes are there?

Salem's post is just OK. Things that I more wanna say that if you write #include<iostream> then you must write "using namespace std;" next line & you can use #include<cmath> in place of #include<math.h>. That's all.

I know about namespaces and the new standards i.e #include<iostream> , but ya my compiler "Turbo C++ v3.0" is old and dont understands the new formats like namespaces and the new style header files. An upgraded, according to the new standards, code will be

#include<iostream>
#include<cmath>
using namespace std;
bool isprime(int);
int main()
{
 int i,j,c1,c2,num;
 bool f1,f2;
 cout<<"Enter the number-";
 cin>>num;
 for(i=2,j=num-2;i<=num/2;i++,j--)
 {
  f1=isprime(i);
  if(f1) 
   { 
    f2=isprime(j);
	if(f2)
    cout<<"Pair:"<<i<<" + "<<j<<endl;	
   }
 }  
 return 0;
}	  
bool isprime(int a)
{
 int i;
 for(i=2;i<=sqrt(a);i++) 
  if(a%i==0)
   return false;
  else 
   continue;	
 return true;
}

And thanks Salem and hiraksarkardg for your concern. :) Is conio.h not ISO C++ standard. Which funtion to be used in place of clrscr() and getch()?

> Is conio.h not ISO C++ standard.
Correct.

> Which funtion to be used in place of clrscr() and getch()?
Such things only matter (to some extent) when you're running from the IDE.
Most programs have neither.
Consider 'dir', which neither clears the screen, nor waits for a key press.

Why void main is deprecated in ISO standards? Where can i get a brief overview of the ISO C++ standards?

You can't deprecate what was never standard to begin with.
void main has always been wrong, despite what many popular books and sloppy compilers say or do

Thanks Salem for help, I think you really hate those who use "void main()" and you love "int main()" as your avtar and line under name says :D

Any other tips for efficiency?
There is only 1 even prime number i.e 2.

>>There is only 1 even prime number i.e 2

So, is there a simple way to determine if a number is even or odd? And, if any factor above 2 is even can the number be prime?

This might be a little more optimized:

bool isprime(int a)
{ 
  bool result = true;
  int i; 

  //assume a > 0
  if(a % 2 == 0)
    result  = false;
  else  
  {
     //check for factors, i, that are odd and above 1
    for(i = 3; i <= sqrt(a); i += 2) 
    {  
       if(a % i == 0) 
       {
          result = false;  
          break;
        }
    }
    return result;
}

Salem gave me the hint, but I dont got it. :( Thanks Lerner for helping.

Salem gave me the hint, but I dont got it. :( Thanks Lerner for helping.

"I don't get it" isn't helpful. You need to be more specific. What don't you get? The point is that this function is inefficient:

int prime(int a)
{
 int i;
 for(i=2;i<=sqrt(a);i++) 
  if(a%i==0)
   return 0;
  else 
   continue;	
 return 1;
}

because it is checking whether 4, 6, 8, 10, etc. are prime by testing whether a % i is equal to 0. You don't need to test 4, 6, 8, 10, etc. at all since there is no way they can be prime since they are even and not equal to 2. So test whether a is equal to 2 at the top. If it is, return true. Then test whether a is even. If it is, a is not prime, so return false. After that, just test the odd values of i as Salem and Lerner suggested.


Lerner's code:

for(i = 3; i <= sqrt(a); i += 2)

See the red text and compare it to your highlighted red text. Yours starts at 2 and checks EVERY number, including the even numbers. Lerner's tests for 3, 5, 7, 9, etc., but not 4, 6, 8, etc. since these are definitely not prime.

Also, note that Lerner checks for evenness of a before executing the loop above. the loop above executes only if a is not even.

Thanks VernonDozier for your concern. :) Actually after the Lerner's post, i realized what was Salem pointing at. "I dont got it" at the time when Salem gave me the hint, but after lerner's post it got clear. Anywayz, Thanks VernonDozier .

When i compiled the above code in Visual C++, I got the following error

error C2668: 'sqrt' : ambiguous call to overloaded function

Though I understood the error, but the same code gave no errors when i compiled it in DEV-CPP. So my question is why does different compilers give different errors(and some dont give that too)? Which one's ISO based? Does every compiler have different header files? Previously, i used Turbo C++ v3.0 but it doesn't supports new C++ code. Which compiler replaced Turbo C++?

A lot of questions ;)

Yes, they all give different errors.
But all ISO compilers should spot the same kinds of errors.

Another problem is you're computing sqrt(a) EVERY time around the loop, but the answer will not change from one iteration to the next.

> Does every compiler have different header files?
There's a standard set.
If your code only uses those headers, and is a correct program, then any ISO C++ compiler will be able to compile it.
Having multiple compilers on your machine is a great way of making sure that your code (and your knowledge) is really portable.

The best of the Borland compilers is probably this one
http://www.codegear.com/downloads/free/cppbuilder
Though they've recently started re-using the "Turbo" name for some new offerings as well. I don't know much about them yet.

Comments
Thanks Salem.

Thanks Salem for your answers. :) But DEV-CPP compiled the code with no error, whereas with the same code Visual C++ gave the above error.

cmath different in visual c++ and dev c++ ? Sorry, I know i ask a lot of questions but i'm Curious.

cmath different in visual c++ and dev c++ ? Sorry, I know i ask a lot of questions but i'm Curious.

cmath is Standard, so it'll be the same everywhere. It's not compiler-specific and is thus portable (i.e. doesn't matter which compiler you use and which Operating System you use).

Same thing happened to me with this program. Dev C++ lets me get away with it, Visual C++ doesn't. Seems like a contradiction of the above statement. Basically I think Dev C++ lets you get away with something that is not technically legal, but if you write it the way it's supposed to be written, you're GUARANTEED that it will work. However, some things that are against the rules will work some of the time on some compilers, but you still shouldn't do it. I think that's the lesson. We just got lucky that we didn't get an error on Dev C++.

#include <iostream>
#include <cmath>

using namespace std;


int main ()
{
    int a = 5;
    cout << sqrt (a) << endl;
    cin.get ();
    return 0;
}

If you typecast a to a double in line 10 like this:

cout << sqrt ((double) a) << endl;

it'll work on either compiler. I'm a little confused as to why myself. Maybe Dev C++ automatically typecasts it for you, but Visual C++ doesn't? Best thing is to probably typecast it to a double to remove all doubt that it may fail on some compilers. Note that sqrt (int) doesn't exist, as Salem mentioned, so it probably shouldn't be used :

http://www.cplusplus.com/reference/clibrary/cmath/sqrt.html

Comments
Thanks for the cmath explanation.

> cmath different in visual c++ and dev c++ ?
The contents which ISO state they should have should be the same, from a logical viewpoint anyway. The actual characters will surely be different.

The problems come in when you use a compiler specific extension in one, which isn't in the other. I don't have the VS compiler to try it to see what it's really complaining about.

Most good compilers have an "ANSI" or "ISO" mode which turns off all the extensions. But even then, it's not a totally foolproof way of making sure your code works on many compilers.

There is a free version of the ISO draft C++ standard on the web somewhere, but I can't seem to find it at the moment. It's definitely worth getting hold of if you want to write portable code.

This question has already been answered. Start a new discussion instead.