• Welcome to the new Internet Infidels Discussion Board, formerly Talk Freethought.

The Programming Thread

In C++ and also in plain C, another useful keyword is const - on a function arg, it states that that arg's contents should not be modified by the function is that arg is a pointer or a reference. It can also be used for variables set at run time but not modified afterward, as a way of avoiding bugs. It can even be used on methods: put "const" after the declaration of a method and you are stating that the method is not to modify the object's variables, though it can modify the method's inputs.

Some recent langs don't do variable as default. Swift makes one declare with let (constant) or var (variable). With Rust, it's let (constant) or let mut (variable). mut = mutable.
 
Here is an alternative to:
C++:
string cards[52] = {
    " sk"," sq"," sj","s10"," s9"," s8",
    " s7"," s6"," s5"," s4"," s3"," s2"," sa",
    " hk"," hq"," hj","h10"," h9"," h8",
    " h7"," h6"," h5"," h4"," h3"," h2"," ha",
    " dk"," dq"," dj","d10"," d9"," d8",
    " d7"," d6"," d5"," d4"," d3"," d2"," da",
    " ck"," cq"," cj","c10"," c9"," c8",
    " c7"," c6"," c5"," c4"," c3"," c2"," ca"};
This stores the "rank" as an integer from 1 to 13. It also has:
const int ACE = 1;
const int JACK = 11;
const int QUEEN = 12;
const int KING = 13;
It also stores the suit as an int
const int HEARTS = 0;
const int CLUBS = 1;
const int SPADES = 2;
const int DIAMONDS = 3;
const int NUM_SUITS = 4;
Or you could use an enum:
enum Suit { Diamonds = 1, Hearts, Clubs, Spades };

That way it's a lot easier to detect the rank or the suit of a card.... and you could initialise the cards in a nested loop with 4 lots of 13....

You don't need to store the points - you could do:
points = min(rank, 10);
points = rank > 10 ? 10 : rank;
 
In C++ and also in plain C, another useful keyword is const ...

I've written rather a lot of plain C code and the ONLY times I've ever used 'const' is to avoid a warning about the arguments to qsort(). The ONLY times. Utility is in the eyes of the beholder.

Dennis Rictchie, who knew something about the C language, was not a fan of adding such type qualifiers to the C language.

Dennis Ritchie said:
This is an essay on why I do not like X3J11 type qualifiers. It is my own opinion; I am not speaking for AT&T.

Let me begin by saying that I'm not convinced that even the pre-December qualifiers (`const' and `volatile') carry their weight; I suspect that what they add to the cost of learning and using the language is not repaid in greater expressiveness.
`Volatile', in particular, is a frill for esoteric applications, and much better expressed by other means. Its chief virtue is that nearly everyone can forget about it. `Const' is simultaneously more useful and more obtrusive; you can't avoid learning about it, because of its presence in the library interface. Nevertheless, I don't argue for the extirpation of qualifiers, if only because it is too late.

The fundamental problem is that it is not possible to write real programs using the X3J11 definition of C. The committee has created an unreal language that no one can or will actually use. While the problems of `const' may owe to careless drafting of the specification, `noalias' is an altogether mistaken notion, and must not survive.
 
A basic principle of good coding practices is to never hard code contrasts into code.

cont int pi = 3.14.. for example ensures the value can never be inadvetetly corrupted elsewhere in the code. If you want to change the value it only as to be dome once.

When I was writing wok code I woud have an include file defs.h that had all the constants and defines.

e, pi. 2pi, C nd so n plus custom constants.

Two common ones people use
const inti TRUE = 1;
const FALSE = 0;

int check_limit(int x){

if*x > 2) return TRUE;
return FALSE;
}

main(){

int z = 3;
if(check_limit == TRUE)cout<<"greater";else cout"less than";
retrurn
}


Self docmtmg code. Meaningful variable and function names so you can follow the flow without havingto figure out code details.
It goes to readability. Another principle is code for the next guy who may have to deal with your code.

The golden rule, code as you would like to nave code written if you have to pick it up.

I am not a fan of hyper perfection and cleverness. It can make code difficult to maintain and modify, even for yourself.

At my firt job when a software engineer left nobody cod mainain his code, a rewrite was neccesary.

On a militarily test system project I was told to use a software engineer by my boss who said was good, turned out to be neporism. He left the company and I had to rewrite from scratch.

