Why does this generate an infinite loop (C, While Loop) - c

I am doing a program for my class, and I need to set all the values of the array 'decade' into -1 before I begin. I tried this (And the version in a for loop) and it just puts me in an infinite loop! Can someone explain why this is happening, and how I can fix it?
Code:
int decade[9][9], i = 0, k = 0;
while (i<10) {
while (k<10) {
printf("i is %d, k is %d\n",i,k);
decade[i][k] = -1;
k++;
}
k=0;
i++;
}
Thanks in advanced!
It prints out this:
For anyone who needs the answer in the future, declare decade as 'decade[10][10]' instead of 'decade[9][9]', or however yours is defined.

When you declare an array of size 9 it has the indexes from 0 to 8. You go to 9 which will overwrite the memory. This is undefined behavior and can cause any number of subtle but faulty behavior.

I don't know how "decade" is defined - but if it is defined incorrectly, and/or the wrong size you could get a buffer overrun which could result in the wrong memory getting set to "-1" - i.e. the "i" or "k" variables could be getting overwritten.

int decade[9][9], i = 0, k = 0;
while (i<10) {
while (k<10) {
printf("i is %d, k is %d\n",i,k);
decade[i][k] = -1;
k++;
}
k=0;
i++;
}
is incorrect, because you are iterationg from 0 to 9 (10 elements)
this code is correct:
int decade[9][9], i = 0, k = 0;
while (i<9) {
k = 0;
while (k<9) {
printf("i is %d, k is %d\n",i,k);
decade[i][k] = -1;
k++;
}
i++;
}
note that you set k to zero before looping again.
There exists also other possibilities to loop for example the for loop, you use while loops actually not for counting.

You loops must be from 0 to 8 (decade array is length 9):
while (i<9) {
while (k<9) {
/* ... */
}
}

The dimension in "9x9" - you are initialzing 10x10. Set it to decade[10][10], use (x<8) or do (x<=9)

Index out of bound exception for your code. Try this one instead.
int dimSize = 10;
int decade[dimSize][dimSize], i = 0, k = 0;
while (i<dimSize) {
while (k<dimSize) {
printf("i is %d, k is %d\n",i,k);
decade[i][k] = -1;
k++;
}
k=0;
i++;
}

Related

How to keep while loop in bubble sort function in C

