May 8, 2013, 11:43 AM  #1 
Some help with some basic C
Hi guys,
I am busy learning C on my MacBook through xCode as the DE. The reason I am doing it this way is due to also going into iOS development. So, to be a better iOS developer, I want to make sure I understand the C language better too, as well as ObjectiveC. I have started reading the book: Learn C on Mac (4th edition) by David Mark's, I think. Now, the following bit of code I am having issues with  I understand how this code works 99%  the challenge in the code is to make the program compute prime numbers 1 to 100. I have having difficulty figuring out how / where to implement a for / while loop to count to 100 (candidate is the int I need to get from 1 to 100) Code:
#include <stdio.h> #include <math.h> //used for extra math functions #include <stdbool.h> // Used for the definition of truth int main(int argc, const char * argv[]) { bool isPrime; int startingPoint, candidate, last, i; startingPoint = 235; if ( startingPoint < 2){ candidate = 2; } else if ( startingPoint == 2 ) { candidate = 3; } else { candidate = startingPoint; if (candidate % 2 == 0 ) /*Test only odd numbers */ candidate ; do { isPrime = true; candidate +=2; last = sqrt( candidate ); for (i =3; (i <= last) && isPrime ;i +=2 ) { if ( (candidate % i) == 0) isPrime = false; } }while ( ! isPrime ); printf ( "The next prime number afer: %d is %d, Happy?" , startingPoint, candidate); return 0; } } Can anyone help a newbie to C out and show me how this is done? Also, if you can explain a little and not just provide the code, that would be great! Thanks guys!
__________________
I don't list my Apple devices as no one cares. "Do what you love (no excuses!)"  Gary Vaynerchuk 

0 
May 8, 2013, 01:05 PM  #2 
What have you tried? Be specific. Post code, if you wrote code. Otherwise post concise descriptions.
In everyday conversation, how would you tell another person to repeat something 100 times? Again, be specific. Think through exactly what you'd tell them. If you were telling an adult you might not need to give specifics, so imagine you're telling a 4yearold child who needs every step described in the correct order. In general, a loop consists of a loop action, which defines the action to perform at each iteration of the loop, and looping conditions, which define a range of values the action is performed over. Look at your description of how to tell a 4yearold to loop, and how to tell a computer to loop with a 'for' loop, and identify what's the action and what's the looping conditions. Please explain this code: Code:
startingPoint = 235; Where did the posted code come from? Did you write it yourself, or copy it from somewhere? If the latter, where was it copied from? 