I always opted for clarity and simplicity at the expense of non optimum code. It was also more time efficient when working to schedules and budgets. I never woked in isolation, there were alwats others with requirements.
 
As to object-oriented programming, I've seen some people argue that it is overrated, or even very troublesome.

It's nevertheless a good paradigm for such applications as GUI widgets. One starts with a base class of "Widget" that has a location and a method for drawing itself that does nothing or else that is undefined, to be defined in subclasses of it. This class may be an abstract base class, one that cannot be instantiated by itself. One then defines subclasses of it like a container class, an image-canvas class, a text-display class, and a button class. The button class one then subclasses for a pushbutton class (what looks like a button), a checkbox class, and a radio-button class.

Multiple inheritance has problems like "diamond inheritance". B and C inherit from A and D from both B and C. Java gets around that problem by allowing only single inheritance of general classes, but multiple inheritance of "interfaces". An interface is an abstract class that contains only constants, class methods, and undefined instance methods. Objective-C and Swift have "protocol classes" of undefined instance methods, including optionally-implemented methods.

For instance, one can define an interface or protocol "Archivable" with methods "load" and "save" and "estimateSize". One would then implement these methods in whichever classes inherit from it.

Encapsulation can be done in a crude way by putting object details into some implementation file (plain C: .c) and exposing only pointers to those objects in some interface file (plain C: .h). But it is much easier in C++ and Java, for instance, where a class can have private variables and methods, only visible inside itself. C++ also has "friend" classes and functions, for letting them peek inside some class.

Polymorphism is done in compile-typed langs like C++ and Java by accepting subclasses of classes specified as arg types, classes in general, including interfaces and protocols.

All these object-oriented features can be done in plain C, but often by hand, and often in a kludgy or error-prone fashion.
 
C++ supports generic programming in a big way, a type-safe alternative to plain-C preprocessor macros. Thus, one can define template functions and classes, like

template<typename T> T square(const T &x) {return x*x;}
template<typename T> T cube(const T &x) {return x*x*x;}

The & in the arg indicates a reference, a C++ way of hiding pointers to data, useful for mutable and/or bulky data.

C++ has its Standard Template Library, including container classes and various algorithms for working with them. These containers are type-safe and they automatically deallocate their contents when they go out of scope. Along with variable-sized containers like "vector", there is a fixed-sized one, "array", in the STL because it has some of the methods that the variable-sized ones do, like size(), begin(), and end().

Most recently, C++ has gotten "concepts", which are type constraints for templates. Like being an integer type or having comparison methods. That makes compiler error messages much easier to understand.


An alternative to object-oriented programming is functional programming, and some people *love* it. But I find that it has its limitations, because most functional programming treats data objects as immutable, when one wants mutability for large sets of data where one wants to change only some of that set's contents without copying the entire set. Mathematica is almost purely functional, with only a few functions treating their args as mutable, like AppendTo[], and I've often run into that limitation of it. There are ways around that, like defining functions that hold one's data: f[1] = (what's in 1), f["a"] = (what's in "a"), etc., but though it achieves mutability, and fast mutability at that, it is an ugly kludge.

One functional language, Haskell, has something called a "monad", but I've never understood what a monad is supposed to be.
 
All these object-oriented features can be done in plain C, but often by hand, and often in a kludgy or error-prone fashion.
Yeah, when OO first came along I was having a hard time seeing how it was all that much superior to what I was already doing. Then I realized I had basically kludged OO.
 
int check_limit(int x){

if*x > 2) return TRUE;
return FALSE;
}

main(){

int z = 3;
if(check_limit == TRUE)cout<<"greater";else cout"less than";
retrurn
}
I guess TRUE/FALSE is easier for a beginner programmer to understand but you could also do this:
C++:
int check_limit(int x){
     return x > 2;
}

cout << (check_limit(z) ? "greater" : "less than");
 
class objects in OOP are just not features.

OOP represents a way of looking at and imaging a problem. It also depends on te scale of te prject.

A large project with multiple coders who may not even communicate with each other benefits from C++ and OOP.

You xcan sort of do the same thing in C. Write functions and compile to a libray. Howver as the scope grows so does the portential for sde effects that can be very difficult to debug and fix without a lot of pain.

I look at it like I do hardware design. Bords, modules, or circuits on a boad heve defined inouts and outputs that inerfcae to the rest of the system.

In circuit design the corollary to OPP is hierarchical design.

I look at a class object like a circuit board or module. There is a well defined interface any can connect to that will not corrupt the inner workings of the module.