I'm trying to make my own bubble-sort function in C.
As you can see in the code below this, I'm trying to only using while / if loop to create this function. I put 5 numbers (1,3,2,5,4) so that size of array of this would be 5, and I got 5 (I checked it with Python(C)tutor. However, It works well until tab[j] gets 3. I'm trying to figure it out, but couldn't figure it out why it keeps going out when tab[j] gets 3.
Could you anybody explain what's wrong to me? I would appreciate it.
Here is my code below:
#include <stdio.h>
void ft_sort_integer_table(int *tab, int size)
{
int i;
int j;
int tem;
i = 0;
j = 0;
while(tab[i] < size)
{
if(tab[j] > tab[j+1])
{
tem = tab[j];
tab[j] = tab[j+1];
tab[j+1] = tem;
printf("%d ", tab[j]);
j++;
}
else if(tab[j] < tab[j+1])
{
printf("%d ",tab[j]);
j++;
}
i++;
}
}
int main(void)
{
int tab[] = {1,3,2,5,4};
int size = sizeof(tab)/sizeof(*tab);
ft_sort_integer_table(tab, size);
return(0);
}
You'll need an inner loop in your bubble sort, which is responsible for moving the largest element to the back and performing swaps i times (these large elements are "bubbling up"). Start the inner loop at 0 on each iteration and iterate through size - i (we know that the last i elements are sorted and in their final positions).
i controls your outer loop and should be incremented at the end of the loop (just as you would with a for loop). j controls the inner loop and should be incremented at the end of the loop.
While you're at it, it's a good idea to move your printing out of the sort function, which causes an unnecessary side effect and might frustrate your debugging efforts.
Also, it's worth mentioning that (1) for loops are more semantically appropriate here and (2) there is an optimization available by adding a boolean--as soon as you have a pass through the inner loop that performs no swaps, end early!
#include <stdio.h>
void ft_sort_integer_table(int *tab, int size)
{
int i = 0, j, tem;
while (i < size)
{
j = 0;
while (j < size - i)
{
if (tab[j] > tab[j+1])
{
tem = tab[j];
tab[j] = tab[j+1];
tab[j+1] = tem;
}
j++;
}
i++;
}
}
int main(void)
{
int tab[] = {1,3,2,5,4,6,7,1,5,6,8,9,1,4,5,1,2};
int size = sizeof(tab) / sizeof(*tab);
ft_sort_integer_table(tab, size);
for (int i = 0; i < size; i++)
{
printf("%d ", tab[i]);
}
return(0);
}
Output:
1 1 1 1 2 2 3 4 4 5 5 5 6 6 7 8 9
I'm trying to figure it out, but couldn't figure it out why it keeps
going out when tab[j] get 3.
From your code above, j increment in the same fashion as i. That means both variables will have the same value since j will be incremented by one after the if-then-else statement, and i will also be incremented by one at the end of each loop. Therefore, tab[j] is referencing the same value as tab[i]
With that being said, the boolean condition in the while loop checks whether the value in the tab[i] is less than the value of size.
When i == 3, tab[i] == 5 since in the loop, only the values in the array of index less then i are swapped/changed. Since the size variable holds that value of 5, tab[i] < size will result in a false value and exit the loop.
More information on bubble sort can be found here, https://www.geeksforgeeks.org/bubble-sort/

Program to find if a number is perfect

I'm having trouble trying to run this program that I made to find if a number if perfect. It gives me a segmentation error. What does that mean? Can you help me to understand what I did wrong? Here's my code:
#include <stdio.h>
void perfect(int number);
int main() {
int n;
printf("Insert a number greater than 0: ");
scanf("%d", &n);
perfect(n);
return 0;
}
void perfect(int number) {
int i, j, array[100], k = 0, tmp = 0, tmp2 = number;
for (i = 2; i <= 1000; i++) {
for (j = 2; j <= 1000; j++) {
if (i % j == 0) {
array[k] = i;
k++;
}
}
}
k = 0;
while (tmp2 != 1) {
if (tmp2 % array[k] == 0) {
tmp += array[k];
tmp2 /= array[k];
}
k++;
}
tmp++;
if (tmp == tmp2) {
printf("It's a perfect number\n");
}
}
The segmentation fault tells you that you are trying to access memory outside the bounds of what you are allowed. Your array is nowhere near big enough for what your program does.
You need to reconsider what you are storing in array. All numbers up to a thousand that are divisible by other numbers, right? But actually it's going to be
all of them and
all the even ones and
all of them that are divisible by 3 and
all of them that are divisible by 4 etc.
That sounds like a lot more than 100 doesn't it? There will also be many, many repeats which I doubt you intend. For example, you will store 6 three times as it is divisible by 2, 3 and itself. (So, by the way, you should stop looking once j is greater than i.)
Your while loop is also peculiar. It terminates when tmp2 is 1. How is tmp ever going to be equal to 1?
Back to the drawing board, I'm afraid!
Given the loop index maximum value 1000, the array array should be defined with a size of at least 1001. With a size of 100, you likely have a buffer overflow causing undefined behavior.

Issue with C program (maybe solved with use of arrays)

