goto statement leading to an infinite loop - c

We were having a quiz of sorts and had the following question where we had to find the error, or if there's none, the output of the given code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
I don't see anything wrong with this in theory but this leads to an infinite loop with the variable going way below 0. Could anyone help me with this?

#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n);
if(n!=0){
n--;
goto b;
}
return 0;
}
This would work. The version you posted does not work because it will never get to 0. It is subtracting once in the if statement, and once in the printf.

You should only have one n-- statement. otherwise even if it reaches 0, when it get the first n-- it will be decremented one more time and will become -1. (so it will never match 0).
Hence, please change your code to
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
goto b;
}
return 0;
}

The condition if (n != 0) is always getting satisfied.
On each iteration the number n decreases by 2.
So when n = 2, it gets decremented once after printf("%d\n",n--)
then the condition if (n != 0) is true, as n = 1
Inside the condition block n is decremented once again, n = 0
So the next time before reaching the condition if (n != 0), n equals to -1,
which leads to an infinite loop.

In C 012 is an octal base number, in decimal it is equal to 10.
This code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
Does this:
print n (10)
subtract 1 of n (n = 10 - 1 = 9)
check if n != 0 (9 != 0 -> true)
subtract 1 of n (n = 9 - 1 = 8)
jump to b
print n (8)
subtract 1 of n (n = 8 - 1 = 7)
check if n != 0 (7 != 0 -> true)
subtract 1 of n (n = 7 - 1 = 6)
jump to b
print n (6)
subtract 1 of n (n = 6 - 1 = 5)
check if n != 0 (5 != 0 -> true)
subtract 1 of n (n = 5 - 1 = 4)
jump to b
print n (4)
subtract 1 of n (n = 4 - 1 = 3)
check if n != 0 (3 != 0 -> true)
subtract 1 of n (n = 3 - 1 = 2)
jump to b
print n (2)
subtract 1 of n (n = 2 - 1 = 1)
check if n != 0 (1 != 0 -> true)
subtract 1 of n (n = 1 - 1 = 0)
jump to b
print n (0)
subtract 1 of n (n = 0 - 1 = -1)
check if n != 0 (-1 != 0 -> true)
subtract 1 of n (n = -1 - 1 = -2)
jump to b
print n (-2)
...
...
... goes on infinitely
Note that when n will never equal to 0 when the program checks if n != 0, because in this evaluation n is always an odd number since two subtractions by 1 are made every time.

Change from b: printf("%d\n",n--); to b: printf("%d\n",n);.
or
Change from
if(n!=0){
n--;
goto b;
to
if(n!=0){
n;
goto b;
Because n-- equals n = n - 1.
Your program:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--); // n = n - 1
if(n!=0){
n--; // n = n - 1
goto b;
}
return 0;
}

for out put [10, 8, 6, 4,2, 0]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
n--;
goto b;
}
return 0;
}
for [10,9,8,7,6,5,4,3,2,1]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
//n--;
goto b;
}
return 0;
}

Related

Storing the right value in a two dimensional array in c. But when I tried to print the value it shows bigger value and even negative number

