C programming passing function in if condition - c

I'm writing simple function which returns maskable array of zeros and ones to array of numbers.
If number is a power of two maskable index will be one if not then zero.
It works fine without passing my simple function isPower() , but when I do pass it. weird things happen.
I want my code works with
if(isPower(nums[i]))
Without or condition
#include<stdio.h>
int *isPowerOf2(int num, int*nums,int *result);
int isPower(int num);
int main(void)
{
int array[]= {1,2,2,4,4,3,4,3,3,4,4,4,4,4};
int size=0;
int *result=NULL;
result=isPowerOf2(14,array,&size);
for(int i=0; i<size; i++)
{
printf("%i : %i\n",array[i],result[i]);
}
free(result);
printf("%i",size);
return 0 ;
}
int *isPowerOf2(int num, int*nums,int *result_num)
{
int *result=(int *)malloc(num*sizeof(int));
*result_num=num;
for(int i=0; i<num; ++i)
{
if(isPower(nums[i])||!(nums[i]&nums[i]-1)) //this won't work but when I use !(nums[i]&nums[i]-1) it works fine
{
result[i]=1;
}
else
{
result[i]=0;
}
}
return result;
}
int isPower(int var)
{
return ((var)&(var-1)==0)?1:0;
}

At times like this it pays to check what you're actually computing:
#include<stdio.h>
int main() {
printf("%d %d\n",!(7&6),((7&6==0) ? 1 : 0)); //Not a power of 2
printf("%d %d\n",!(8&7),((8&7==0) ? 1 : 0)); //Power of 2
return 0;
}
Returns:
0 0
1 0
If you think about it a bit, should make sense. Or does it? Operator precedence is killing you here. Why would the bottom right be 0?

Befare that
(1 & 2) is a bitwise operand while
(1 && 2) is the logical operand.
So to be clear:
(1 & 2) == 0 is something completely different than !(1 & 2).

Related

product of digits not including 0 on C

