Wątek przeniesiony 2023-10-10 13:07 z C/C++ przez Althorion.

techniki pisania w języku C vs C++?

1
Riddle napisał(a):

Jeśli coś ma być grupowane dla samego grupowania (bez enkapsulacji i abstrakcj), to praktycznie masz strukturę, a nie obiekt.

mi chodziło o zgrupowanie razem i składników i operacji na nich wykonywanych

0
jarekr000000 napisał(a):
Miang napisał(a):

tak jak w javie ;)

Jak? Da się zrobić NullPointerException w C++?

Jak najbardziej, wymaga to tylko odrobiny gimnastyki przy odpowiednich handlerach SIGSEGV.

0
jarekr000000 napisał(a):
andrzejlisek napisał(a):

To wynika ze znaczącej różnicy między C++ a Java w kwestii wskaźników i obiektów. W przypadku C++ wskaźnik na obiekt może być "przypadkowy" i próba odwołania się do niego może spowodować nieprzewidziany skutek.

Jesteś pewny? Czy może raczej odwołanie się do przypadkowego wskaźnika w C++ jest niezdefiniowane - więc w zasadzie oznacza, że kod nie jest w C++?

Możliwe, że się nie rozumiemy, więc kawałek kodu:

class foo
{
};

#define NULL 0

int main()
{
    foo * bar;

    // w C, C++ bar ma przypadkową wartość, a w Java i C# ma null lub kompilator nie skompiluje z powodu próby odczytu zmiennej bez nadanej wartości.
    // W C++, próba odczytu lub zapisu pod wartość wskazywaną przez wskaźnik jest UB (nie wiadomo, co się wydarzy, nie jest to zdefiniowane).

    bar = NULL;

    // wskaźnik jest pusty, nie wskazuje na żaden obiekt ani na żaden bajt w pamięci. Próba odczytu lub zapisu powinna rzucić wyjątek.
    // Można jednoznacznie stwierdzić, czy ==NULL, czy !=NULL.

    bar = new foo();

    // wskaźnik wskazuje na obiekt klasy foo. Pod spodem jest jakaś liczba, od tego momentu można coś odczytać, zapisać w obiekcie bar.

    delete bar; // czynność niemożliwa w Java i w C#

    // Od tego momentu próba odczytu lub zapisu tak, jakby był obiekt jest UB, nie wiadomo, ta pamięć jest uznawana za pustą, a wskaźnik przypadkowy.
    
    bar = NULL; // To przypisanie powinno następować po wywołaniu delete lub free.

    // Teraz wiadomo, ze wskaźnik jest pusty.

    bar = (foo *)12457; // jakaś liczba, niemożliwe w Java i C#

    // bar w tym momencie wskazuje na przypadkowy adres w pamięci, każda próba wykorzystania (odczyt lub zapis) jest UB.
}

Jeżeli coś źle napisałem, to proszę wskazać, co źle napisałem. Dlatego uważam, że C++ różni się od Java/C# istnieniem możliwości, że wskaźnik wskazuje na przypadkowe miejsce, które nie powinno być odczytane ani zapisywane, a próba odczytu lub zapisu da skutek niemożliwy do przewidzenia. A poprawne możliwości są dwie i dostępne we wszystkich trzech językach:

  1. Wskaźnik jest pusty, czyli 0, null, NULL.
  2. Wskaźnik wskazuje obiekt zgodny z typem wskaźnika.

Nie piszę tu o C, bo jest tak samo, jak w C++. Też są wskaźniki, tylko, ze mogą wskazywać tylko na struktury. Stan wskaźnika tak samo może być jeden z trzech, czyli pusty, na strukturę i przypadkowy. Co oczywiste, należy unikać powstawania przypadkowych wskaźników, a tym bardziej prób odwołania się do takowego.

0
zkubinski napisał(a):

ok, dzięki, to co trzeba już rozumiem, zadając to pytanie chciałem się dowiedzieć jak myśleć programując arduino... bo mam tam parę rzeczy do zrobienia

Użyj C++, arduino bazuje na C++.

https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Client.h

Language server łatwo radzi sobie z klasami i namespace, a w takim C musisz pamiętać jak się dane metody nazywają/zaczynają lub je w struktury powkładać, żeby móc korzystać z podpowiedzi składni.

A i wypierdol Arduino IDE, bo jest beznadziejne, jedno threadowa kompilacja, brak lsp i wiele więcej, przy bardzo dużych projektach cały dzień się kompiluje i użyj Platform IO z vscode/neovim.

11

Podaję definicje:

  • programowanie proceduralne: f(x, y)
  • programowanie obiektowe: x.f(y)
  • programowanie funkcyjne: (f x y)
  • metaprogramowanie: f<x, y>()
0

O proszę teraz Arduino, będzie rześko

1 użytkowników online, w tym zalogowanych: 0, gości: 1