I wrote the following program to display all prime numbers up to 150. It is not executing at all. what is so wrong with it?
# include <stdio.h>
int main(void)
{
int p[150], i, j;
for (i = 2; i < 150; i++)
p[i] = 0;
i = 2;
while (i < 150){
if (p[i] == 0)
printf("%i ", i);
for (j = 1; i*j <= 150; j++)
p[i*j] = 1;
i++;
}
return 0;
}
You're accessing p[i*j], which is beyond the valid [0-149] range. The condition i*j <= 150 will evaluate true when i*j is equal to 150, which is off-by-one. It should be i*j < 150.
The stdout stream is buffered. You need to flush at the end of your loop. Try adding a fflush(stdout).
Might be of less importance, but if you care about the resulting array (e.g.: wants to use it later), the value of p[2] is erroneously set to 1. However, your program would still print 2, but that's because your loop prints numbers before changing the value of p[i*j]. Concluding, numbers get printed correctly, but the values in the array are not entirely correct.
i*j <= 150 is incorrect, it should be i*j < 150, because the p array has elements from 0 to 149. The program gets stuck in an infinite loop because of this.
EDIT: The rest of this answer was incorrect, so I've removed it.
As a learning exeercise, try adding some printf's to learn what your program does.
Also bear in mind that, as jweyrich says, that printf without \n in it will not output anything until (possibly) the program exits.
Related
I'm trying to replace the jth value of the function's input string to '0' whenever the ith value of alphabet is contained in the function's input.
I am expecting this for-loop to increment i whenever the alphabet[i] equals input x[j] but it gets stuck at i when it does. What is going on here??
P.S This is an introductory programming course (CS50) and it uses different syntax then standard C.
void checkrepeat(string x)
{
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
}
}
The output of function with value x = 'AAA' gives me
0,A,0AA
0,A,00A
0,A,000
I am expecting it to give me
0,A,0AA
1,B,0AA
2,C,0AA
This is my first post so pardon me if I am too verbose or not following any unsaid rules; I would be happy to include any suggestions as I contribute more.
I could be wrong but looks like "Your expected output pattern" and "your interpretation of assignment" are contradictory.
Let me explain why ?
1 - Expected Output for x='AAA'
I am expecting it to give me
0,A,0AA
1,B,0AA
2,C,0AA
2 - your interpretation of assignment
replace the 'j'th value of the function's input string to '0' whenever the 'i'th value of alphabet is contained in the function's input.
Here you are interpreting whenever as "update input string with '0' for **ALL** matches"
i.e. replace all A's with 0's.
If I follow interpretation [2] then output of your function code "as is" for x='AAA' would print like this
0,A,0AA
0,A,00A
0,A,000
i loop with j=1 will run but nothing is printed because there is no B in input string
i loop with j=2 will run but nothing is printed because there is no C in input string
and this will continue till Z
and the loop will end
BTW - I hope you can see the waste of CPU processing power in your solution.
If your interpretation [2] is correct then your expectation of output [1] is erroneous and vice versa.
ASSUMING interpretation [2] is correct then you need to change your code as below however the output would be different from expected output [1].
void checkrepeat(char x[])
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
}
}
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
And output of your modified function for x='AAA' would print like this
0,A,000
1,B,000
2,C,000
...
25,Z,000
As an example when x='ABCDZABCDZ' then the expected output would look like
0,A,0BCDZ0BCDZ
1,B,00CDZ00CDZ
2,C,000DZ000DZ
3,D,0000Z0000Z
4,E,0000Z0000Z
...
25,Z,0000000000
Open this link to see Working code in C
https://onlinegdb.com/rJhda-gMP
3 - your interpretation of assignment
I am expecting this for-loop to increment the 'i' whenever the alphabet[i] equals input x[j]
Here you are interpreting whenever as "as soon as first match is found update input string with '0' and increment 'i'"
ASSUMING interpretation [3] is correct, following code changes are needed to print your expected output [1]
void checkrepeat(char x[])
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
break;
}
}
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
If I follow interpretation [3] then it meets the expected output [1] and for x='AAA' your function would print like this which
0,A,0AA
1,B,0AA
2,C,0AA
...
25,Z,0AA
As an example when x='ABCDZABCDZ' then the expected output would look like
0,A,0BCDZABCDZ
1,B,00CDZABCDZ
2,C,000DZABCDZ
3,D,0000ZABCDZ
4,E,0000ZABCDZ
...
25,Z,00000ABCDZ
Open this link to see Working code in C
https://onlinegdb.com/rJhda-gMP
Hope it helps.
Firstly, printf("%c,", alphabet[i]);is an error. You probably didn't mean to use the , after %c. Remove it.
Second,Its easy to loose the logic in nested loops, especially as a beginner. Write it down on paper and run through it, If you haven't yet learn about debuggers.
Now,you probably do not want i to ++ when there is a match between alphabet[i]and x[j], because i is your loop counter, and should not be messed with like that (You have likely confused a for loop with a while loop or are coming from something like Scratch).
I would suggest declaring a separate variable, say int x for this task.
As already mentioned in the comments, you haven't actually implemented this incrementation to take place(with a simple x++; in the if statement), and have wrongly assumed that somehow the i++ in your for loop has done it for you .
Again, I'll suggest you to hit the books and go back to see the exact workings of a for loop , which is very frequently used in C , so you cannot afford to be fuzzy on its key concepts.
Also, you seem to expect the string x to remain 0AA ... If this is the case , why would the first statement in you if() be x[j] = '0'; ? This will make every jth element of x that matches with alphabets a '0'.
Further, in the expected output, you have expected alphabet[i] to be A , then B , then C, despite clearly stating in your question that you had passed x as "AAA" (which obviously cannot then match with B or C).
Maybe you haven't written the 'I expect' with clear forethough. Please do not include sample expected output if it is not possible with the code you have supplied in the question. It confused me, and could confuse anyone. I assume you drastically shortened the code for S.O. but supplied the expected output of the original code you have somewehere on your computer.
I'm trying to calculate the index of Fibonacci number with 1000 digits.
int i = 0, cnt = 2;
mpz_t limit;
mpz_init (limit);
mpz_ui_pow_ui(limit,10UL,999UL);
mpz_t fib[3];
for (i = 0; i < 3; i++)
mpz_init2(fib[i], 1024UL);
mpz_set_ui(fib[0],1UL);
mpz_set_ui(fib[2],1UL);
I think there's something wrong with assigning 1 to 1st and last element. I know that because those elements are not changing. But the loop should be valid till cnt becomes 4782.
The condition in while loop is only satisfied 2 times if.. <=0 or 3 times if .. >=0.
while(mpz_cmp(fib[i],limit)<=0) // should be <= only, not >=
{
i=(i+1)%3;
cnt++;
mpz_add(fib[i],fib[(i+1)%3],fib[(i+2)%3]);
}
for (i = 0; i < 3; i++)
mpz_clear(fib[i]);
mpz_clear(limit);
printf("Fibonacci number with more than 1000 digits: %d\n",cnt);
Please help find the logical error in this (it is compiling perfectly).
P.S. I don't want to use in-built mpz_fib_ui.
Integer Functions
After the for loop, i=3, so the conditional statement for the while loop depends on fib[3]
Adding i=0; before the while loop fixes it, and gives me the desired output:
Fibonacci number with more than 1000 digits: 4782
I have some problem with that. I am trying to learn C programming. Please help me
#include<stdio.h>
int main()
{
int a, factorial;
printf("Please enter a value :" );
scanf("%d", &a);
for (int i = 1; i<=a; i++)
{
a = (a - 1)*a;
}
printf("%d", factorial);
return 0;
}
Well in your code line a = (a - 1)*a; you actually changed your input for getting the factorial. It also will blow your loop. See your for loop will continue as long as your i is less than a, lets say you choose a=3 after first iteration the a itself will become 6, so the for loop will continue until it reach the integer limit and you will get overflow error.
What you should do?
First of all you should use a second variable to store the factorial result, you introduced it as factorial, the way that #danielku97 said is a good way to write a factorial since if you present 0 as input it will also give the correct result of 1. so a good code is:
factorial = 1;
for (int i = 1; i<=a; i++)
{
factorial *= i;
}
But lets say you insist of subtraction, the way you just tried to use, then you need to change the code like:
scanf("%d", &a);
if (a==1 || a==0){
printf("1");
return 0;
}
factorial = a;
for (int i = 1; i<a; i++)
{
factorial *= (a - i)*factorial;
}
You can see that the code just got unnecessarily longer. An if included to correct the results for 1 and 0. Also you need to make sure that i never become like i =a since in that case a-i will be equal to zero and will make the factorial result equal to zero.
I hope the explanations can help you on learning C and Algorithm faster.
Your for loop is using your variable 'a' instead of the factorial variable and i, try something like this
factorial = 1;
for (int i = 1; i<=a; i++)
{
factorial *= i;
}
You must initialize your factorial to 1, and then the for loop will keep multiplying it by 'i' until 'i' is greater than 'a'.
You are modifying the input a rather than factorial and also wrong (undefined behaviour) because you are using factorial uninitialized. You simply need to use the factorial variable you declared.
int factorial = 1;
...
for (int i = 1; i<=a; i++) {
factorial = i*factorial;
}
EDIT:
Also, be aware that C's int can only hold limited values. So, beyond a certain number (roughly after 13! if sizeof(int) is 4 bytes), you'll cause integer overflow.
You may want to look at GNU bugnum library for handling large factorial values.
Consider this code:
int main()
{
int i;
int ints[3];
ints[0] = 0;
ints[1] = 1;
ints[2] = 2;
for(i = 0; (ints[i])<4 && i<3; i++)
{
printf("%d\n", ints[i]);
}
}
Is there a reason I shouldn't do this sort of conditioning in the loop? I mean, when i becomes 3, will it look for a non-existing value at ints[3]? And if yes, is it ok?, since the loop is going to terminate anyway? It compiles and runs fine, but I was just wondering if there is some sort of a hidden problem with this. Thanks.
In the last iteration of this loop, the expression ints[i]<4 will access ints[3]. Since this access reads past the end of the array ints, the behavior is undefined in C. So yes, this is not good code. It may work most of the time, but the behavior is ultimately undefined.
It will be better to do i < 3 && ints[i] < 4 because the second part of the statement is evaluated only if the first one is true. The way you have it, it will look for ints[3] that does not exist.
It isn't okay to do this, because ints[3] will indeed be accessed. Now, because this is C, you're not going to get an error (unfortunately), but you'll never know for sure what the outcome would be.
Swapping the statements will solve the problem, because the && operator is optimized so that it doesn't evaluate the second condition if the first one is false.
The 'for' keyword expands out the following way:
int i;
for(i = 0; i < 2; i++)
dothing();
becomes
int i;
i = 0; /* first part of (i = 0; ...) */
beginloop:
if (i >= 2) goto endloop; /* second part of (...; i < 2; ...) */
dothing();
i++; /* final part of (...; ...; i++) */
goto beginloop;
endloop:
So, your code would expand out as follows:
i = 0;
beginloop:
if (ints[i] >= 4)
goto endloop;
if (i >= 3)
goto endloop;
printf(...);
i++;
goto beginloop;
endloop:
While this is fine, there is a problem with the ordering of your tests:
(ints[i] < 4) && (i < 3)
You should always check array indexes first to ensure they are valid before using them:
i = 0:
ints[0] < 4 && 0 < 3
i = 1:
ints[1] < 4 && 1 < 3
i = 2:
ints[2] < 4 && 2 < 3
i = 3:
ints[3] < 4 && 3 < 3 /* illegal access to ints[3] */
As a general rule of thumb, always try to order your conditionals in order of cost unless there is a better reason for the ordering, such as priority: In this case, i < 3 is the cheaper of the two tests, plus it is a constraint on the elements of ints you can access, so you checking the index should have a higher priority - you should check it before using it to tests ints[i] for anything.
The way you have written the loop, your code will try to read the non-existing array element ints [3]. That's undefined behaviour; a consequence is that anything can happen. Right now the whole internet is in uproar because of some code in OpenSSL that invoked undefined behaviour.
The loop terminates, that's okay. But you're accessing an area outside of what you're allowed to. It is undefined behaviour. You may get a segmentation anytime. But you're lucky.
Try putting i<3 before. That would work just fine.
for(i = 0; i<3 && (ints[i])<4; i++)
If i becomes 3, the second part is not evaluated. See short circuit evaluation.
I wrote this incredibly stupid code
#include <stdio.h>
main(){
int new[10], i;
for(i=1; i<=10; ++i){
new[i] = 0;
}
for(i=1;i<=10; ++i)
{
printf("%d", new[i]);
}
}
I compiled this using GCC on Xubuntu and then did the ./a.out. The cursor is just blinking resulting in no output. The same is the case when tried to debug with gdb. It runs and then stays with the blinking cursor.
Any help?
C arrays are 0 indexed - your program writes outside the boundaries of the new array, so it causes undefined behaviour. In this case, you probably are overwriting the i variable, so you end up with an infinite loop. You need to change your loops:
for (i = 0; i < 10; i++)
{
new[i] = 0;
}
and:
for (i = 0; i < 10; i++)
{
printf("%d", i);
}
you need to have a new line character to see the output , or flush the stdout otherwise sometimes it doesn't print, or it will be combined with the next line... try:
printf("%d\n", new[i]);
also, set your for loop from 0 to 9
int new[10] - Here new array can store 10 elements of type integer. You can access these elements from 0th to 9th index of array. Accessing beyond 9th index is undefined behavior.