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.
.
Related
I do not know why this is giving me garbage:
#include <stdio.h>
int main(){
int a[10];
for(
int i =0;
i++<10;
a[i-1]=i
)
{
printf("%i:%i\n", i-1, a[i-1]);
}
}
Which gives me:
0:1676584240
1:32609
2:0
3:0
4:-1577938528
5:21992
6:-1577938864
7:21992
8:2114427248
9:32766
The indices looks correct, and even the assignment inside the loop, is correct (e.g. printf("%i\n",a[0]) gives 1 which is correct, after loop). But inside the body of for loop, the printf, despite having correct indices, gives wrong values (some garbage). Why is that?
EDIT, after some answers with ... && (a[i]=i), I have tried to do that with other statements:
for(
int i = 0;
i<10 && (a[i]=i);
(i++) && printf("%i\n", a[i])
);
But that does not print anything, just gives warning:
warning: value computed is not used [-Wunused-value]
i++ && printf("%i\n",a[i])
Why? when I can make "true" statement of (a[i]=i), why cannot I make "true" statment of (i++)?
doing
for(
int i =0;
i++<10;
a[i-1]=i
)
{
printf("%i:%i\n", i-1, a[i-1]);
}
you set the entries after you print them because a[i-1]=i is executed after the body of the for, so you print non initialized array entries
your code is also 'complicated' because you increase i too earlier in the test part of for, a 'standard' way to do what you (probably) want is :
for(int i = 0; i < sizeof(a)/sizeof(*a); ++i) {
a[i]=i+1;
printf("%i:%i\n", i, a[i]);
}
if you really want to not have a[i]=i+1; in the body you can do that :
for(int i = 0; (i < sizeof(a)/sizeof(*a)) && (a[i]=i+1); ++i) {
printf("%i:%i\n", i, a[i]);
}
to avoid a warning when compiling do ... && ((a[i]=i+1) != 0);
note (a[i]=i+1) is not false because values at least 1, in case you wanted to do a[i]=i the test to use can be (i < sizeof(a)/sizeof(*a)) && (a[i]=i, 1) to not be false when i is 0
but that does not help to read the code ^^
A for loop consists of 4 parts:
Initialisation
Condition
Body code
Action
Example:
for (initialisation; condition; action)
{
Body code
}
The execution order is as I enumerated it above.
In your example,
for (int i = 0; i++ < 10; a[i-1])
{
printf("%i:%i\n");
}
Initialisation - i = 1
Condition - i++ < 10; --> 0 < 10 = true, i = 1
Body code - printf while i=1, a[0] is still uninitialised!
Action - a[i-1] = i, a[0] = 1 (only now a[0] gets initialised!
In your code you first execute the code in the brackets, then you assign the array. It has to be done the right opposite way.
#include <stdio.h>
int main()
{
int a[10];
for(int i =0; i++, i <= 10 && (a[i-1] = i);)
{
printf("%i:%i\n", i-1, a[i-1]);
}
}
https://godbolt.org/z/r-DvJi
or better
#include <stdio.h>
int main()
{
int a[10];
for(int i = 0; i < 10 && (a[i] = i + 1); i++)
{
printf("%i:%i\n", i, a[i]);
}
}
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;
}
I'm try to complete a task set by a lecturer and I have the following code:
#include <stdio.h>
#define N 100
int main(void)
{
int i, a, cnt = 1;
for (a = 1; a < 6; a++){
for (i = 0; i < N; i++, cnt++) {
if (a%2 > 0){
a = 3*a + 1;
}
else{
a = (a/2);
}
printf("%3d\n", a);
if (a == 1){
printf("Count: %d\n", cnt);
return 0;
}
}
}
return 0;
}
The point of this code is to run a hailstone sequence on each integer, a. For now I have it to start at a = 1, then adding 1 to a, and running the sequence again up until a = 5.
This code runs it for the initial value of a but doesn't then add one to a to run it again. I really can't see why it won't do the outer loop again, please help!
A hailstone sequence is where it takes the integer before it in the sequence, if this integer is odd it computes 3*a +1, and if the integer is even it computes a/2. I've told the sequence to stop once a = 1.
Thanks in advance!!
Instead of return 0; in second loop add break; to move out of the inner loop and continue with outer loop.
If you don't want to add break this is another way and there are minor changes in your code which I have highlighted below.
1. You will have to reinititlize cnt for every new value of a.
2. You will have to take a new variable instead of a for calculations
3. For moving out of loop you can increase value of i.
#include<stdio.h>
int main()
{
int i, a, cnt=1, b;
for(a=1; a<6; a++){
cnt = 1;
b = a;
for(i=0; i<100; i++, cnt++){
if(b%2 > 0){
b = 3*b + 1;
}
else{
b = b/2;
}
printf("%d ", b);
if(b==1){
printf("\nCount %d\n", cnt);
i = 100;
}
}
}
return 0;
}
I'm only a student too, but try removing the first "return 0;", I think that's what is ending the code early.
return will end the function. I think what you are looking for is break
I have been trying to debug this code I made, it outputs only 1's in the first row of the array and all other elements are zero(from second row till the last element.), is it the problem of function calling of passing the array by value or something else. Help appreciated.
#include<stdio.h>
#include<stdlib.h>
int isSafe(int x, int y, int a[][8])
{ int i,j;
//for left check of the cols
for(i=0;i<y;i++)
{
if(a[x][i]==1)
return 0;
}
//for check of left upper diagonals
for (i = x, j = y; i >= 0 && j >= 0; i--, j--)
{
if(a[i][j]==1)
return 0;
}
//for check of left lower diagonals
for(i = x, j = y; i<=7 && j>=0; i++,j--)
{
if(a[i][j]==1)
return 0;
}
return 1;
}//close isSafe
int EQueen(int a[][8], int q)
{
int c=0;
if(q==8)
return 1;
else
{
while(c<=7)
{
if(isSafe(q,c,a)==1)
{
a[c][q] = 1;
if(EQueen(a,q+1)==1)
return 1;
else
a[c][q] = 0;
}//close if
c++;
}//close while
return 0;
}//close else
}//close EQueen
int main()
{
int i,j,chess[8][8] = {[0 ... 7][0 ... 7] = 0};
if(EQueen(chess,0)==1)
{
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
printf("%d ",chess[i][j]);
printf("\n");
}
}
return 0;
}//close main
Your code is good in principle. You just have to take care to use the same indexing for rows and cols throughout. The way you print the board, you use chess[row][col].
Choose a consistent nomenclature of x, i, c and so on, and you will see that you got your indexing wrong when you check the board. Change the call to IsSafe to
if (isSafe(c, q, a) == 1) ...
and it will work.
(By the way, the array is passed by reference, thus reflecting the changes you make. No problem here.)
I believe it is because your c variable is not incrementing. This is due to how you recursively call your EQueen function.
if(q==8)
return 1;
When your q variable is equal to 8, that specific call for that function call of EQueen will return 1. After that, all the preceding function calls of EQueen will then be true for the if statement because they will all backtrack and return the value 1 and exit that instance of the function call.
if(EQueen(a,q+1)==1)
return 1;
else ...
This makes it so your isSafe function only looks at the 0th row (c = 0) because your c variable does not increment to check all spaces within the 2x2 dimensional array due to EQueen exiting the function before it can loop.
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;
}