I have written the following code. But it doesn't run until the final printf. Plus if the validation I have set fails to pass, it prints a result I can't explain.
#include <stdio.h>
int main(void)
{
int k, j, z, i, n;
int l[30];
// Setting initial values 0 (0=off 1=on)
for (n=0; n<30; n++)
{
l[n] = 0;
}
// Employee number
printf("give employee number\n");
scanf("%d", &k);
// Validation of k
if (k<0 || k>30)
{
printf("wrong input");
}
else
// Lamp status change
for (i=1; i=k; i=i+1)
{
for (z=i; z=30; z=2*z)
{
if (l[z] = 0)
l[z] = 1;
else
l[z] = 0;
}
}
for (j=0; j<30; j++);
{
printf("lamp[%d] is: %d\n", j+1, l[j]);
}
return(0);
}
I suggest that you go work a little more your C basis...
First advice: As reported by halfer you should take care of your indentation code, it allows you (and us) to read it more easily.
First error, also pointed out by halfer: You probably forgot to declare a
block of code with {}, tips for your research to know when to put
it here.
Second error: You should take a look at the for loop syntax: for (j=0; j<30; j++);will basically do nothing due to ;at the end.
You confuse assignment and condition test, if (l[z]=0), for (i=1; i=k; i=i+1) and for (z=i; z=30; z=2*z) haven't condition test, but assignment (just = and not == or <=, etc.) so they are always true...
Also, you don't explain what you want your code to do... It seems like you want to turn on some lights, but the double statement loop with the wrong for is confusing. I don't know if you want to turn on 2^N bulbs or just the one selected by the user... Here is my correction of your code:
int main(void) {
int k, j, z, i, n;
int l[30];
// Setting initial values 0 (0=off 1=on)
for (n=0; n<30; n++) {
l[n] = 0;
}
// Employee number
printf("give employee number\n");
scanf("%d", &k);
// Validation of k
if (k<0 || k>30) {
printf("wrong input");
} else { // New block
// Lamp status change
/*
i = k is an assignment not a test, maybe i == k ?
but still false, for do while the condition is true
so use <= and why use i = i+1 here and not i++ like for n++ L6 ?
Ok for this loop, but with the other you gonna reswitch again and
again. If you want only switch the one selected, consider to use
an if instead of the 2nd for loop.
*/
for (i=1; i <= k; i=i+1) {
/*
Same test / assignment misunderstanding.
personally except 15, I don't know a lot of intergers
mutiplied by 2 that give 30. Example: if I set 1 in
my keyboard, k = 1, then i = 1, z = 1, z = 2,z = 4,
z = 8,z = 16, z = 32, z = 64, etc. to overflow.
So z = 30 (ouch z == 30) is never true.
If you tried to switch only the lamp selected by the user
I don't see the point of the second for loop.
But if you wanted to switch 1 light each 2^N bulbs you
should set z <= 30.
*/
for (z=i; z<=30; z=2*z) {
if (l[z] == 0) // = is an assignment, == instead?
l[z] = 1; // A block with {} is not needed here because there is only 1 instruction
else
l[z] = 0; // Same as above, {} are not needed here too
}
}
for (j=0; j<30; j++) { // No; here, see the 'for' loop syntax
printf("lamp[%d] is: %d\n", j+1, l[j]);
}
} // End of the else block
return(0);
}

Nested for loops in C

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

missing numbers