A class object has a public interface. On a complex project as long as the interface does not change the inner workings of a class can chnge without affecting any other code or objects. The compiler will not allow an external pointer to be set to any private code or variables. It increase program relibility, minimizes the posiiblity of unforseen side effects. A major issue on large C programs.


C++ came about to deal with C issues and involve reliability.

In the 80s I had a roommate who was a COBOL programmer at a large company in Portland. Off hours he carried a beeper incase tere was a problem.

Back then a company could be held hostage when a programmer left. He'd be pad a retainer because nobody else oould maintain it.

OOP along with coding and documentation standards evolved because of all that.

A lot of code was written in GWBASUC that came with DOS. Some became nightmares. People add to and modify code without any structure. Spaghetti code.
 
A neural net based in C++ OOP.



Artificial Neural Network C++ class with two use cases: Counter and Handwritten Digits recognition
This article provides a simple C++ class without any complications in the mathematical calculations of the backpropagation algorithm. Two use cases have been provided to facilitate code usage.

Introduction​


Today, (ANN) Artificial neural networks has become dominant in many areas of life, whether an industry or at home. ANN enables machines to learn and to simulate human brain to recognize patterns, and make predictions as well as solve problems in every business sector. Smartphones and computers that we use on a daily basis are using ANN in some of its applications. For example, Finger Print and Face unlock services in smartphones and computers use ANN. Handwritten Signature Verification uses ANN. I have written a simple implementation for an Artificial Neural Network C++ class that handles backpropagation algorithm. The code depends on Eigen open-source templates to handle Matrices’ mathematics. I made code simple and fast as possible.

 
Craps, can you beat the dds? I thought about putting thi in math, but put it here.


Code:
void dice_test(){

    double total = 0, k = 100./36.;
    double pcalc[11] = {1*k,2*k,3*k,4*k,5*k,
                 6*k,5*k,4*k,3*k,2*k,1*k};
    int i, j, x,y,n[11],trials = 100000;

    unsigned seed = unsigned (time(NULL));
    srand(seed);
    for(i = 0; i < 11;i++)n[i] = 0;
    for(i = 0;i < 11;i++)total += pcalc[i];
    cout<<"total prob  "<<total<<endl;
    for(i = 0; i < trials;i++){
        x = int(rand()%6) + 1;
        y = int(rand()%6) + 1;
        //cout<<x+y<<endl;
        for(j = 0; j < 11;j++)if((x+y) == (j+2))n[j]++;
        }//fo1
    for(j = 0; j < 11;j++)
      printf("n %2d Count %8d  pc  %3.3f   prob calc  %2.3f\n",
        j+2,n[j],100*double(n[j])/double(trials),pcalc[j]);
}//dice_test()


First simulate th dice rolls. Results for 100k trials compared to calculated odds percent.


Note 7 has the highestpercentage.

N - Simulated - Calculated

2 2.802 2.778

3 5.522 5.556

4 8,245 8.333

5 11.186 11.111

6 13.916 13.888

7 16.661 16.667

8 13.815 13.889

9 11.023 11.111

10 8.362 8.333

11 5.597 5.556

12 2.865 2.778

There are may ways to bet with different odds. You can add the betting options.

Knowing the probabilities can you beat the hose and walk away with more money than you started with?

https://www.lasvegasdirect.com/las-vegas-craps-rules-and-bets/


Code:
int main(){

    int roll = 0,point = 0,x = 0, y = 0,cnt = 0;
    char ch;
    unsigned seed = unsigned (time(NULL));
    srand(seed);

    while(FOREVER){

      while(FOREVER){
        x = int(rand()%6) + 1;
        y = int(rand()%6) + 1;
        point = x + y;
        cout<<"Your Point Is "<<point<<endl;
        cout<<"Roll Out"<<endl;
        if(point == 11 || point == 7)
           {cout<<"Natural - Win"<<endl;point = 0;break;}
        if((point == 2) || (point == 3) || (point == 12))
           {cout<<"Craps 7 11  - Loose"<<endl;point = 0;break;}
        cnt = 0;
        cout<<"Pass Line  "<<endl;
        do{
            if(!point)break;
            if(cnt++ == 20000){cout<<"Runaway Loop"<<endl;return(0);}
            x = int(rand()%6) + 1;
            y = int(rand()%6) + 1;
            roll = x + y;
       }while((roll != point) && (roll != 7));

        if(point){
          if(roll == point)cout<<"Point - Win"<<endl;
          if(roll == 7)cout<<"Craps 7  - Lose"<<endl;
          }
       break;
     }//while

     cout<<endl<<"x to exit c continue -  ";
     cin>>ch;
     if(ch == 'x')break;
     cout<<endl<<endl;

    }//while

    return 0;

}//main()




