for loop: make increment and accessing in one loop - c

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]);
}
}

Related

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.
.

this code work with N=348 but dont work when N = 349

why dose this sorting code work with N=348 but when N=349 program hang.?there is not compilation error.
#define N 348
int main(void){
int n[N];
int temp;
for(int i=0;i<N;i++) n[i] = rand();
for(int i=0 ; i<N-1;){
if (n[i]<n[i+1]) {i++;continue;}
else {
temp = n[i];
n[i] = n[i+1];
n[i+1] = temp;
if (i != 0) i--;
else i++;
}
}
return 0;
}
The behavior of the program does not depend on the value of N.
In case when two consecutive elements of the array are equal each other there will be infinite loop due to this condition
if (n[i]<n[i+1]) {i++;continue;}
else {
and this statement inside the compound else statement
if (i != 0) i--;
That is the else statement will be always executed when n[i] is equal to n[i+1].
For example try to run the program for the array
#define N 3
//...
int n[N] = { 1, 2, 2 };
You can avoid the error by changing the condition to
if (n[i]<=n[i+1]) {i++;continue;}
else {

Unpredictable result in counting pairs of integers

The task of the program is to count how many times there are two consecutive integers their value exceeds 40. So, the problem here is that the result of the program is way wrong.
To solve this problem, I tried το change some initial values and investigating the mechanism of the code, but I didn't notice any mistakes. The code is below.
#include <stdio.h>
int main() {
int a,i,e=0;
int A[31];
for(i=0; i<=30; i++) {
scanf("%d",&a);
A[i]=a;
}
if (A[i]>40 && A[i+1]>40) {
e=e+1;
}
printf("%d",e);
return 0;
}
The expected result if we enter the integer 41 in all of 31 places of the matrix, the result should be 30, while the result there is always zero (0)
Thank you in advance for your help.
"if statement" must be in loop.
And, Please aware the condition of 2nd loop what I set it as '< 30' instead of '<= 30' because your program want to compare the next variable together as "if (A[i] > 40 && A[i + 1] > 40)".
#include <stdio.h>
int main()
{
int a, i, e = 0;
int A[31];
for (i = 0; i <= 30; i++) {
scanf("%d", &a);
A[i] = a;
}
for (i = 0; i < 30; i++){
if (A[i] > 40 && A[i + 1] > 40)
e = e + 1;
}
printf("%d", e);
return 0;
}

IF statement overriding FOR loop in C

I'm have trouble with a for loop. Basically, I get the output that I want, but for the wrong reason. This program prints out
xoxoxoxo
oxoxoxox
xoxoxoxo
oxoxoxox
xoxoxoxo
oxoxoxox
xoxoxoxo
oxoxoxox
The problem is the order in which this is produced. I'm required to have the inner loop iterate 8 times for every outer loop (also iterating 8 times), which isn't happening.
The compiler keeps returning to the if statement instead after printing, instead of returning to check the inner for loop (j).
#include <stdio.h>
int main() {
int i;
int j = 0;
for (i = 1; i < 9; i++) {
for (j = 1; j < i + 4 && j < 5; j++) {
if (i % 2 == 0) {
printf("o");
printf("x");
}
else {
printf("x");
printf("o");
}
}
printf("\n");
}
getchar();
return 0;
}
I assume you misinterpret the behavior of your debugger, and the code actually does exactly what it is supposed to do. Why your debugger does not jump to the head of the for loop but instead immediately to the if again, I cannot say. But they are all different about these things :)

printing randome choices from an array

I am working on a function that picks random numbers from a given array and prints them to stdout. These numbers should not repeat and how many numbers are picked is given to the function along with the array. I have a separate test file for the function and a header file as well. Everything compiles fine but when I run the program I get a hang up in the pickNumbers function, nothing is printed and I don't even know if anything is being chosen to begin with.
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
//program that picks random numbers from the given array
int alreadyPicked(int choices[], int choice);
void pickNumbers(int myArray[],int max)
{
// delcare/initilize variables
int i;
int choices[max];
int length = sizeof(myArray)/sizeof(myArray[0]);
// seed rand
srand(time(NULL));
// pick a random choice until that given number of choices is reached
// to make sure non repeat run against alreadyPicked function
for (i=0; i <= max; i++) {
do{
choices[i] = (rand() % max);
}while (alreadyPicked(choices, choices[i]) == TRUE);
}
for (i=0; i <= max; i++) {
printf("%d", myArray[choices[i]]);
}
printf("\n");
}
int alreadyPicked(int choices[], int choice)
{
int i;
int answer = FALSE;
for (i=0; i <= (sizeof(choices)/sizeof(choices[0])); i++) {
if(choices[i] == choice)
answer = TRUE;
}
return answer;
}
Perhaps
for (i=0; i <= max; i++) {
must be:
for (i=0; i < max; i++) {
and
for (i=0; i <= (sizeof(choices)/sizeof(choices[0])); i++) {
must be:
for (i=0; i < (sizeof(choices)/sizeof(choices[0])); i++) {
In your first "for" loop you have a nested while/do. You increment "i" in your for loop, instead you should increment the variable inside of while/do, otherwise it will hang forever performing such loop because "i" is never incremented.
Replace:
for (i=0; i <= max; i++) {
by:
for (i=0; i < max;) {
And also replace:
choices[i] = (rand() % max);
By:
choices[i++] = (rand() % max);
This way you make sure "i" is being incremented. Also your construction "i<=max" is incorrect since you start from 0, use the way David RF did.
Apart from the aforementioned wrong loop tests, the reason for the endless loop is that in alreadyPicked() you compare the new choice index with every choice index in choices[], including uninitialized ones and the new one itself; thus, alreadyPicked() always returns TRUE. I suggest to change to call of alreadyPicked() to
alreadyPicked(choices, i)
and its implementation to
int alreadyPicked(int choices[], int choice)
{
for (int i = 0; i < choice; i++)
if (choices[i] == choices[choice])
return TRUE;
return FALSE;
}

Resources