Problem:
In this question I tried to solve a bitwise operator problem. Giving two number as input
Input will be two number. Here is some input:
n = 3
k = 3
Then I need to construct "a" and "b" in some way(for instance when "a = 1" then b will be one past a to <= n. The results of the comparisons are below:
a b and or xor
1 2 0 3 3
1 3 1 3 2
2 3 2 3 1
Here is my code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
//Complete the following function.
void calculate_the_maximum(int n, int k)
{
// Two dimentional array for storing the value of and or xor
int rowOfArray = 3;
int sets[rowOfArray][k];
//For loop for a
for (int i = 0; i < k; i++)
{
int a = i + 1;
//For loop for b
for (int j = a; j < n; j++)
{
int b = j;
b++;
printf("{%i, %i}\n", a, b);
//Storing and operation result to the array
sets[0][j - 1] = a&b;
printf("And: %i\n", sets[0][j - 1]);
//Storing or operation result to the array
sets[1][j] = a|b;
printf("Or: %i\n", sets[1][j]);
//Storing xor opertaion result to the array
sets[2][j + 1] = a^b;
printf("Xor: %i\n", sets[2][j + 1]);
}
}
//Find the biggest number in array
for (int i = 0; i < rowOfArray; i++)
{
int big;
for (int j = 0; j < k; j++)
{
big = 0;
printf("Big1: %i\n", big);
if (big < sets[i][j])
{
big = sets[i][j];
printf("Big2: %i\n", big);
}
}
printf("big3: %i\n", big);
if (big < k)
{
printf("%i\n", big);
}
else
{
printf("%i\n", 0);
}
}
}
int main() {
int n, k;
scanf("%d %d", &n, &k);
calculate_the_maximum(n, k);
return 0;
}
I used too many printf function to show that what have I done wrong. I stored the value as I expected but later in the for loop when I tried to print the specific position integer I didn't get the correct result even sometimes I got bigger and negative number too.
Here is the output:
3 3
{1, 2}
And: 0
Or: 3
Xor: 3
{1, 3}
And: 1
Or: 3
Xor: 2
{2, 3}
And: 2
Or: 3
Xor: 1
Big1: 0
Big1: 0
Big2: 2
Big1: 0
Big2: 120329728
big3: 120329728
0
Big1: 0
Big2: 1986993953
Big1: 0
Big2: 3
Big1: 0
Big2: 3
big3: 3
0
Big1: 0
Big1: 0
Big2: 32765
Big1: 0
Big2: 3
big3: 3
0
As is, for the input 3 3, j holds the values 1, 2, and 2, so clearly sets[2][j + 1] is Undefined Behaviour since it accesses the subarray at index 3, when valid indices are [0, 2].
Given the source problem, the issues are more clear.
k is simply a limit on output, and should not be used as a bound for iteration, or for calculating the storage required for the number of k-combinations.
It is unnecessary to store all the results at once. For each combination, each value of the operation a ? b (where ? is a bitwise operator) can be tested against the value k and the currently stored maximum value for the given operator.
Here is a quick solution. Compile with -DDEBUG to see additional output.
#include <stdio.h>
void setmax(int *dest, int value, int limit)
{
if (value < limit && value > *dest)
*dest = value;
}
void calc(int n, int k)
{
int and = 0;
int or = 0;
int xor = 0;
#ifdef DEBUG
printf("INFO: a b and or xor\n");
#endif
for (int a = 1; a < n; a++) {
for (int b = a + 1; b <= n; b++) {
setmax(&and, a & b, k);
setmax(&or, a | b, k);
setmax(&xor, a ^ b, k);
#ifdef DEBUG
printf("INFO: %-3d %-3d %-3d %-3d %-3d\n",
a, b, a & b, a | b, a ^ b);
#endif
}
}
printf("%d\n%d\n%d\n", and, or, xor);
}
int main(void)
{
int n, k;
if (2 != scanf("%d%d", &n, &k))
return 1;
calc(n, k);
}
Sample runs:
./a.out <<< "3 3"
2
0
2
./a.out <<< "5 4"
2
3
3
If you run the code, you'll get stack corruption error which is due to indexing the array beyond its allocated size. Accessing memory that's not for your program is undefined behavior. Anything might happen. The program may crash or it may not. For my specific compiler and the fact that I ran the code in debug mode and not release mode, the program crashed with the error I mentioned.
Now to fix the error, from what you explained, you have three columns for and, or and xor. So you need to reverse the dimensions of set (set[k][rowOfArray], better change the name to rowSize or n_columns or so). Also reverse the indexing, e.g. change set[0][j-1] to set[j-1][0] and so on. I'm not sure what you're trying to do in the second part, though.

Counting the number of elements of blocks with same consecutive elements

I'm having the following problem:
A park that have the form of a m x n board. There are k kinds of trees (1 <= k <= 100). The park is divided into m x n cells and each cell, they'll plant a tree. Now, on the map, each cell of the park have an integer i inside if the i-th kind of tree is planted in it, or a 0 if no tree is planted in it. A line of cells is considered "good" if it has at least t trees of same types, (and they must be on the same either line or column). Count the number of trees that is not in a "good" line.
Input: Integers m, n, t and an m x n array of integers represent the map.
Output: Number of trees that is not in a "good" line.
Example:
Input:
5 6 3
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
Output: 10
Explanation: The bold numbers are the trees that is not in a good line.
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
My idea is to check for each element in the array. If it is satisfied then I'll move to the nearest element outside the "good" line. Else, it will just move to the next element on the same line, or if the line is ended then the next element on the column.
Here is my code
#include <stdio.h>
#define maxn 120
int a[maxn][maxn], m, n, t;
int check(int *i, int *j){
int k, cnt_r, cnt_c;
cnt_r = 0;
//jump to the nearest cell that is not in good line
for(k = *i + 1; k < m; k++){
if(a[*i][*j] == a[k][*j]) cnt_r++;
if(cnt_r >= t){
*i = k;
return 1;
}
}
cnt_c = 0;
for(k = *j + 1; k < n; k++){
if(a[*i][*j] == a[*i][k]) cnt_c++;
if(cnt_c >= t){
*j = k;
return 1;
}
}
return 0;
}
//check if this is the last square or not
int lastSq(int r, int c){
return (r == n - 1 && c == n);
}
int main(){
int res = 0, i, j, pos_r = 0, pos_c = 0;
scanf("%d%d%d", &m, &n, &t);
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
scanf("%d", &a[i][j]);
while(!lastSq(pos_r, pos_c)){
if(a[pos_r][pos_c] == 0){
if(pos_c < n - 1) pos_c++;
else if(pos_r < n - 1){
pos_c = 0;
pos_r++;
}
}
if(!check(&pos_r, &pos_c)){
res++;
if(pos_c < n - 1) pos_c++;
else{
pos_c = 0;
pos_r++;
}
}
}
printf("%d", res);
}
But it doesn't print any output. The only thing I have is 0xC0000005. Can someone please check where did I make a mistake and provide me a direction? Thanks.

Project Euler 2# - strange output

I've tried to solve problem 2 on Project Euler in C. This is the first possible solution that came to my mind, and, in fact, it gives as an output the right answer. The problem is that each time I run my program it gives me a different output, which is either "2" or "4613732" that is the right answer. Sorry for my poor english, can you help me find out what's wrong?
#include <stdio.h>
int main(){
int n, n1 = 1, n2 = 2, sum = 2;
while(n<4000000){
n = n1 + n2; /*calculate the next number of the series*/
n1 = n2;
n2 = n;
if(n%2 == 0){
sum = sum + n; /*if the number it's even add it to the main sum*/
}
}
printf("The sum is %d\n", sum);
}
You didn't initialize n; when you get the right answer, it means you got lucky.
#include <conio.h>
#include <iostream>
using namespace std;
int evenFibSum(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int sum = 0;
while (sum < max)
{
sum = i + j;
i = j;
j = sum;
if (sum % 2 == 0)
eventsum +=sum;
}
return eventsum;
}
For more efficient solution apply following logic
Fibbonaci Series => 1 2 3 5 8 13 21 34 55 89 144
Index => 0 1 2 3 4 5 6 7 8 9 10
To get even fibbonanci addition I have to add following index values[1 4 7 10]
Here I am sensing some pattern
[1 4 7 10] => I need advance index by 3
so how to advance index by 3
// k = i+j = > 3 13 55
// i = k+j => 5 21 89
// j = k+i => 8 34 144
int evenFibSumx(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int k= 0;
while (1)
{
k = i + j;
i = k + j;
j = k + i;
if(i >= max)
break;
if (j%2 == 0)
eventsum +=j;
}
return eventsum;
}
int main()
{
std::cout << evenFibSum();
std::cout << evenFibSumx();
}

Serial numbers of equal numbers next to each other in array

#include <stdio.h>
void main(){
int i, j, n;
int num[5];
int serial;
for(i=0; i<5; ++i){
scanf("%d",&num[i]);
if(num[i]==num[i-1])
serial=i;
else
continue;
}
printf("Serial number of equal numbers next to each other:%d. %d.", serial-1, serial);
}
This may be hard to understand because I'm not a native English speaker.
If the numbers next to each other are equal the program should print the serial number of those numbers.
For example:
Input: 1 2 3 7 7 7 6;
Output: 3. 4. 5.
Input: 5 5 5 5 5
Output: 0. 1. 2. 3. 4.
I made some changes now it prints the serial of two equal numbers.
I: 1 2 2 3 4 - O: 1. 2.
But what if all the numbers are equal?
// ...
// deal with index 0
if (num[0] == num[1]) printf("0. ");
// deal with indexes 1 .. N - 2
for (int k = 1; k < n - 1; k++) {
if ((num[k - 1] == num[k]) || (num[k] == num[k + 1])) {
printf("%d. ", k);
}
}
// deal with index N - 1
if (num[n - 2] == num[n - 1]) printf("%d. ", n - 1);
// ... possibly with a printf("\n"); somewhere
You can solve this without storing the numers in an array, but you must keep track of how many equal numbers have been read before reading the present one:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i = 0; // running index
int prev = 0; // previously read number
int iprev = 0; // start of range of equal numbers previously read
int n; // currently read number
while (scanf("%d", &n) == 1) {
if (n != prev) {
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
iprev = i;
prev = n;
}
i++;
}
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
return 0;
}
You consider stretches of equal numbers only after you read a number that terminates the current range of equal numbers. When all numbers are different, the size of that range is 1 and we don't print anything. If the range is larger than 1, print all indices in question.
Because you don't notice a change after reading the last number, you must check the last range separately after the main loop.
If you can put a non-numeric character in the [0] element of your array, you won't need a different test for the first element
int main (void)
{
/* non-numeric in position 0 of data array */
char myList[] = {'.','1','2','2','3','4','4','4','5','6','6'};
int listSz = strlen(myList) -1;
int n;
/* check everything except last */
for (n = 1; n < listSz; n++) {
if(( myList[n] == myList[n +1]) || ( myList[n] == myList[n -1] )) {
printf("%d . ", n);
}
}
/* check last */
if( myList[listSz] == myList[listSz -1] ) {
printf("%d", n);
}
printf("\n");
}
Output: 2 . 3 . 5 . 6 . 7 . 9 . 10

Perplexing Output of C language program using Turbo C++ 3.0 compiler

Concerning my determination for output.It's 1 40 1 While using C it displays output as 0 41 1 How's that possible?What wrong step I'm going into?
#include<stdio.h>
#include<conio.h>
void main(void)
{
clrscr();
int n,a,b;
n = 400;
a = n % 100; //remainder operation
b = n / 10; //division operation
n = n % 10; //remainder operation
printf("%d %d %d",n++,++b,++a); //post-,pre-,pre- increment used
getch();
}
What your compiler prints is correct. Here is the program flow:
#include<stdio.h>
#include<conio.h>
void main(void)
{
clrscr();
int n,a,b;
n = 400; // n has value 400
a = n % 100; // a has value 0
b = n / 10; // b has value 40
n = n % 10; // n has value 0
// n++ evaluates to 0, afterwards n has the value 1
// ++b evaluates to 41, afterwards b has the value 41
// ++a evaluates to 1, afterwards a has the value 1
printf("%d %d %d",n++,++b,++a);
// Thus, 0 41 1 is printed.
getch();
}
Notice especially that the postfix-incrememnt operator n++ returns the value of n unchanged and then changes n. That's why 0 is printed in the first column.

Resources