#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b,c;
b=1;
a=0;
scanf("%d", &a);
while (a>0)
{
c=a%10;
if (c==0)
b=b*1;
else {
b=b*(a%10);
a=a/10;
}
}
printf("Proizvedenie: %d\n", b);
return 0;
}
It doesnt work when I add 0 in any position of number, but i added if and dont know why it doesnt work, cycle just does not end, pls help
01234 - 24; Right
1234 - 24; Right
12304 - doesnt work
12340 - doesnt work
WHY PLS HELP =(
You're only dividing a by 10 when the current digit is not 0. When the digit is 0 a stays the same and you and up in an infinite loop.
Move the update of a to outside of the if block. Also, b=b*1 is a no-op, so you can remove that.
while (a>0)
{
c=a%10;
if (c!=0) {
b=b*c;
}
a=a/10;
}
You're only doing a = a/10 in the else block. So when you get to a 0 digit, you stop dividing by 10 and get stuck in an infinite loop.
Take that line out of the if/then, since it needs to be done every time.
while (a>0)
{
c=a%10;
if (c!=0) {
b *= c;
}
a /= 10;
}
unsigned int product(int x)
{
int result = !!x;
while(x)
{
if(x % 10) result *= abs(x % 10);
x /= 10;
}
return result;
}
int main(void)
{
int testData[] = {0, 1234, 12304, 12340, -1234, -12304, -012340 /* <- octal number!! */};
for(int x = 0; x < sizeof(testData)/sizeof(testData[0]); x ++)
printf("%d - %u\n", testData[x], product(testData[x]));
}
https://godbolt.org/z/T8T1a5YEE
Use functions.
integers can be negative as well
You need to handle zero too.
In your code:
c=a%10;
if (c==0)
b=b*1;
else {
b=b*(a%10);
a=a/10;
}
you need to move a = a / 10 outside the if as it is only executed when a % 10 is not zero. If it is, a does not change and you are in an infinitive loop
Others have noted the flaw in your code (location of a=a/10; inside else code block.
Here is a branchless way to achieve your objective. "Branching" (using an if() conditional) can make code run much slower when the processor's pipeline prediction turns out to be wrong. When processing millions (or billions) of data items, this may be a significant cost in time.
#include <stdio.h>
#include <stdlib.h>
int main() {
int a = 0, prod = 1;
if( scanf( "%d", &a ) != 1 ) {
fprintf( stderr, "scanf failed\n" );
return 1;
}
for( a = abs(a); a; a /= 10 ) {
int r = a%10;
prod *= r+(r==0); // branchless technique
}
printf( "Proizvedenie: %d\n", prod );
return 0;
}
54300012
Proizvedenie: 120
When the value of r is one of 1-9, r==0 has the value 0.
When the value of r is 0 and r==0 has the value 1.
So the 10 different rhs values can be 1, 1, 2, 3, 4, 5, 6, 7, 8 or 9.

Learning C: if and functions not executing in loop

I have started relearning C (self study), and ran into a problem with an if statement not always executing inside of a loop. What's odd is that on it's own, the function executes correctly, but unless I add a printf() statement referencing the variable in the loop then it won't attempt to test the if statement.
Specifically, the line printf("%d ", aCounter); in the while loop in the main(void) function is what's required for it to attempt test the if statement. I had a similar problem using a for loop (as you can see it's commented out). I am confused as to why it doesn't test the if statement without the printf() mentioned. And yet it does successfully find: 1, 6, 24, 28, and 496 with the printf() statement. It only finds "1" without it.
#include <stdio.h>
int isPerfect(unsigned int n);
int main(void) {
/* for (unsigned int i = 1; i <= 1000; i++) {
if (isPerfect(i) == 1) {
printf("%d is perfect\n", i);
}
}
*/
int aCounter = 0;
while (aCounter < 1000) {
aCounter++;
if (isPerfect(aCounter) == 1 ) {
printf("%d is perfect\n", aCounter);
for (int aTemp = 1; aTemp < aCounter; aTemp++) {
if (aCounter % aTemp ==0) {
printf("%d is a factor of %d\n", aTemp, aCounter);
}
}
}
printf("%d ", aCounter);
//aCounter++;
}
int a = 6;
if (isPerfect(a) == 1 ) {
printf("%d is perfect\n", a);
}
printf("%d is perfect: %d\n", 6, isPerfect(6));
printf("%d is NOT perfect: %d\n", 8, isPerfect(8));
printf("%d is perfect: %d\n", 6, isPerfect(6));
}
int isPerfect(unsigned int n) {
int aNumber;
for (int i =1; i <= n; i++) {
if (n % i == 0) {
aNumber += i;
if (aNumber == n)
{
return 1;
}
}
}
return 0;
}
I'm not sure about the expected output of your program, but I can see that inside the isPerfect(unsigned int n) function, we have a statement aNumber += i; which basically does is aNumber = aNumber + 1;, i.e, update the value of aNumber by 1. But as we can see, in the very first statement inside this function where aNumber is defined, it isn't initialized, so updating its value to 1 seems pointless as it's previous value is unknown. Initializing its value , let's say int aNumber = 0;
will do the job.
But uninitialized variable in C need not always contain a garbage value.
automatic (local) variables are not guaranteed to be zero, can contain
garbage but global variables and static variables are guaranteed to be
zero
please refer to this post StackOverflow post for more details.
.

Need to generate 4 random numbers without repetition in C programming. 1 to 4

I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}

Incrementing pointer's value doesn't work

This program is supposed to count number of similar entries, using pointers, but
whenever I type in number, counter is always equal to zero. What am I going wrong?
#include <stdio.h>
#include <stdlib.h>
//using function to count similar enteries in an array...
void count_similar_enteries(int array_func[10],int *number, int *ptr_to_counter);
int main()
{
int number = 0;
int array[10] = {0,1,1,2,3,1,2,67,65,1};
int counter = 0;
printf("enter a number\n");
scanf("%d", &number);
count_similar_enteries(array, &number,&counter);
printf("the number of similar enteries are %d\n", counter);
return 0;
}
void count_similar_enteries(int array_func[10],int *number, int *ptr_to_counter)
{
int i;
for (i = 0; i< 10 ; i++)
{
if(array_func[i] == *number)
{
*ptr_to_counter++;
continue;
}
else
{
continue;
}
}
}
*ptr_to_counter++; is incrementing the pointer itself, write (*ptr_to_counter)++; to increment the value of the ptr_to_counter.
Note that continue; is redundant. You don't have to have if-else there. The loop will be "looped" anyway. You can just do:
for(i = 0; i< 10 ; i++) {
if(array_func[i] == *number) {
(*ptr_to_counter)++;
}
}
I advise you to reduce the amount of pointers as much as you can, for example, you don't have to pass a counter by pointer. You can just have a local int counter; and return its value to the caller.
You are incorrectly incrementing counter value at address ptr_to_counter.
You have use *ptr_to_counter++ which means *(ptr_to_counter++) i.e. it is increamenting address not the value. You should use (*ptr_to_counter)++. It will work perfectly.
I think you require
*ptr_to_counter = *ptr_to_counter + 1;
EDIT
Perhaps this would be a better implementation
int count_similar_enteries(int arr, size_t len,int number)
{
i;
int count = 0;
for (size_t i = 0; i<len ; ++i)
{
if(arr[i] == number)
{
++count;
}
}
return count;
}
If you are not sure about operator precedence please use brackets, it will also increase readability of your code.
*ptr_to_counter++ will work like *(ptr_to_counter++) because ++ has higher precedence. You should have used (*ptr_to_counter)++
*ptr_to_counter++
means
*(ptr_to_counter++)
which means increment the address holed by ptr_to_counter, which is taking your pointer to the adjacent address where nothing is stored(or may be garbage).
You should use (*ptr_to_counter)++ meaning increment the value pointed at by ptr_to_counter.

