You are not logged in.

#26 2009-09-27 20:51:22

absolutezero1287
Member
Registered: 2008-11-13
Posts: 133

Re: Tips for someone new to C/C++

This was one of the first scripts I wrote in Perl. I'm trying to rewrite it in C.

#!/usr/bin/perl
use strict;
use warnings;
use Math::Complex;
#
#This is my attempt at a script that solves quadratic equations
#
print "NOTICE: I only like integers. Any attempts at using\nsomething like four instead of 4 will result in an error.\n";
sleep 1;
print "Input the value of a\n";
#
#a must not equal zero
#
my $a;
chomp ($a = <STDIN>);
if ($a == 0) {print "You can not divide by 0.\n" and exit};
unless ($a == 0) {print "a = $a\nInput the value of b\n"};
my $b;
chomp ($b = <STDIN>);
print "b = $b\nInput the value of c\n";
my $c;
chomp ($c = <STDIN>);
#
#First we'll get the discriminant, d
#
my $d= ($b**2 - (4*$a*$c));
#
#1 for positive
#2 for negative
my $x1 = (-$b + sqrt($d));
my $x2 = (-$b - sqrt($d));
#
my $x1ans = ($x1 / (2*$a));
my $x2ans = ($x2 / (2*$a));
my @vals = ($x1ans , $x2ans);
print "@vals\n";

Offline

#27 2009-09-28 01:30:37

Trent
Member
From: Baltimore, MD (US)
Registered: 2009-04-16
Posts: 990

Re: Tips for someone new to C/C++

Here's a quick scrap of C that reads in a string of 3 integers with fgets() and picks them apart with strtok(). This is one way to read input with C, and (I think) less prone to mistakes than using scanf().

#include <stdio.h> /* for fgets() */
#include <string.h> /* for strtok() */
#include <stdlib.h> /* for EXIT_* and strtod() */

#define MAX_PARAMS  128 /* number of characters in the string that will be read */

int main(void)
{
    double a, b, c;
    char *tmp, params[MAX_PARAMS];
    printf("Enter the coefficients of your quadratic equation: ");
    fflush(stdout);
    if (!fgets(params, MAX_PARAMS, stdin)) {
        fprintf(stderr, "EOF or file I/O error occurred\n");
        return EXIT_FAILURE;
    }
    tmp = strtok(params, " \t\n");
    a = strtod(tmp, NULL);
    tmp = strtok(NULL, " \t\n");
    b = strtod(tmp, NULL);
    tmp = strtok(NULL, " \t\n");
    c = strtod(tmp, NULL);
    printf("a=%f b=%f c=%f\n", a, b, c);
    return EXIT_SUCCESS;
}

It has a few bugs.  If you do not enter at least three whitespace-separated tokens, it will segfault because I didn't check the return value of each strtok() (which returns NULL if it reaches the end of the string before finding an appropriate token).  It can read at most 127 characters (including a terminating newline) before it gives up trying to pack more in.  Also, I didn't check whether the strtod succeeds in finding a number, so it has issues if the first three whitespace-delimited tokens don't start with valid numeric sequences.

On the other hand, fgets doesn't try to access memory you don't own no matter how many characters you try to cram in.  I remembered to fflush(stdout) after printing the prompt (forgetting to do so could mean that it doesn't get printed at all until the next newline).  And I used EXIT_SUCCESS and EXIT_FAILURE instead of 0 and 1 (or 0 and -1).

Handling complex solutions is going to be a problem, though (at least, more so than in Perl).  As it is, the code above is valid ANSI C89.  If you want to deal with complex roots in a sane manner, you can either calculate them yourself and keep track of a real and imaginary part for each root, or use C99's csqrt(), cimag(), and creal() functions (be sure to #include <complex.h>).

So, suggested exercises for the reader:
- Check the return value of strtok() and make sure strtod() actually finds a number.  Make the program recover sensibly from malformed input.
- Find the discriminant and calculate the real and imaginary parts of each complex solution.  Print them out.
- Research <complex.h> and find the solutions by using C99 complex arithmetic.  You'll use csqrt() instead of sqrt() and print the real and imaginary parts individually (there's no "natural" way to print a complex number).
- Rewrite input with loops and getchar() instead of using fgets() and strtok().  (Hint:  Collect consecutive numeric characters in a buffer and run strtod() on it when you find a non-numeric character).  This should make its input handling more robust.
- Rewrite input with scanf().  This is probably the quickest way of reading three numbers, but recovery from input errors is very difficult (scanf is meant for reading fixed-format files, not interactive input).
- Instead of reading the numbers interactively from the user, take them from the command line arguments.

If you're getting the idea that you really need to watch your step in C, you're right.  Unlike Perl, which collects your garbage, provides convenience functions like chomp, and has nice imports like Math::Complex to take care of the mess, C demands that the programmer know what he or she is doing.  C is like a razor-sharp blade:  when correctly wielded, it's precise and effortless, but if you don't treat it with respect, you'll just cut yourself.

(My original analogy was "C is like a cockatrice corpse", but I figured most people wouldn't get that one.)

Offline

#28 2009-09-28 13:13:13

Lich
Member
Registered: 2009-09-13
Posts: 437

Re: Tips for someone new to C/C++

Trent wrote:

(My original analogy was "C is like a cockatrice corpse", but I figured most people wouldn't get that one.)

yikes
tMmZ0NA


Archlinux | ratpoison + evilwm | urxvtc | tmux

Offline

#29 2009-09-29 00:03:00

SoleSoul
Member
From: Israel
Registered: 2009-06-29
Posts: 319

Re: Tips for someone new to C/C++

I know people posted links to books and you may think why another one. Well, I admire this book so much so I must let other know about it. It's called C++ in action and the book teaches you not just C++ but how to program. This is a VERY different thing.
I started learning C++ from Herbert Schildt's "C++ form the ground up" and after I finished the book I found that I know the syntax and a bit more but I don't really know how to program. Then I restarted learning from "C++ in Action" and after learning half of the book I knew enough to skip a few courses in the university (C++, data structures etc).
Therefore I REALLY recommend this book. I can't guarantee that you will like it but I think you should give it a try.
Just an example for the creative thinking of the author: His hello world program is creating a "World" (class World) and letting it say hello (through the constructor). It emphasizes the idea of OOP of C++ in contrast to C.
Link to the book:
http://www.relisoft.com/book/

Good luck!

Offline

Board footer

Powered by FluxBB