Can you write code to come out ahead?
 
Bet you have been wodering how to use conplex numbers in C++. Well, the wait is over.



C = 1 + 1i is a complex number in C++. i is the imaginary number i = sqrt(-1).

Addition, subtraction, multiplication, division work like any other variable.

arg() retruns the angle +- PI radians(+-180 degrees). If you can’t think in radians it is easy to convert to degrees. You can change the signs on a amd vefy the nagles.

Depending on what you are doing polar(mag,angle) may be handy. It converts ploar magnitude and angle to a complex number.

abs() calculates the sqrt(real^2 + imag^2

Code:
#include<complex.h>
typedef complex<double> compvar;

//angle in degrees
double argd(compvar c){return(180*arg(c)/_PI);}


int main(){

    compvar a,b,c,d;
    double x,y,z;
    a = 1. + 1i;
    b = 1. - 2i;
    x = arg(a);
    y = argd(a);
    z = abs(a);
    cout<<" a  "<<a<<endl;
    cout<<"Mag a  "<<z<<endl;
    cout<<"a Radians   "<<x<<" a Degreees  "<<y<<endl;
    c = polar(sqrt(2),_PI/4);
    cout<<"Polar  "<<c<<endl;
    c = a/b;
    x = abs(c);
    y = argd(c);
    cout<<" / Magnitude "<<x<<"   Angle  "<<y<<endl;
    c = a*b;
    x = abs(c);
    y = argd(c);
    cout<<" * Magnitude "<<x<<"   Angle  "<<y<<endl;


    return 0;
}
 
Bet you have been wodering how to use conplex numbers in C++. Well, the wait is over.

Implicit in many discussions of C++ is the idea that C++ is distinctly superior to vanilla C. As an ardent fan of vanilla C, my instinct is to defend that simpler purer language.

Overloading the basic arithmetic operators is a major feature of C++. If the task is to add complex numbers a and b, who wouldn't want to be able to write (a+b) ? But I'll guess that much of the overloading that goes on in C++ is relatively useless. (cout << "Hello world" ? Whippee!)

Doing arithmetic with complex numbers will seem almost essential for some engineering and scientific programmers. But there is no need to switch from C to C++ just for that! The gcc C compiler offers support for complex numbers, complete with complex trig functions etc.
Code:
% head /usr/include/complex.h
/* $NetBSD: complex.h,v 1.3 2010/09/15 16:11:30 christos Exp $ */

/*
 * Written by Matthias Drochner.
 * Public domain.
 */

#ifndef _COMPLEX_H
#define _COMPLEX_H
...
long double complex cpowl(long double complex, long double complex);

gcc is an EXCELLENT C compiler, and the price is right. Let's hear no complaints please about C's support for complex numbers.
 
Implicit in many discussions of C++ is the idea that C++ is distinctly superior to vanilla C. As an ardent fan of vanilla C, my instinct is to defend that simpler purer language.
I toyed around with C a while ago by implementing a dynamic array, and while it was possible to do this, I also saw why developers would prefer to use classes and objects when working with data structures.

I can see the appeal of using C in embedded systems. It's easy to test, for one thing, and if a program is easy to test then it's potentially easy to optimise.
 
I toyed around with C a while ago by implementing a dynamic array, and while it was possible to do this, I also saw why developers would prefer to use classes and objects when working with data structures.
To do that in plain C, one has to choose between
  • Writing a set of functions for each data type of array - type-safe, but it requires a lot of copy-and-paste
  • Writing functions with lots of void * pointers - not type-safe
  • Using the preprocessor - not type-safe
One also has to be careful to deallocate one's array when one's done with it.

History of C++ - cppreference.com
C++ started out in 1979 as "C with Classes", and that was enough to make it possible to write a class that can clean up after itself, deallocating the memory that it earlier allocated for its use. One still had to use malloc() and free() until 1985, when new and delete were introduced. So one could write dynamic arrays, even if one had to choose between a lot of copy-and-pasting and using the preprocessor.

That changed in 1990, when templates were introduced. That made it possible to write type-safe dynamic arrays without any copy-and-pasting. All one has to do is define the array with the type one wants.

In 1992, dynamic arrays were made a part of C++ with the Standard Template Library, so one doesn't have to write one's own.

C++ got its name in 1983:  C++

I can see the appeal of using C in embedded systems. It's easy to test, for one thing, and if a program is easy to test then it's potentially easy to optimise.
If you don't have to do very much, then plain C is likely OK.
 
One of the most important features of C++ is using // to comment out a line.:D

The GNU MINGW distribution supports c and c++. Its what I use with Codeblocks IDE. With an IDE you can general select from a list which standard of c or C++ rules you want to use.

Didn't think complex numbers could evoke such strong emotions.

If you want to explore emnved programming you can download the Microchip IDE and c compiler. It includes a simulator so you don;t need any hardware.

There is a leaning curve to undertsnding one of the basic microcontrollers.
 
Overloading the basic arithmetic operators is a major feature of C++. If the task is to add complex numbers a and b, who wouldn't want to be able to write (a+b) ? But I'll guess that much of the overloading that goes on in C++ is relatively useless. (cout << "Hello world" ? Whippee!)
I agree that that's silly. I don't use it very much myself -- I use plain-C printf() instead, even though I like a lot of C++ features.
 

Implicit in many discussions of C++ is the idea that C++ is distinctly superior to vanilla C. As an ardent fan of vanilla C, my instinct is to defend that simpler purer language.
C++: Take C, increase it, but use the original. How can that be an improvement? Programs, like ships, sink in the C.

If you have to go bare metal (or even the device driver level) you don't really have much of a choice, but otherwise use a safer language!
 
Implicit in many discussions of C++ is the idea that C++ is distinctly superior to vanilla C. As an ardent fan of vanilla C, my instinct is to defend that simpler purer language.
C++: Take C, increase it, but use the original. How can that be an improvement? Programs, like ships, sink in the C.

If you have to go bare metal (or even the device driver level) you don't really have much of a choice, but otherwise use a safer language!

This comment seems to assume that any addition to a language — at least if folded in to allow full backward compatibility — is an improvement. This is certainly NOT the view of Dennis Ritchie as I showed above in #283. The very spartanness — simplicity and transparency — of C is its great strength. Surely we'll agree that creating a (C+Cobol) or (C+Lisp) language — if it were possible to do that while retaining backward compatibility with C — and touting it as a general replacement for C is NOT a good idea.

The Transparency — easy-to-grok deterministic nature — of C is a key to its elegance and beauty. This can be lost in C++ where concealing library sources is sometimes considered virtuous, and where, at least in principle, inheritance mazes must be traversed to associate proper class elements.

Safety? Does C++ not suffer from the same risks of buffer overrun and pointer misuse that are possible in C? C++ makes SOME garbage collection automatic compared with C, but the programmer is still responsible via destructor functions which it is easy to get wrong ESPECIALLY when trying for automation.

Sure, C++ is superior to C for SOME programmers and SOME applications. Perhaps these SOMEs can be replaced with MOSTs but I do not think they can be replaced with ALLs.

And why shouldn't programming be a matter of pleasure? Some people just LIKE to program in an odd language like Forth, Lisp or APL. Do we denounce their source of pleasure? I have been fortunate that most of my million lines of code have been solo independent projects, or done where C was stipulated by my client. It may reflect my autism somewhat but I preferred machine/assembly language programming until my love-at-first-sight experience with C.

Is C++ better for most projects, or for very large multi-person projects? Perhaps; I do not argue this point. But when I think back on bugs I have made, or horrid designs I was hired to fix, few if any would have been avoided by coding in C++ instead of C.
 
Implicit in many discussions of C++ is the idea that C++ is distinctly superior to vanilla C. As an ardent fan of vanilla C, my instinct is to defend that simpler purer language.
C++: Take C, increase it, but use the original. How can that be an improvement? Programs, like ships, sink in the C.

If you have to go bare metal (or even the device driver level) you don't really have much of a choice, but otherwise use a safer language!

This comment seems to assume that any addition to a language — at least if folded in to allow full backward compatibility — is an improvement. This is certainly NOT the view of Dennis Ritchie as I showed above in #283. The very spartanness — simplicity and transparency — of C is its great strength. Surely we'll agree that creating a (C+Cobol) or (C+Lisp) language — if it were possible to do that while retaining backward compatibility with C — and touting it as a general replacement for C is NOT a good idea.
It was a joke.
 
Back
Top Bottom