How write a recursive print program

Gurus,
I want to know how to write a recursive function that prints
1
12
123
1234
...
......
For eg: display(4) should print
1
12
123
1234
Code
#include <stdio.h>
void print(int n)
{
if(n != 0)
{
print(n-1);
printf("\n");
print(n-1);
printf("%d",n);
}
}
int main()
{
print(3);
}
Output
1
12
1
123
Issues
I wanted to write a pure recursive (without any loop) function but unable to filter unwanted prints.
Hope someone will help me out!!!
Update
Thanks all for the answers.From all the comments which were given it seems like we can write one with only recursion and a loop is required.
To define a recursive function, you have to do three things:
Define what the function does. In this case it is printing numbers from 1 up to n.
Define what the recursive call is. What happens the next time around? The easiest way is to think from the bottom up; in this case, on each earlier line, it is printing numbers up to one less than the previous. Therefore, every time you call the function again, you want to call it with one less than the previous number.
Define your stop condition. When should I stop recursing? In this case, once you hit the number 1, this will be your last iteration. This means, we want to call the recursive function until this stop condition is reached - or in other words, while n is greater than 1.
Therefore, we end up with the following algorithm:
function display(n):
if(n > 1):
display(n-1);
print 1..n;
EDIT: OK, I improved my answer with the guidelines of #lc.
void print_recursive(unsigned int num) {
if (num > 1) {
print_recursive(num - 1);
}
for (unsigned int i = 0; i < num; i++) {
printf("%d ", (i + 1));
}
printf("\n");
}
This question is quite old, yet none of the answers answer the actual question, viz. solving the problem in C using recursion only, without explicit loops.
Here is a simple solution obtained by fixing the misunderstanding present in the original code (confusion between two possible functions of "print"). There are no explicit loops.
#include <stdio.h>
void countto(int n)
{
if(n != 0)
{
countto(n-1);
printf("%d",n);
}
}
void triang(int n)
{
if(n != 0)
{
triang(n-1);
printf("\n");
countto(n);
}
}
int main()
{
triang(4);
}
We keep calling PrintIt() with the argument-1 recursively until x < 1. Each call will then return in reverse order when x < 1. At each return we print a line starting at 1 to x.
#include "stdio.h"
void PrintIt( int x )
{
int i;
if( x > 1 )
{
PrintIt( x - 1 );
printf("\n");
}
for( i = 1; i < x+1; i++)
{
printf("%d", i);
}
return;
}
int main(int argc, char *argv[])
{
PrintIt( 4 );
return 0;
}
The recursive function used here is func(int).
Initially the value is passed from the main() program.
The recursion occurs till we reach the exit condition , which is val=0 in this case.
Once we reach that level , we move the penultimate frame a print "1". The same pattern is followed to attain the sequence "1 2". . . "1 2 3 " . . . "1 2 3 4"
int func(int val){
int temp,i;
if( val == 0 )
{
val++;
return val;
}
else
{
val--;
temp=func( val );
for (i=1;i<=temp;i++)
{
printf("%d",i);
}
printf("\n");
temp++;
return temp;
}
}
int main(){
int value=4, result;
result=func(value);
}
Just for fun, here's a purely recursive solution. It's in python, which is practically pseudocode anyway. (Non-pythonic newlines are for clarity).
def loop(max, row=1, col=1):
if col <= row:
print col,
loop(max, row, col+1)
elif row < max:
print "\n",
loop(max, row+1, 1)
else:
print "\n",
#include<stdio.h>
void print_num(int x);
int n;
void main(){
printf("Enter number of lines: ");
scanf("%d",&n);
print_num(1);
}
void print_num(int x){
int i;
for(i=1;i<=x;i++){
printf("%d",i);
}
if(x<n){
printf("\n");
x++;
print_num(x);
}
}
This is simple, right?
void display(int k)
{
if (k < 1) { return; }
display(k-1);
for (int i = 1; i <= k; i++)
{
cout << i;
}
cout << endl;
}
int main()
{
int a = 4;
display(a);
return 0;
}

Resources