0 
May 8, 2013, 02:52 PM  #3  
Quote:
With me starting out programming, I really need to practice more "thoughtpatern" and steps to solving these problems. Okay  so I understand for / while / do loops pretty well i think. This is what I changed and it didn't work: Code:
bool isPrime; int startingPoint, candidate, last, i; startingPoint = 5; if ( startingPoint < 2){ candidate = 2; } else if ( startingPoint == 2 ) { candidate = 3; } else { // candidate = startingPoint; for (candidate = startingPoint; candidate < 100; candidate++) { if (candidate % 2 == 0 ) /*Test only odd numbers */ candidate ; do { isPrime = true; candidate +=2; last = sqrt( candidate ); for (i =3; (i <= last) && isPrime ;i +=2 ) { if ( (candidate % i) == 0) isPrime = false; } }while ( ! isPrime ); printf ( "The next prime number afer: %d is %d, Happy?" , startingPoint, candidate); return 0; } } } What I am unsure of is this: 1. Can I have a do loop and another for loop inside a a main for loop  or is this the reason the code won't run the way I intend it to do? The original code comes from a book published by Apress: Learn C on the Mac (4th edition)  Author: Dave Mark's I know to a child I would say: "Go through all these numbers (1 to 100 ) pick up the prime numbers (numbers that cannot be divided evenly) then write them down for me." Translating that to the computer is my stumbling block  I mean I can do a simple for loop that counts to 100 which is easy. But I feel I am missing something obvious here. Can you tell me if I am at least heading down the right direction with my modified code? I'm going to try work on it tomorrow. The answer to this question has been given to me on another programming bored  I haven't looked at the code yet because I want to try work my way to the answer. Thanks again for your assistance. Edit: Code:
startingPoint = 235
__________________
I don't list my Apple devices as no one cares. "Do what you love (no excuses!)"  Gary Vaynerchuk 

0 
May 8, 2013, 03:51 PM  #4  
When your posted code "doesn't work", exactly what does it do? What output is produced? If none, then say that.
If you take out the 'for' loop, and only that, leaving other values the same, what output is produced? Here are some Rules of Thumb: 1. Be specific. 2. Post your code. 3. Describe what you expected to happen. 4. Describe what actually happened. You're sorta doing #1, definitely doing #2, but you're not doing #3 or #4. These aren't just rules of thumb for posting, they're guidelines for how to think about debugging your program. For example, if you don't know what's expected to happen, then you don't understand the code. If you don't compare the expectation against the actual result, then you're not testing systematically. "It doesn't work" could mean almost anything. "I expected it to say '5' but instead it said '12'" is a very specific statement, and if accompanied by the code that was used can be debugged. Have you mentally stepped through your original code? The code in your first post? You should be able to manually do each step, perhaps using a calculator, and write down the results of each statement. If you follow it logically, you'll be manually performing the same steps the computer does. If you don't know how to do that, then it suggests you don't have as good a grasp of the fundamentals as needed. In other words, if you can't read the code and actually work out what it does, then you have a problem that suggests more studying is needed. You have two separable problems in your first post: 1. How to use a for loop. 2. How to find a prime number. You can learn to use a for loop by practicing it with simpler problems. For example, use a for loop to print the numbers from 112, one per line. Next, use it to print the odd numbers between 1 and 21, including both endpoints. This should teach you how for loops work, because the action done at each iteration is quite simple. You're learning how to loop and how to set up the correct looping conditions. Once you learn how for loops work (and you can come up with more exercises than just those two above), you can learn how the primefinding code works. I suggest stepping through it manually. Start with values that will give specific expected results, such as 5 as the starting point, and find the first prime after that. You know the answer, so make sure the answer comes out. Then do it again with a slightly different starting point, such as 7. Again, you know the answer, but it's not the next odd number (9), it's 11. So again, manually step through and make sure it works out. You can also run the program without a for loop and make sure that an input of 5 produces 7, and an input of 7 produces 11. I suggest doing that BEFORE manually stepping thru the code, because otherwise you have no idea if the code even works. If a single run doesn't produce the expected output, then you need to solve that problem first, before putting it inside a for loop. Quote:
Quote:
From the site for the book: http://www.apress.com/9781430218098 Referring to the Source Code/Downloads zip file, exactly which project number are you working from? Last edited by chown33; May 8, 2013 at 03:57 PM. 

2 
May 8, 2013, 03:56 PM  #5 
You mentioned its not entering the loop at all  how do you know whether it is or isn't, or are you just guessing? Since you don't know any better techniques right now to find out, I suggest putting some sort of printf statement in the loop that let's you know each time it runs.


0 
May 8, 2013, 04:00 PM  #6  
First issue, you have no way of knowing whether you are entering the for loop since you don't have a print statement at the top of the for loop.
Try inserting the printf shown below in your code: Code:
for (candidate = startingPoint; candidate < 100; candidate++) { printf("in for loop: candidate= %d startingPoint=%d\n", candidate, startingPoint); if (candidate % 2 == 0) /* Test only odd numbers */ That will give you some information about what is happening when you run the code. You also have the following at the end of your code: Code:
return 0; } } } This would also be a lot easier to reason about if you wrote a function to check whether a number is prime. Break the problem down into:
So, for part 1 get the following working: Code:
bool is_prime(int n) { /* fill in this function */ } int main(int argc, const char * argv[]) { int number = 1; /* change value to test implementation of is_prime() function */ if(is_prime(number)) { printf("%d is prime\n", number); } else { printf("%d is not prime\n", number); } } One more thing: Quote:
Last edited by mrichmon; May 8, 2013 at 04:06 PM. 

0 
May 8, 2013, 04:20 PM  #7 
You can have one loop inside another ("nested loops"). What kind of loops you decide to use doesn't matter. You should keep as few levels of nesting as possible, or the program will take very long time to terminate.
One obvious problem with your code is that you're setting isPrime to true when you can't know for sure if the number at hand ("candidate") is prime or not. All you know is that it's an odd number. In most cases, the forloop won't be executed. When the variable "last" has not been assigned any value, it will be using whatever was in its assigned part of the memory (usually 0 but it can be anything). So if last == 0, it will never be the case that candidate <= last, and the condition for running the loop will not be fulfilled. 

