MacRumors Forums Some help with some basic C

 May 8, 2013, 11:43 AM #1 Tander macrumors 6502a     Join Date: Oct 2011 Location: Johannesburg, South Africa 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 Objective-C. 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 #include //used for extra math functions #include // 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; } } After trying a few methods, I am stuck. 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
chown33
macrumors 603

Join Date: Aug 2009
Quote:
 Originally Posted by Tander After trying a few methods, I am stuck.
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 4-year-old 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 4-year-old 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.

Code:
startingPoint = 235;
Why does it start at 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
Tander
macrumors 6502a

Join Date: Oct 2011
Location: Johannesburg, South Africa
Quote:
 Originally Posted by chown33 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 4-year-old 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 4-year-old 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; Why does it start at 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?
Thank you for the insightful reply.

With me starting out programming, I really need to practice more "thought-patern" 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;
}
}
}
Okay - so the above code runs - however, it runs ones and it doesn't enter the loop at all.

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?

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.

Edit:

Code:
startingPoint = 235
This is a random number - there is no real reason for starting at 235. Yes, it's above the 100 boundary - I have modified it in the second code I posted.
__________________
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
chown33
macrumors 603

Join Date: Aug 2009
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.
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 1-12, one per line. Next, use it to print the odd numbers between 1 and 21, including both end-points. 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 prime-finding 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:
 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."
Imagine it's a younger child. You have to show each step. Step by step. Do this. Then do this. Then do this. Every. Single. Step.

Quote:
 The original code comes from a book published by Apress: Learn C on the Mac (4th edition) - Author: Dave Mark's
Which chapter? Which exercise?

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 ArtOfWarfare macrumors 603     Join Date: Nov 2007 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
mrichmon
macrumors 6502a

Join Date: Jun 2003
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;
}
}
}
The indentation suggests that you intend that the red colored brace will close the for statement brace. However, in C indentation is irrelevant. The red closing brace is actually closing the brace for the else statement.

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:
1. Write main() method that will call a function to determine if a number is prime.
2. Write function to determine if a number is prime.
3. Modify main method to loop over 1 to 100 and print all prime numbers.

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);
}
}
When you have that code working, try to adapt the main function to solve your original problem. The key is that the is_prime function will not need to be modified if you get it working correctly in step 2.

One more thing:
Quote:
 Originally Posted by Tander 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 code will never run the way you intend it to. It will only ever run the way you have written it to run.

Last edited by mrichmon; May 8, 2013 at 04:06 PM.
0
 May 8, 2013, 04:20 PM #7 DesertEagle macrumors 6502a     Join Date: Jan 2012 Location: /home @ 127.0.0.1 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 for-loop 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 10, 2013, 08:58 AM #9 PatrickCocoa macrumors 6502a   Join Date: Dec 2008 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

 MacRumors Forums