C (ISO 99 standard) is a low level programming language, with powerful functionality. Windows, Linux and a variety of operating systems are written largely in C. C is also used to write time-sensitive applications, manage memory and generally undertake actions unavailable in higher level languages. To design applications in this language, you will need a compiler. Linux distros, in general, include the GNU C Compiler (GCC). For Windows developers, you can use Visual Studio or MinGW (basically GCC ported to Windows). To download MinGW: http://mingw.org/ and follow the installation instructions. If you have any trouble installing the compiler, let me know and I will try to help out. OK folks, lets grab a coffee and get to coding. While you can use an IDE, I personally use notepad when writing C applications. To start, I've created a new text file named "example.c" and opened the blank file in notepad. For the next part, I suggest typing the code in your IDE/text editor instead of copy/pasting it. This will give you more hands on experience with the code. IMO, reading/modifying code is a great way to learn the nuts & bolts of a language, as well as familiarize yourself with its all important syntax. (PHP developers will recognize the syntactical similarities between the two languages) Code:#include <stdio.h> /* This is a simple application that compares two integers and evaluates them with an IF statement */ int main(){ int var1 = 100; int var2 = 130; if(var1 > var2){ printf(“%d is greater than %d”,var1,var2); }else{ printf(“%d is less than %d”,var1,var2); } return(0); } If you used Visual Studio (vs MinGW + Notepad) compiling is pretty straightforward. Refer to VS documentation for specifics, or feel free to ask questions here and I will do my best to help you. I am very familiar with Visual Studio (with vb.NET and C#) but find MinGW more intuitive when compiling C applications due to my Linux background. In MinGW/GCC, you will need to run the following via the Windows command line (start->run->cmd.exe). Please note the path to your MinGW installation, as we will need it for the next steps. cd C:\mingw32path\bin {ENTER}gcc C:\Cprojectpath\example.c -o C:\Cprojectpath\example.exe {ENTER}C:\Cprojectpath\example.exe {ENTER}The output in your console will depend on the values specified in your code. Because these values are hard-coded, the utility of this application is pretty limited, right? Lets fix that, and provide our application a means of collecting information from users. Code:#include <stdio.h> /* This is a simple application that compares two user supplied integers and evaluates them with an IF statement */ int main(){ int var1; int var2; printf(“Please enter the first integer: “); //provide instructions to the user scanf(“%d”,&var1); //sets var1 equal to the input integer printf(“\n”); //line return printf(“Please enter the second integer: “); //provide instructions to the user scanf(“%d”,&var2); //sets var2 equal to the input integer printf(“\n”); //line return if(var1 > var2){ printf(“%d is greater than %d\n\n”,var1,var2); }elseif(var1 = var2){ printf(“%d is equal to %d\n\n”,var1,var2); }else{ printf(“%d is less than %d\n\n”,var1,var2); } return(0); } Now, following the same steps above, re-compile the code and run your executable. When prompted, provide the application numeric input. For the sake of learning, you can also try providing non-integer input. Take a look at the above code, and try to figure out what it is doing and why. If you need any help, let me know! In the mean time, I will continue to introduce my fellow PF members to the art/science of programming. For those curious, I am fluent or professionally proficient in several languages/technologies, including: C/99, C#, VB.NET, PHP, SQL, ASM, and others. Looking forward to writing more tutorials on these languages. PS: You may edit, re-use, modify, share, sell or otherwise use this code in any way you see fit. I do not require attribution in any way.
// pants C++ program #include <iostream> #include <conio.h> using namespace std; void main (void) //main program start { cout << "Hello World!"; //print stuff to screen _getch(); //notice the underscore here } //end of the code compile in visual studio 2017 (download the free student edition)
Jesus I've been doing for so long that a hello world application looks so weird. Also grab VSCode and a compiler. Get yourself off Windows and getchu urself a lil VM with a Ubuntu install. Windows got a headache more than @Luffaren with a Haloumi cheese overdose. Your life is grander when YOUR NOT CODING ON A SYSTEM THAT STILL USES C:\. WTF IS A ":" for?!?!?!
If you're a student, I wholly recommend using CLion, or any of Jetbrain's IDEs. Totally useful stuff and a lot of really neat built-in features. Otherwise, VSCode and Notepad++ are fine alternatives, as long as you're good with compiling using command line arguments C is an incredible language and one of my favorite languages to write in (Probably because my prof was fucking amazing) but it's also a major pain in the ass when you get into pointers and memory management. I was enjoying writing C programs to do OS calls for multithreading and the like.
//neural network digits //Doc Watson 2020 //..in less than 200 lines of code! #include <opencv2/core.hpp> #include "opencv2/highgui.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/ml.hpp" #include <opencv2/dnn.hpp> #include <algorithm> #include <iostream> #include <iomanip> #include <conio.h> #include <vector> #include <windows.h> using namespace cv; using namespace ml; using namespace dnn; using namespace std; const int SZ = 20;//size of each image is SZ x SZ pixels greyscale (1 channel) const int CLASS_N = 10;//number of output classes, in this case '0','1','2',...,'8','9' static void mosaic(const int width, const vector<Mat>& images, Mat& grid) { int mat_width = SZ * width; int mat_height = SZ * (int)ceil((double)images.size() / width); if (!images.empty()) { grid = Mat(Size(mat_width, mat_height), images[0].type()); for (size_t i = 0; i < images.size(); i++) { Mat location_on_grid = grid(Rect(SZ * ((int)i % width), SZ * ((int)i / width), SZ, SZ)); images.copyTo(location_on_grid); } } } static void shuffle(vector<Mat>& digits, vector<int>& labels) { vector<int> shuffled_indexes(digits.size()); for (size_t i = 0; i < digits.size(); i++) shuffled_indexes = (int)i; randShuffle(shuffled_indexes);//shuffle the test images vector<Mat> shuffled_digits(digits.size()); vector<int> shuffled_labels(labels.size()); for (size_t i = 0; i < shuffled_indexes.size(); i++) { shuffled_digits[shuffled_indexes] = digits; shuffled_labels[shuffled_indexes] = labels; } digits = shuffled_digits; labels = shuffled_labels; } static void deskew(const Mat& img, Mat& deskewed_img) { Moments m = moments(img); if (abs(m.mu02) < 0.01) { deskewed_img = img.clone(); return; } float skew = (float)(m.mu11 / m.mu02); float M_vals[2][3] = { {1, skew, -0.5f * SZ * skew}, {0, 1, 0} }; Mat M(Size(3, 2), CV_32F); for (int i = 0; i < M.rows; i++) { for (int j = 0; j < M.cols; j++) { M.at<float>(i, j) = M_vals[j]; } } warpAffine(img, deskewed_img, M, Size(SZ, SZ), WARP_INVERSE_MAP | INTER_LINEAR); } int main(void) { Mat raw; vector<Mat> digits, digitsraw; vector<int> labels; LARGE_INTEGER fr, t1, t2; //theRNG().state = time(NULL);//seed the random number generator printf("Loading training/test image mosaic...\n"); raw = imread("digits.png", IMREAD_GRAYSCALE);//load the raw image mosaic //imshow("Raw Image Mosaic",raw); //split the moasic into individual images and set labels####################### int height = raw.rows;//get height of mosaic image int width = raw.cols;//get width of mosaic image int sx = SZ;//set width of individual image int sy = SZ;//set height of individual image digitsraw.clear(); for (int i = 0; i < height; i += sy) for (int j = 0; j < width; j += sx) digitsraw.push_back(raw(Rect(j, i, sx, sy))); //now store labels for each digit for (int i = 0; i < CLASS_N; i++) for (size_t j = 0; j < digitsraw.size() / CLASS_N; j++) labels.push_back(i); printf("Raw image %d x %d pixels\npreprocessing...\n", width, height); shuffle(digitsraw, labels);//shuffle the images#################################### //deskew all digits for (size_t i = 0; i < digitsraw.size(); i++) { Mat deskewed_digit; deskew(digitsraw, deskewed_digit); digits.push_back(deskewed_digit); } int train_n = (int)(0.9 * digits.size());//90% training and 10% for testing######## int test_n = (int)(digits.size() - train_n); cout << "Total images =" << digits.size() << endl; cout << "Training images=" << train_n << endl; cout << "Testing images =" << test_n << endl; Mat train_set;//image for training images####################################### vector<Mat> digits_train(digitsraw.begin(), digitsraw.begin() + train_n); mosaic(50, digits_train, train_set); imshow("train set", train_set); vector<int> labels_train(labels.begin(), labels.begin() + train_n); Mat test_set;//image for test images############################################ vector<Mat>digits_test(digits.begin() + train_n, digits.end()); mosaic(25, digits_test, test_set); imshow("test set", test_set); vector<int> labels_test(labels.begin() + train_n, labels.end()); //convert training array of images to 32 bit floating point############################ Mat temp; Mat inputtrainingdata; vector <Mat> digits_trainf; for (int i = 0; i < train_n; i++) { digits_train.convertTo(temp, CV_32F, 1.0 / 255.0); digits_trainf.push_back(temp); Mat DataInOneRow = digits_trainf.reshape(0, 1); inputtrainingdata.push_back(DataInOneRow); } //cout<<digits_trainf[0]<<endl; //cout << "First training image is a " << labels_train[0] << endl; //cout<<"input training data cols="<<inputtrainingdata.cols<<endl; //convert testing array of images to 32 bit floating point############################ Mat inputtestdata; vector <Mat> digits_testf; for (int i = 0; i < test_n; i++) { digits_test.convertTo(temp, CV_32F, 1.0 / 255.0); digits_testf.push_back(temp); Mat DataInOneRow = digits_testf.reshape(0, 1); inputtestdata.push_back(DataInOneRow); } //cout << digits_testf[0] << endl; //cout<<"First test image is a "<<labels_test[0]<<endl; //cout << "input test data cols=" << inputtestdata.cols << endl; //convert output results to floating point with ouput=1.0 for correct digit############# Mat outputtrainingdata(0, CLASS_N, CV_32FC1); for (int i = 0; i < train_n; i++) { vector<float> outputTraningVector(CLASS_N); fill(outputTraningVector.begin(), outputTraningVector.end(), 0.0); outputTraningVector[labels_train] = 1.0; Mat tempMatrix(outputTraningVector, false); outputtrainingdata.push_back(tempMatrix.reshape(0, 1)); } //cout<<"output training data cols="<<outputtrainingdata.cols<<endl; //cout<<outputtrainingdata<<endl; int epochs = 10;//set up the NN############################################# const int h1 = 10;//just a guess?!?! //const int h2=10;//just a guess?!?! //const int h3=10;//just a guess?!?! Ptr<ANN_MLP>nndigits = ANN_MLP::create(); Mat layersSize=Mat(3, 1, CV_32F); layersSize.row(0) = Scalar(inputtrainingdata.cols); layersSize.row(1) = Scalar(h1); //layersSize.row(2)=Scalar(h2); //layersSize.row(3)=Scalar(h3); layersSize.row(2) = Scalar(outputtrainingdata.cols); nndigits->setLayerSizes(layersSize);//create the nn nndigits->setActivationFunction(ANN_MLP::ActivationFunctions::SIGMOID_SYM); TermCriteria termCrit = TermCriteria(TermCriteria::Type::COUNT + TermCriteria::Type::EPS, 1, 0.0000001); nndigits->setTermCriteria(termCrit); nndigits->setTrainMethod(ANN_MLP::TrainingMethods::BACKPROP); //nndigits->setTrainMethod(ANN_MLP::TrainFlags::NO_OUTPUT_SCALE); Ptr<TrainData> trainingData = TrainData::create(inputtrainingdata, SampleTypes::ROW_SAMPLE, outputtrainingdata); //cout<<"Press a key to start training..."<<endl; //waitKey(); printf("Training...\n"); for (int i = 0; i < epochs; i++) { QueryPerformanceCounter(&t1); nndigits->train(trainingData); QueryPerformanceCounter(&t2); QueryPerformanceFrequency(&fr); double t = (t2.QuadPart - t1.QuadPart) / (double)fr.QuadPart; //now test the NN //cout << "Epoch " << i << " time=" << t << " s "; cout << i + 1 << " "; Mat result; nndigits->predict(inputtestdata, result);//now test the trained network float best; int bint, correct = 0; for (int i = 0; i < result.size().height; i++) { best = result.at<float>(i, 0); bint = 0; for (int j = 1; j < result.size().width; j++) { if (result.at<float>(i, j) > best) { best = result.at<float>(i, j); bint = j; } } if (bint == labels_test) correct++; } printf("%.3f\n", ((float)correct / result.size().height) * 100.0); /*//print the results int prec=3; for (int i = 0; i < result.size().height; i++) { cout << "[ "; for (int j = 0; j < result.size().width; j++) { cout << fixed << setw(2) << setprecision(prec) << result.at<float>(i, j); if (j != result.size().width - 1) cout << ", "; else cout << " ]" << labels_test<<endl; } }*/ }//end of epoch loop cout << "Saving NN as \"digits.xml\"..." << endl; nndigits->save("digits.xml"); cout << "Finished testing..." << endl; cout << "Press anykey to exit... where's the anykey?" << endl; waitKey(); return 0; }