Given an array of size n. It contains numbers in the range 1 to n. Each number is present at
least once except for 2 numbers. Find the missing numbers.
eg. an array of size 5
elements are suppose 3,1,4,4,3
one approach is
static int k;
for(i=1;i<=n;i++)
{
for(j=0;j<n;j++)
{
if(i==a[j])
break;
}
if(j==n)
{
k++;
printf("missing element is", a[j]);
}
if(k==2)
break;}
another solution can be..
for(i=0;i
Let me First explain the concept:
You know that sum of natural numbers 1....n is
(n*(n+1))/2.Also you know the sum of square of sum of first n natural numbers 1,2....n is n*(n+1)*(2n+1)/6.Thus you could solve the above problem in O(n) time using above concept.
Also if space complexity is not of much consideration you could use count based approach which requires O(n) time and space complexity.
For more detailed solution visit Find the two repeating elements in a given array
I like the "use array elements as indexes" method from Algorithmist's link.
Method 5 (Use array elements as index)
Thanks to Manish K. Aasawat for suggesting this method.
traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
make it negative by A[abs(A[i])]=-A[abs(A[i])];
else // i.e., A[abs(A[i])] is negative
this element (ith element of list) is a repetition
}
The only difference is that here it would be traversing 1 to n.
Notice that this is a single-pass solution that uses no extra space (besides storing i)!
Footnote:
Technically it "steals" some extra space -- essentially it is the counter array solution, but instead of allocating its own array of ints, it uses the sign bits of the original array as counters.
Use qsort() to sort the array, then loop over it once to find the missing values. Average O(n*log(n)) time because of the sort, and minimal constant additional storage.
I haven't checked or run this code, but you should get the idea.
int print_missing(int *arr, size_t length) {
int *new_arr = calloc(sizeof(int) * length);
int i;
for(i = 0; i < length; i++) {
new_arr[arr[i]] = 1;
}
for(i = 0; i < length; i++) {
if(!new_arr[i]) {
printf("Number %i is missing\n", i);
}
}
free(new_arr);
return 0;
}
Runtime should be O(2n). Correct me if I'm wrong.
It is unclear why the naive approach (you could use a bitfield or an array) of marking the items you have seen isn't just fine. O(2n) CPU, O(n/8) storage.
If you are free to choose the language, then use python's sets.
numbers = [3,1,4,4,3]
print set (range (1 , len (numbers) + 1) ) - set (numbers)
Yields the output
set([2, 5])
Here you go. C# solution:
static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
HashSet<int> values = new HashSet<int>( numbers ) ;
for( int value = 1 ; value <= numbers.Length ; ++value )
{
if ( !values.Contains(value) ) yield return value ;
}
}
I see a number of problems with your code. First off, j==n will never happen, and that doesn't give us the missing number. You should also initialize k to 0 before you attempt to increment it. I wrote an algorithm similar to yours, but it works correctly. However, it is not any faster than you expected yours to be:
int k = 0;
int n = 5;
bool found = false;
int a[] = { 3, 1, 4, 4, 3 };
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < n; j++)
{
if(a[j] == i)
{
found = true;
break;
}
}
if(!found)
{
printf("missing element is %d\n", i);
k++;
if(k==2)
break;
}
else
found = false;
}
H2H
using a support array you can archeive O(n)
int support[n];
// this loop here fills the support array with the
// number of a[i]'s occurences
for(int i = 0; i < n; i++)
support[a[i]] += 1;
// now look which are missing (or duplicates, or whatever)
for(int i = 0; i < n; i++)
if(support[i] == 0) printf("%d is missing", i);
**
for(i=0; i < n;i++)
{
while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{
swap(a[i],a[a[i]-1]);
}
for(i=0;i< n;i++)
{
if(a[i]!=i+1)
printf("%d is missing",i+1); }
this takes o(n) time and o(1) space
========================================**
We can use the following code to find duplicate and missing values:
int size = 8;
int arr[] = {1, 2, 3, 5, 1, 3};
int result[] = new int[size];
for(int i =0; i < arr.length; i++)
{
if(result[arr[i]-1] == 1)
{
System.out.println("repeating: " + (arr[i]));
}
result[arr[i]-1]++;
}
for(int i =0; i < result.length; i++)
{
if(result[i] == 0)
{
System.out.println("missing: " + (i+1));
}
}
This is an interview question: Missing Numbers.
condition 1 : The array must not contain any duplicates.
The complete solution is :
public class Solution5 {
public static void main(String[] args) {
int a[] = { 1,8,6,7,10};
Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
int ch = a[i];
if(start == ch) {
start++;
}else {
list.add(start);
start++;
//must do this
i--;
}
}//for
System.out.println(list);
}//main
}

Resources