C/Przykłady z komentarzem
Liczby losowe
edytujPoniższy program generuje wiersz po wierszu macierz o określonych przez użytkownika wymiarach, zawierającą losowo wybrane liczby. Każdy wygenerowany wiersz macierzy zapisywany jest w pliku tekstowym o wprowadzonej przez użytkownika nazwie. W pierwszym wierszu pliku wynikowego zapisano wymiary utworzonej macierzy. Program napisany i skompilowany został w środowisku GNU/Linux.
#include <stdio.h> #include <stdlib.h> /* dla funkcji rand() oraz srand() */ #include <time.h> /* dla funkcji time() */ main() { int i, j, n, m; float re; FILE *fp; char fileName[128]; printf("Wprowadz nazwe pliku wynikowego..\n"); scanf("%s",&fileName); printf("Wprowadz po sobie liczbe wierszy i kolumn macierzy oddzielone spacją..\n"); scanf("%d %d", &n, &m); /* jeżeli wystąpił błąd w otwieraniu pliku i go nie otwarto, wówczas funkcja fclose(fp) wywołana na końcu programu zgłosi błąd wykonania i wysypie nam program z działania, stąd musimy umieścić warunek, który w kontrolowany sposób zatrzyma program (funkcja exit;) */ if ( (fp = fopen(fileName, "w")) == NULL ) { puts("Otwarcie pliku nie jest mozliwe!"); exit; /* jeśli w procedurze glownej to piszemy bez nawiasow */ } else { puts("Plik otwarty prawidłowo.."); } fprintf(fp, "%d %d\n", n, m); /* w pierwszym wierszu umieszczono wymiary macierzy */ srand( (unsigned int) time(0) ); for (i=1; i<=n; ++i) { for (j=1; j<=m; ++j) { re = ((rand() % 200)-100)/ 10.0; fprintf(fp,"%.1f", re ); if (j!=m) fprintf(fp," "); } fprintf(fp,"\n"); } fclose(fp); return 0; }
Zamiana naturalnej liczb dziesiętnych na liczby w systemie dwójkowym
edytujZajmijmy się teraz innym zagadnieniem. Wiemy, że komputer zapisuje wszystkie liczby w postaci binarnej (czyli za pomocą jedynek i zer). Spróbujmy zatem zamienić liczbę, zapisaną w "naszym" dziesiątkowym systemie na zapis binarny. Uwaga: Program działa jedynie dla liczb od 0 do maksymalnej wartości którą może przyjąć typ unsigned short int
w twoim kompilatorze.
#include <stdio.h> #include <limits.h> void dectobin (unsigned short a) { int licznik; /* CHAR_BIT to liczba bitów w bajcie */ licznik = CHAR_BIT * sizeof(a); while (--licznik >= 0) { putchar (((a >> licznik) & 1) ? '1' : '0'); } } int main () { unsigned short a; printf ("Podaj liczbę od 0 do %hd: ", USHRT_MAX); scanf ("%hd", &a); printf ("%hd(10) = ", a); dectobin (a); printf ("(2)\n"); return 0; }
Zalążek przeglądarki
edytujZajmiemy się tym razem inną kwestią, a mianowicie programowaniem sieci. Jest to zagadnienie bardzo ostatnio popularne. Nasz program będzie miał za zadanie połączyć się z serwerem, którego adres użytkownik będzie podawał jako pierwszy parametr programu, wysłać zapytanie HTTP i odebrać treść, którą wyśle do nas serwer. Zacznijmy może od tego, że obsługa sieci jest niemal identyczna w różnych systemach operacyjnych. Na przykład między systemami z rodziny Unix oraz Windowsem różnica polega tylko na dołączeniu innych plików nagłówkowych (dla Windowsa - winsock2.h). Przeanalizujmy zatem poniższy kod:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define MAXRCVLEN 512 #define PORTNUM 80 char *query = "GET / HTTP1.1\n\n"; int main(int argc, char *argv[]) { char buffer[MAXRCVLEN+1]; int len, mysocket; struct sockaddr_in dest; char *host_ip = NULL; if (argc != 2) { printf ("Podaj adres serwera!\n"); exit (1); } host_ip = argv[1]; mysocket = socket(AF_INET, SOCK_STREAM, 0); dest.sin_family = AF_INET; dest.sin_addr.s_addr = inet_addr(host_ip); /* ustawiamy adres hosta */ dest.sin_port = htons (PORTNUM); /* numer portu przechowuje dwubajtowa zmienna - musimy ustalić porządek sieciowy - Big Endian */ memset(&(dest.sin_zero), '\0', 8); /* zerowanie reszty struktury */ connect(mysocket, (struct sockaddr *)&dest,sizeof(struct sockaddr)); /* łączymy się z hostem */ write (mysocket, query, strlen(query)); /* wysyłamy zapytanie */ len=read(mysocket, buffer, MAXRCVLEN); /* i pobieramy odpowiedź */ buffer[len]='\0'; printf("Rcvd: %s",buffer); close(mysocket); /* zamykamy gniazdo */ return EXIT_SUCCESS; }
Powyższy przykład może być odrobinę niezrozumiały, dlatego przyda się kilka słów wyjaśnienia. Pliki nagłówkowe, które dołączamy zawierają deklarację nowych dla Ciebie funkcji - socket(), connect(), write() oraz read(). Oprócz tego spotkałeś się z nową strukturą - sockaddr_in. Wszystkie te obiekty są niezbędne do stworzenia połączenia. Aby dowiedzieć się więcej nt. wszystkich użytych tu funkcji i struktur musisz odwiedzić podręcznik o programowaniu w systemie UNIX.
Znajdowanie wzoru funkcji kwadratowej przechodzącej przez trzy punkty
edytuj// gcc m.c -Wall
// ./a.out
# include <stdio.h>
//
//
// znane 3 punkty : (x0,y0), (x1,y1), (x2,y2)
// dane do testów
// (3,10),(1,0),(-2,15) -> f(x)=2x^2 -3x +1 http://matematyka.pisz.pl/strona/1394.html
// (1,−4), (2,3), (−1,0) -> f(x)=3x2−2x−5 http://matematyka.pisz.pl/forum/52119.html
// A(1,-1), B(0,0), C(-1,3): -> f(x)=x2-2x. http://www.traugutt.miasto.zgierz.pl/matma/kwadratowa.html
// (-6 ,51),(-5 , 38), (-4 , 27) -> The solution is a = 1, b = -2 and c = 3 http://answers.yahoo.com/question/index?qid=20090814183525AA26rSD
// (2 , -8),(1 , 0) (-2 , 0) -> f(x) = -2(x - 1)(x + 2) = - 2 x^2 - 2 x + 4 http://www.analyzemath.com/quadraticg/Tutorial1.html
// (1, 3), (−1, 4), (2, 1) -> a = −1/2 , b = −1/2 , and c = 4
// (−1,2), (0,3) and (1,6) -> y=x2+2x+3 http://www.amsi.org.au/ESA_Senior_Years/SeniorTopic2/2a/2a_2content_8.html
double wx[3]={3,1,-2}; // double wx[3]={x0,x1,x2};
double wy[3]={10,0,15}; // double wy[3]={y0,y1,y2};
// szukamy trójmianu kwadratowego
// f(x) = ax^2 + bx + c
//przechodzącego przez te 3 punkty = interpolacja kwadratowa
//
// układ 3 równań liniowych
// z 3 niewiadomymi : a, b, c
// a*x0^2 + b*x0 + c = y0
// a*x1^2 + b*x1 + c = y1
// a*x2^2 + b*x2 + c = y2
// układ 3 równań liniowych postaci :
// a*wi1 + b*wi2 + c*wi3 = yi
//
// win jest współczynnikiem : w
// gdzie pierwsza cyfra i jest numerem równia ( rząd )
// druga cyfra n jest numerem kolumny ( szukanej a, b, c )
//
// a*w00 + b*w01 + c*w02 = y0
// a*w10 + b*w11 + c*w12 = y1
// a*w20 + b*w21 + c*w22 = y2
// wi0 = xi^2
// wi1 = xi
// wi2 = 1
// 4 macierze :
//double ws[3][3] = {{w00,w01,w02},{w10,w11,w12}, {w20,w21,w22}};
// w kolumnie n jest yi
//double wa[3][3] = {{y0,w01,w02},{y1,w11,w12}, {y2,w21,w22}};
//double wb[3][3] = {{w00,y0,w02},{w10,y1,w12}, {w20,y2,w22}};
//double wc[3][3] = {{w00,w01,y0},{w10,w11,y1}, {w20,w21,y2}};
// a=wa/ws
// b= wb/ws
// c=wc/ws
/*
w = wyznacznik macierzy 3x3
1 2 3 w11 w12 w13 a1 b1 c1 w00 w01 w02
4 5 6 w21 w22 w23 a2 b2 c2 w10 w11 w12
7 8 9 w31 w32 w33 a3 b3 c3 w20 w21 w22
det = 1*5*9 + 2*6*7 + 3*4*8 - 3*5*7 - 2*4*9 - 1*6*8 =
det = w11*w22*w33 + w21*w32*w13 + w31*w12*w23 - w31*w22*w13 - w11*w32*w23 - w21*w12*w33;
det = a1*b2*c3 + a2*b3*c1 + a3*b1*c2 - a3*b2*c1 - a1*b3*c2 - a2*b1*c3;
det = w00*w11*w22 + w10*w21*w02 + w20*w01*w12 - w20*w11*w02 - w00*w21*w12 - w10*w01*w22;
http://www.sciaga.pl/tekst/41303-42-obliczanie_wyznacznikow_macierzy_c_c
test :
1 2 3
6 5 4
3 7 2
----
63.0000
http://www.matematyka.pl/12881.htm
3 1 1
2 2 3
1 3 2
----
-12
*/
// macierze do testów funkcji DeterminatOfMatrix33
double t1[3][3] = {{1,2,3},{6,5,4},{3,7,2}}; // det = 63
double t2[3][3] = {{3,1,1},{2,2,3},{1,3,2}}; // det = -12
// w = 1*5*9 + 2*6*7 + 3*4*8 - 3*5*7 - 2*4*9 - 1*6*8 = 0
double t3[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; // det = 0
double t4[3][3] = {{2,1,1},{1,-1,-1},{1,2,1}}; // det = 3 http://www.purplemath.com/modules/cramers.htm
double DeterminatOfMatrix33(double w[3][3])
{
return ( w[0][0]*w[1][1]*w[2][2] + w[1][0]*w[2][1]*w[0][2] + w[2][0]*w[0][1]*w[1][2] - w[2][0]*w[1][1]*w[0][2] - w[0][0]*w[2][1]*w[1][2] - w[1][0]*w[0][1]*w[2][2] );
}
// i =0 give det(wa);
// i =1 give det(wb)
// i =2 give det(wc)
double GiveDet_n(int n, double ws[3][3], double wy[3])
{
int i;
double wi[3][3]; // use local copy, do not change ws !
// copy values from ws to wi
for (i=0; i<3; ++i)
{
wi[i][0]= ws[i][0];
wi[i][1]= ws[i][1];
wi[i][2]= ws[i][2];
}
// copy wy column
for (i=0; i<3; ++i)
wi[i][n]=wy[i];
//
printf(" w%d = {",n);
for (i=0; i<3; ++i)
{
printf("{ %f ,",wi[i][0]);
printf("%f ,",wi[i][1]);
printf("%f }, \n",wi[i][2]);
}
return DeterminatOfMatrix33(wi);
}
// main matrix of system of equations
double GiveMatrixOfSystem(double wx[3], double ws[3][3])
{
int i;
printf(" ws = {");
for (i=0; i<3; ++i)
{
ws[i][0]= wx[i]*wx[i]; printf("{ %f ,",ws[i][0]);
ws[i][1]= wx[i]; printf("%f ,",ws[i][1]);
ws[i][2]= 1; printf("%f }, \n",ws[i][2]);
}
return DeterminatOfMatrix33(ws);
}
/* =================== main ============================================================*/
int main()
{
double ws[3][3];
double dets,deta, detb, detc;
double a,b,c;
dets = GiveMatrixOfSystem(wx,ws);
deta = GiveDet_n(0,ws,wy);
detb = GiveDet_n(1,ws,wy);
detc = GiveDet_n(2,ws,wy);
a = deta/dets;
b = detb/dets;
c = detc/dets;
printf("a = %f ; b = %f ; c = %f ;\n",a,b,c);
return 0;
}
Wybieranie ciągu z łańcucha
edytuj#include <stdio.h> // printf
/*
gcc r.c -Wall
time ./a.out
'0123456789012345678901'
'2345678'
/*
http://stackoverflow.com/questions/9895216/remove-character-from-string-in-c
"The idea is to keep a separate read and write pointers (pr for reading and pw for writing),
always advance the reading pointer, and advance the writing pointer only when it's not pointing to a given character."
modified
remove first length2rmv chars and after that take only length2stay chars from input string
output = input string
*/
void extract_str(char* str, unsigned int length2rmv, unsigned long int length2stay) {
// separate read and write pointers
char *pr = str; // read pointer
char *pw = str; // write pointer
int i =0; // index
while (*pr) {
if (i>length2rmv-1 && i <length2rmv+length2stay)
pw += 1; // advance the writing pointer only when
pr += 1; // always advance the reading pointer
*pw = *pr;
i +=1;
}
*pw = '\0';
}
int main() {
char str[] = "0123456789012345678901";
printf("'%s'\n", str);
extract_str(str, 2, 7); // opuszczamy 2 pierwsza znaki i wybieramy 7 następnych
printf("'%s'\n", str);
return 0;
}
Liczby wymierne binarne
edytuj#include <stdio.h> // fprintf
/*
https://stackoverflow.com/questions/19738919/gcd-function-for-c
The GCD function uses Euclid's Algorithm.
It computes A mod B, then swaps A and B with an XOR swap.
*/
int gcd(int a, int b)
{
int temp;
while (b != 0)
{
temp = a % b;
a = b;
b = temp;
}
return a;
}
int main(){
int dMax = 6;
int denominator = 1;
fprintf(stdout, "0/%d\n", denominator); // initial value
for (int d = 0; d < dMax; ++d ){
denominator *=2;
for (int n = 1; n < denominator; ++ n ){
if (gcd(n,denominator)==1 )// irreducible fraction
{fprintf(stdout, "%d/%d\t", n,denominator);}
}// n
fprintf(stdout, "\n"); // end of the line
} // d
return 0;
}
Kompilujemy:
gcc d.c -Wall -Wextra
Wynik :
./a.out
0/1
1/2
1/4 3/4
1/8 3/8 5/8 7/8
1/16 3/16 5/16 7/16 9/16 11/16 13/16 15/16
1/32 3/32 5/32 7/32 9/32 11/32 13/32 15/32 17/32 19/32 21/32 23/32 25/32 27/32 29/32 31/32
1/64 3/64 5/64 7/64 9/64 11/64 13/64 15/64 17/64 19/64 21/64 23/64 25/64 27/64 29/64 31/64 33/64 35/64 37/64 39/64 41/64 43/64 45/64 47/64 49/64 51/64 53/64 55/64 57/64 59/64 61/64 63/64