Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am an absolute newbie to the C language (I started today to learn it). As a test I wrote this program to output all prime numbers between two ranges. I then optimized and shortened the checkIfPrime function with some google help and took all return statements out of the function, for it obviously doesn't need to have a return value to understand I want to have the flag variable back. How does the function returns the flag variable even without any returns in it?
#include <stdio.h>
int checkIfPrime(int n);
int main(int argc, char *argv[]) {
int n1, n2;
scanf("%d %d", &n1, &n2);
for (int i = n1; i < n2; i++) {
if (checkIfPrime(i)) {
printf("%s", "Is prime: ");
printf("%d\n", i);
}
}
return 0;
}
int checkIfPrime(int n) {
int flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
flag = 0;
break;
}
}
}
Unlike some languages such as Groovy where the last expression evaluated by a function is the return value of the function, in C you need to explicitly state the return value with a return statement.
int checkIfPrime(int n)
{
int flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
flag = 0;
break;
}
}
return flag;
}
If you fail to explicitly return a value from a function that expects one, your code invokes undefined behavior.
As an example of undefined behavior, your original code give the "correct" answer for me, but if I change the function to this:
int checkIfPrime(int n) {
int flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
flag = 0;
break;
}
}
// this loop should have no effect
for (int i = 2; i <= (n / 2); i++) {
}
}
In a properly behaving program, the extra loop added should have no effect. But without a return, I get back this if I input 2 and 10:
Is prime: 2
Is prime: 3
Is prime: 4
Is prime: 5
Is prime: 6
Is prime: 7
Is prime: 8
Is prime: 9
If you had put the return statement in place at the end of the function, things like this wouldn't happen.
Why the above code behaves the way it does is an implementation detail of the compiler in use. A different compiler may have different output, or the same compiler with different optimization settings could have different output.
Your current function int checkIfPrime(int n) is by its definition saying it will return an int, so you must then return an int value.
If you really didn't want to return a value using the return statement, you could pass the value back as a pointer to a variable to store the flag in:
void checkIfPrime(int n, int *flag) {
*flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
*flag = 0;
break;
}
}
}
Its far easier to read and understand using a return of the value though, and main would then have to change to allocate a new variable and would have to call the function and then check the variable - much nicer just using the return value.
There are only two ways to give a value back from a function: explicitly return a value, or mutate a variable external to the function.
Except when writing OO code (and in that case you're mutating object fields), or a void function, your functions should always explicitly return a value.
Since you gave your function a return type, I'm surprised the compiler didn't raise an error.
You shouldn't try to avoid using return statements; avoid using them in ways that lead to confusing code.
How does the function returns the flag variable even without any returns in it?
It doesn't; or, it doesn't do so in a predictable or reliable manner.
The intent is that if you define a function T f() { ... } and T is not void, then you will have at least one return statement returning a value of type T.
For whatever reason, the language definition does not mandate a return statement in a non-void function1 (the compiler may complain, but it's not required to), but if the caller attempts to use the return value of the function and you don't explicitly return a value, then the behavior is undefined, meaning any result you get (whether expected or not) is considered "correct".
Interestingly, it does mandate that a return statement in a void function not return a value.
Related
I am new to coding. so I wanted to write a c program using recursion to calculate the factorial of a number.
#include <stdio.h>
int fact(int a) {
int n = 1;
if (a != 0)
return;
else
n = n * a;
a--;
fact(a);
return n;
}
int main() {
printf("%d", fact(5));
return 0;
}
This is the program I have written. I know this is probably wrong but I think I would understand programming better if I was able to understand why the above program is exactly wrong.
Because whenever you pass any value other than 0 to fact your code exits without even returning a value:
if(a!=0)
return;
You should get at least a warning from your compiler that this is invalid code, since fact is expected to always return an int value.
But even more so, this is a logical error.
Did you mean to write:
if (a == 0) return 1; //0! = 1
Lev M. pointed out your mistakes in his answer. This is a working recursive implementation of the factorial algorithm.
unsigned int fac(unsigned char n)
{
if (n == 0)
return 1;
return n * fac(n - 1);
}
This is a recursive function to find the amount of 2 appearing in a number.
Example Input:
221122
Example Output:
countTwo(): 4
#include <stdio.h>
void countTwo2(int num, int *result);
int main()
{
int number, result;
printf("Enter the number: \n");
scanf("%d", &number);
countTwo2(number, &result);
printf("countTwo2(): %d\n", result);
return 0;
}
void countTwo2(int num, int *result)
{
if(num > 0) {
if((num % 10)/2 == 1) {
*result += 1;
}
countTwo2(num/10, result);
}
}
I can't increment result since it has not been initialised but I also can't initialise result in the recursive function as this will reset the result.
Edit: This is a question given, with all the template written as above except for the code within countTwo. We are supposed to write the code in countTwo such that main() will be able to run.
Edit2: Thanks for the help! This problem has been solved by using static int. I understand that this is not very efficient. I will also ask my teacher pertaining to this question. Once again, Thanks!
The way to keep all the oddities of this code:
it has to be recursive
you cannot change main, so the initial result value will be undefined
is to, as you stated you cannot do, actually reset result inside countTwo2. However, you need to it in the right place, before you start incrementing.
The way to do that is to reorder your function and add the part that resets the value at the right place:
void countTwo2(int num, int* result)
{
if (num > 0)
{
countTwo2(num / 10, result);
if ((num % 10) / 2 == 1)
{
*result += 1;
}
}
else
*result = 0;
}
Notice that I moved the recursive call up above the if-then block that increments the result, and that when num is 0, we reset. This will call recursively down digits of the input until we're at the end, then reset the result, then return back up one digit at a time and optionally increment the value.
This requires no other changes to your code.
As many have stated, in comments and answers, this is obviously not a good implementation or design but if you have a confined context to work in, this is probably as good as it gets.
I can't see any good reason for declaring this as a void function with the result passed back via pointer parameter.
The following would be a lot cleaner, surely?
int countTwo(int num) {
return (num == 0) ? 0 : (num % 10 == 2) + countTwo(num / 10);
}
For reference, the proper way to write such a function is to not use recursion. It isn't obvious that the compiler will be able to unroll the recursion in this case, as the recursive call would be in the middle of the function, and also conditional.
Thus the only thing gained from recursion is slow execution and higher stack peak use. Why would we want slow execution when we can have fast execution? You should ask your teacher this question, so they can tell you why they are teaching it. I would be most curious to hear their rationale.
For a professional, non-academic programmer, the proper way to write the function would be to use a loop:
int count_n (int input, int n)
{
int result = 0;
for(; input>0; input/=10)
{
if(input%10 == n)
{
result++;
}
}
return result;
}
(This version doesn't work with negative numbers.)
As I mentioned before you may use static variables.
You do not need two arguments.
Here is a solution: #Lasse Vågsæther Karlsen
#include <stdio.h>
int countTwo2(long int num)
{
static int m=0; //static variable is initialized only once.
if (num==0)
return m;
else if (num % 10 ==2)
m=m+1;
num=num /10;
countTwo2(num);
}
int main()
{
int result; long int number;
printf("Enter the number: \n");
scanf("%ld", &number);
result=countTwo2(number);
printf("countTwo2(): %d\n", result);
return 0;
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I'm receiving Output: 1. I should count the number of times a digit appear in an integer, for example, for number 1222345 and n = 2 Should appear 3 times.
int countOccurrences(int n, int num)
{
int i,k;
i=0;
while(num!=0)
{
k=num%10;
num=num/10;
if(k==n)
{
i++;
}
}
}
// Main
void main()
{
int num= 1222345;
int n = 2;
printf("Occurance of a number: %d", countOccurrences(n,num));
}
You have undefined behavior in the code. The function is supposed to return an int and it didn't.
Solution is to add return i in the end of other function. This will give you correct result. In the countOccurrences() function
...
if(k==n)
{
i++;
}
}
return i;
}
I was skipping the discussion of error check and all that. As chux mentioned for n<=0 case you might want to add a different way of handling it but you didn't add it. Atleast consider those case and put an error message on whatever input you need.
Some corner cases are
n=0,m=0.
Negative value of n or m.
Put a return on your countOccurrences function please
int countOccurrences (int n, int num) {
int i, k;
i = 0;
while (num! = 0)
{
k = num% 10;
num = num / 10;
if (k == n)
{
i ++;
}
}
return i; }
As other have pointed out, there are important issues with your code.
Here is a recursive solution that you may find interesting:
int countOccurrences(int n, int num)
{
int count = ((num % 10) == n);
return (num < 10) ? count : count + countOccurrences(n, num / 10);
}
Few general remarks about your code:
When using printf(), you should #include <stdio.h>.
main() should return int.
Place spaces around operators and format your code consistently. This k = num % 10; is more readable than k=num%10;. (There's more to code formatting than a matter of taste; without spaces you create areas full of characters which are more difficult to parse for our visual system.)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
#include <stdio.h>
int main()
{
int i, n, c, p;
printf("enter\n");
scanf("%d", n);
c = find(n);
if (c == 1)
{
printf("no. is not prime");
}
else
{
printf("no. is prime");
}
}
find(int n)
{
int i = 2, p;
while (i < n)
{
p = n % i;
printf("value of p%d", p);
if (p == 0)
{
return 1;
}
i = i + 1;
}
return 2;
}
....................................
Above program giving me 'not a prime number' output for all inputs...also the value of p is always zero and this shouldn't be the case...
Please help...badly stuck...
Your scanf() call must take the address of n. Furthermore you primality test fails for numbers smaller than 2. It is also better to return non-zero for true, zero otherwise, so that the value can directly be tested with if. And you should find a better name than find.
Try something like this:
#define TRUE 1
#define FALSE 0
int is_prime (int n)
{
int i;
if (n < 2)
return FALSE;
for (i = 2; i < n; i++) {
if (n % i == 0) {
return FALSE;
}
}
return TRUE;
}
int main()
{
int n;
printf ("enter number: ");
scanf ("%d", &n);
if (is_prime (n)) {
printf ("number is prime.\n");
}
else {
printf("number is not prime.\n");
}
return 0;
}
Various improvements are possible but I wanted to stay as close to your code as possible.
This looks like a student exercise so let me start by suggesting that the debugger is your friend. :)
Having said that, you may want to review the Sieve of Eratosthenes and leverage Wikipedia for a source of some good test content.
As already suggested, there are loads of potential improvements... I'd modify your "find" function to be more clear as follows:
bool IsPrime(unsigned int n)
{
unsigned int nCounter = 2;
while (n % nCounter++);
return (nCounter > n);
}
Prime's can't be negative and since you're asking a "TRUE/FALSE" question, the name and return type should enforce that contract.
Several issues:
scanf("%d", n); should be scanf("%d", &n); - you need to pass the address of n so scanf can update it (note that you risk a runtime error,
since the value of n most likely isn't a valid address value);
Implicit typing of functions such as find(int n) {...} is no longer supported as of the C99 standard, and it was never good practice to begin with. You should (and for C99 and later, must) provide a type specifier along with the function name in both function declarations and function definitions - int find( int n ) {...};
Similar to 2, a function declaration must be visible before a function is called; the simplest way to accomplish this is to move the function definition above the definition for main. If you don't want to do that, then you need to add the declaration int find(int n); somewhere before find is called.
Note that you can speed up the primality test in a couple of ways. First, you can skip testing against even factors; if a number is divisible by a multiple of 2, then it's divisible by 2, and you would have already checked for that. Secondly, you don't need to test all factors up to n - 1; you only need to test factors up to the square root of n. You can put that all together like so:
if ( n < 2 )
return 0; // zero indicates false
if ( n == 2 )
return 1; // non-zero indicates true
int result = n % 2;
for ( int i = 3; result && i * i <= n; i += 2 ) // loops as long as result
result = n % i; // is non-zero, only tests
// against odd numbers up to
return result; // sqrt(n)
I have the programming reading in middle just fine however using the pointer with below and above is not giving the correct value to be found using middle.
Why is below (most likely above as well) negative when running in the for loop?
Am I calling using pointers in the correct way?
/*
*
*Function pwrTwo has one parameter "middle" it reads the inout from the user
*to find below and above
*
*the function is used to find the highest power of two below middle
*and the lowest power of two above middle
*
*The function then returns the two values and they are printed in the
* the main function displayed as below<middle<above
*
*/
#include <stdio.h>
int pwrTwo(int m, int*above, int*below) {
int i = 0;
*above = 0;
*below = 0;
for (i = 2; *below < m; i += 1) {
*below = pow(2, i);
printf("%d,%d,%d\n", below, m, i); //my check to see if below middle and i are correct
}
for (i += 3; *above > m; i -= 1) {
*above = pow(2, i);
printf("%d,%d,%d\n", below, m, above); // checking again
}
return;
}
int main() {
int middle = 1;
int above = 0;
int below = 0;
while (middle > 0) {
printf("Please input a value:");
scanf("%d", &middle);
pwrTwo(middle, &above, &below);
printf("%d<%d<%d\n", below, middle, above);
}
}
You need to include to use pow function
Since you are getting the values in the parameters, your return type should be void,
and you dont need to use pointers in this case, you want just one value for below, and one for above, so you just use a int..but...
you can work with this:
void pwrTwo(int m, int*above,int*below){
double log2m = log2(m);
*below = pow(2,floor(log2m));
*above = pow(2,ceil(log2m));
}
You are using printf with an int* instead of in an int. I am surprised your compiler did not give you warnings, since my compiler gives me warnings about this.
When you print a pointer as an int, you will get a negative number if the sign bit happens to be set for the address it stores.
Try changing
printf("%d,%d,%d\n",below,m,i)
to
printf("%d,%d,%d\n",*below,m,i)
as well as changing printf("%d,%d,%d\n",below,m,above) to printf("%d,%d,%d\n",*below,m,*above).
#3 is the main issue.
1) Missing #include <math.h>
2) Mis-matched return. Change from
int pwrTwo(int m, int*above, int*below) {
...
return;
}
to
void pwrTwo(int m, int*above, int*below) {
...
// return;
}
3) Wrong types in printf()
// printf("%d,%d,%d\n", below, m, i);
printf("%d,%d,%d\n", *below, m, i);
...
// printf("%d,%d,%d\n", below, m, above);
printf("%d,%d,%d\n", *below, m, *above);
...
4) Good idea to check return value from scanf()
// scanf("%d", &middle);
if (scanf("%d", &middle) != 1) Handle_Error();
5) Code may simplify. Watch out for range errors.
// some_int = pow(2, i);
some_int = 1 << i;