0 
May 9, 2013, 10:02 AM  #8 
Hi guys
Okay, so a lot to reply to here: @Chown33: Your reply really help me. I thought I understood the code 99% from the first example that I posted. I then took your advice and went stepbystep through the code on my own, with a calculator to see if I could match the computers result with my result. I was around 60% accurate and thus I knew I was missing the point of some of the code. I tracked it down to the dowhile, loop. It seems I was expecting it start at the top of the loop every time and increment candidate, even if it wasn't a prime. So after some fiddling and putting printf statements all over the place so I could "see" when / where candidate and last (The sqrt of candidate ) were incremented and sometime why  it was only then I figured out exactly how it works. So, to test this new found knowledge of how the code works I wrote down 15 random numbers between 20 and 600. I then calculated the next prime number for all those numbers and matched it to the computer 100% of the time!! So, now I understood exactly how this code was getting the next prime number I decided to tackle my original problem. Looking at the second code I posted I realized it would never work for two reasons: 1. Having the for loop start within the else statement was not a good idea and this did not work too well. (Unpredictable results) (I'm going through the code again to see exactly what it does when I put it inside the else statement) 2. I had terminaled the loop with: Code:
return 0; I picked this up when I was the I was only getting one printf statement in the console  which, was correct and was the first next prime number after 3. So I figured my for loop was ending prematurely. Once I realized these things  I moved the termination code (Code that tells the computer program ran okay, no errors, correct?) to outside of the loop, at the end of the main function: I then moved the for loop to start at the very top and for it to initialize "startingPoint" This is the modified code: Code:
int main(int argc, const char * argv[]) { bool isPrime; int startingPoint, candidate, last, i; for (startingPoint = 0; startingPoint <= 100; ++startingPoint){ if ( startingPoint < 2){ candidate = 2; } else if ( startingPoint == 2 ) { candidate = 3; } else { candidate = startingPoint; if (candidate % 2 == 0 ) /*Test only odd numbers */ candidate ; do { isPrime = true; candidate +=2; last = sqrt( candidate ); for (i = 3; (i <= last) && isPrime ;i +=2 ) { if ( (candidate % i) == 0) isPrime = false; } } while ( ! isPrime ); printf ( "The next prime number afer: %d is %d, Happy?\n" , startingPoint, candidate); } } return 0; } Code:
The next prime number afer: 3 is 5, Happy? The next prime number afer: 4 is 5, Happy? The next prime number afer: 5 is 7, Happy? The next prime number afer: 6 is 7, Happy? The next prime number afer: 7 is 11, Happy? The next prime number afer: 8 is 11, Happy? The next prime number afer: 9 is 11, Happy? The next prime number afer: 10 is 11, Happy? The next prime number afer: 11 is 13, Happy? The next prime number afer: 12 is 13, Happy? The next prime number afer: 13 is 17, Happy? The next prime number afer: 14 is 17, Happy? The next prime number afer: 15 is 17, Happy? The next prime number afer: 16 is 17, Happy? The next prime number afer: 17 is 19, Happy? The next prime number afer: 18 is 19, Happy? The next prime number afer: 19 is 23, Happy? The next prime number afer: 20 is 23, Happy? The next prime number afer: 21 is 23, Happy? The next prime number afer: 22 is 23, Happy? The next prime number afer: 23 is 29, Happy? The next prime number afer: 24 is 29, Happy? The next prime number afer: 25 is 29, Happy? The next prime number afer: 26 is 29, Happy? The next prime number afer: 27 is 29, Happy? The next prime number afer: 28 is 29, Happy? The next prime number afer: 29 is 31, Happy? The next prime number afer: 30 is 31, Happy? The next prime number afer: 31 is 37, Happy? The next prime number afer: 32 is 37, Happy? The next prime number afer: 33 is 37, Happy? The next prime number afer: 34 is 37, Happy? The next prime number afer: 35 is 37, Happy? The next prime number afer: 36 is 37, Happy? The next prime number afer: 37 is 41, Happy? The next prime number afer: 38 is 41, Happy? The next prime number afer: 39 is 41, Happy? The next prime number afer: 40 is 41, Happy? The next prime number afer: 41 is 43, Happy? The next prime number afer: 42 is 43, Happy? The next prime number afer: 43 is 47, Happy? The next prime number afer: 44 is 47, Happy? The next prime number afer: 45 is 47, Happy? The next prime number afer: 46 is 47, Happy? The next prime number afer: 47 is 53, Happy? The next prime number afer: 48 is 53, Happy? The next prime number afer: 49 is 53, Happy? The next prime number afer: 50 is 53, Happy? The next prime number afer: 51 is 53, Happy? The next prime number afer: 52 is 53, Happy? The next prime number afer: 53 is 59, Happy? The next prime number afer: 54 is 59, Happy? The next prime number afer: 55 is 59, Happy? The next prime number afer: 56 is 59, Happy? The next prime number afer: 57 is 59, Happy? The next prime number afer: 58 is 59, Happy? The next prime number afer: 59 is 61, Happy? The next prime number afer: 60 is 61, Happy? The next prime number afer: 61 is 67, Happy? The next prime number afer: 62 is 67, Happy? The next prime number afer: 63 is 67, Happy? The next prime number afer: 64 is 67, Happy? The next prime number afer: 65 is 67, Happy? The next prime number afer: 66 is 67, Happy? The next prime number afer: 67 is 71, Happy? The next prime number afer: 68 is 71, Happy? The next prime number afer: 69 is 71, Happy? The next prime number afer: 70 is 71, Happy? The next prime number afer: 71 is 73, Happy? The next prime number afer: 72 is 73, Happy? The next prime number afer: 73 is 79, Happy? The next prime number afer: 74 is 79, Happy? The next prime number afer: 75 is 79, Happy? The next prime number afer: 76 is 79, Happy? The next prime number afer: 77 is 79, Happy? The next prime number afer: 78 is 79, Happy? The next prime number afer: 79 is 83, Happy? The next prime number afer: 80 is 83, Happy? The next prime number afer: 81 is 83, Happy? The next prime number afer: 82 is 83, Happy? The next prime number afer: 83 is 89, Happy? The next prime number afer: 84 is 89, Happy? The next prime number afer: 85 is 89, Happy? The next prime number afer: 86 is 89, Happy? The next prime number afer: 87 is 89, Happy? The next prime number afer: 88 is 89, Happy? The next prime number afer: 89 is 97, Happy? The next prime number afer: 90 is 97, Happy? The next prime number afer: 91 is 97, Happy? The next prime number afer: 92 is 97, Happy? The next prime number afer: 93 is 97, Happy? The next prime number afer: 94 is 97, Happy? The next prime number afer: 95 is 97, Happy? The next prime number afer: 96 is 97, Happy? The next prime number afer: 97 is 101, Happy? The next prime number afer: 98 is 101, Happy? The next prime number afer: 99 is 101, Happy? The next prime number afer: 100 is 101, Happy? So happy when I made this realization  once I figured out exactly how the original code worked  it took a whole of 30 seconds to modify to to work as I wanted it to! Once again, thank you Chown33! @ ArtOfWarfare: I wasn't guessing at first  I could only see the first result in the console and this was a clue that the loop only ran once or not at all. I later figured out adding more printf statements would help me track the problem down! Thanks! @ mrichmon I realize now you actually provided me with a clue (indentation) which was the biggest problem with the modified code I posted. Tomorrow I will look at your own code and see if I can fill that function in  although I now understand my original code 100%  I must keep getting better at this and more practice! @ DesertEagle isPrime is set to true at the top of the dowhile, loop  at the bottom we check to see if candidate really is prime  if it is not  we set isPrime to false  the loop will continue to run until we can not divide candidate evenly by " i " and thus, leaving isPrime as true  terminating the dowhile, loop. "Last" will always have a value as it gets assigned the square root of candidate  and candidate gets its value from startingPoint, which always has a value: So: startingPoint is initilized to a value by the for loop at the top (Modified code) half way down, we assign startingPoint's value to candidate: Code:
candidate = startingPoint; Once that happens and we get into the dwhile, loop (I am skipping a bit of code here, I know, but I don't think it needs me to explain? ) we then get the square root of candidate Code:
last = sqrt( candidate ); Also, the dowhile, loop is not conditioned upon last having a value  it's conditioned upon this: Code:
while ( ! isPrime ); I didn't feel it was needed for me to explain the whole code, step by step? I think i will give myself a pat on the back? Appreciate all the help guys  I know this was a "simple" problem, but it has helped me a lot I will now make sure I understand the code 100% before trying to change it. It has also taught me more about loops and math functions than before. So I guess it's good progress?
__________________
I don't list my Apple devices as no one cares. "Do what you love (no excuses!)"  Gary Vaynerchuk Last edited by Tander; May 9, 2013 at 12:46 PM. 

0 
May 10, 2013, 08:58 AM  #9 
chown FTW
I'd lilke to add to OP's praise of chown's teaching style. I've seen chown help a lot of people in this forum. Their underlying problem is that they've bitten off more than they can chew and don't know it. chown's analysis method (to paraphrase: baby steps, MF'er) is the best path to both solving whatever your current problem is, and to having a method to solve future problems.
__________________
iMac 21.5", 3.06GHz, 4 GB, 2 TB HD. iPod Touch 3G. 

2 
«
Previous Thread

Next Thread
»
Thread Tools  Search this Thread 
Display Modes  


All times are GMT 5. The time now is 06:02 AM.