HomeMade
Język C - co autor miał na myśli ??? - Wersja do druku

+- HomeMade (http://sp-hm.pl)
+-- Dział: Oprogramowanie (/forum-84.html)
+--- Dział: Technika programowania mikroprocesorów (/forum-85.html)
+--- Wątek: Język C - co autor miał na myśli ??? (/thread-2327.html)



Język C - co autor miał na myśli ??? - SP5FCS - 18-04-2015 17:51

Maja znajomość tego C-iekawego języka jest raczej pobieżna i czasem trudno mi zinterpretować składnię wyszukanych zapisów kodu. Czasem wydaje mi się że to taka maniera programistów: "im bardziej zawiła konstrukcja kodu tym podziw czytających będzie większy".
Może koledzy z większym doświadczeniem pomogą odkryć: "Co autor kodu miał na myśli ?"

Przykład_1 Odwracanie kolejności znaków w tablicy. Pytanie dotyczy kodu instrukcji FOR po incrementacji i++.

Kod:
* odwrócenie stringów
* s = string
void reverse(int8_t s[])
{
int i, j;
char c;

for (i = 0, j = strlen(s)-1; i<j; i++,="" j--)="" {<br=""> c = s[i];
s[i] = s[j];
s[j] = c;
}
}



RE: Język C - co autor miał na myśli ??? - SQ4AVS - 18-04-2015 18:31

Podpytałem się Kolegi i twierdzi, że mogło to być związane z jakimś kodowaniem specjalnym znaków i dlatego jest to tak dziwnie. Na szybko to bardziej typowo tak:
* s = string
void reverse(int8_t s[])
{
int i, j;
char c;

for (i = 0, j = strlen(s)-1; i<j; i++,="" j--)
{
c = s[i]; //do zmiennej tymczasowej podstaw znak z pozycji i (na poczku jest ona równa zero
s[i] = s[j]; //w miejsce znaku z pozycji i podstaw znak z pozycji j(na początku ostatni znak w napisie)
s[j] = c; // w miejsce znaku z pozycji j podstaw tek skopiowany po zmiennej tymczasowej czyli ten co był pod pozycją i
}
}
a teraz przykład:
mamy napis : s = "kotołaki" -> s[0] = k, s[1] = o, itd
pokolei:
i =0, j= długość napisu -1 czyli 8 -1 = 7

c = k;
s[0] = i;
s[7] = k;
iotołakk
i++, j-- : i=1, j=6; 1 nie jest <6

c = o;
s[1] = k;
s[6] = o;
iktołaok
i++, j-- : i=2, j=5

c = t;
s[2] = a;
s[5] = t
ikaołtok
i++, j-- : i=3, j=4; 3 nie jest < 4

c = o;
s[3] = ł;
s[4] = o;
ikałotok;
i++, j-- : i = 4, j = 3; 4 jest < 3 więc mamy warunek kończący pętlę

i to by było na tyle


RE: Język C - co autor miał na myśli ??? - SP5FCS - 18-04-2015 19:11

Rafał sorry ale nie w tym problem. Sam mechanizm odwracania kolejności jest trywialny i nie wymaga komentarza.
Tak jak napisałem problemem jest jedna linia a w zasadzie jej fragment (na czerwono).

for (i = 0, j = strlen(s)-1; i<j; i++,="" j--)="" {<br=""> c = s[i];

Specjalnie podałem link do strony na której jest kurs programowania STM32 z przykładami. To tylko prosty przykład w jakie "maliny" może nas wpędzić demo z netu.

Tu poprawna wersja kodu funkcji revers z GitHUB
I tu wszystko jest jasne jak słońce na niebie.

Kod:
/* reverse: reverse string s in place */
static void reverse(unsigned char s[])
{
int i, j;
unsigned char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}



RE: Język C - co autor miał na myśli ??? - SQ9RFC - 19-04-2015 22:32

A nie są to znaczniki do formatowania tekstu w edytorze?. Przekopiował przy pomocy schowka pomiędzy różnymi edytorami, nie zauważył i zostało ...


RE: Język C - co autor miał na myśli ??? - SP2IPT - 20-04-2015 10:32

Mi to tez wyglada bardziej na rozjechany kod strony niz cudaczny zapis kodu w C.
Znacznik BR jest dosc charakterystyczny Wink


RE: Język C - co autor miał na myśli ??? - SP5FCS - 22-04-2015 10:37

Problem z pierwszym przykładem jest wyjaśniony i zamknięty.
W kodzie pojawiły się przypadkowe znaki, tylko czemu autor kursu tego nie poprawił ?

Przykład_2. Definicja zmiennych pod STM32
Czemu jedne zmienne są deklarowane z __IO a inne bez, jaka jest różnica ?

Kod:
__IO uint16_t CCR1_Val = 54618;
__IO uint16_t CCR2_Val = 27309;
__IO uint16_t CCR3_Val = 13654;
__IO uint16_t CCR4_Val = 6826;
uint16_t PrescalerValue = 0;

Wydawało mi się, że:
__I lotne const // definiuje "tylko do odczytu"
__O lotne // definiuje "tylko do zapisu"
__IO lotne // definiuje do "Odczyt / Zapis"

OK, rozumiem typ __I jako const np. w kodzie programu, tylko do odczytu.
Czy GCC ma typ __O, nie wydaje mi się ?
Czym różni się zwykła zmienna od takiej typu __IO ?

Jakieś wskazówki, literatura do poczytania dla zaczynających zabawę w STM32 ?


RE: Język C - co autor miał na myśli ??? - SQ5KVS - 22-04-2015 11:42

To zależy od kompilatora (czy jest natywny dla danego procesora czy nie). Typy zmiennych można sobie "definiować" samemu w pewnym sensie, czyli zakładać nazwy alternatywne dla podstawowych typów zmiennych , ale też nieco bardziej skomplikowane konstrukcje. Czasem ma to za zadanie po prostu uwidocznienie danej definicji zmiennej że jest do jakiegoś konkretnego celu, a czasem potrafi to uprościć życie. Instrukcja w C/C++ do tego to "typedef".
Przykład prosty to:
Kod:
typedef int points ;
Zdefiniowaliśmy alias dla zmiennej int, który się nazywa "points". Potem można robić:
Kod:
points  punkty;
To takie zastosowanie estetyczne.
Ale można też robić bardziej trudne aliasy, do wskaźników, struktur itp.

Trzeba by poszukać w bibliotekach które Twój kod załącza (jawnie, albo nie jawnie) bo gdzieś w nich jest prawdopodobnie napisane
Kod:
typedef long long _IO
albo coś nieco bardziej skomplikowanego Smile
Natomiast jeśli to jest natywny kompilator, to można tego nie znaleźć, i ten typ zmiennej może być bardziej "sprytny", na przykład mieć gdzieś ograniczenie że jest np "read only" czy coś w tym stylu.


Edit: Znalazłem (chyba to to): biblioteka core_cm3.h
Tam stoi coś takiego:
Kod:
#ifdef __cplusplus
  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
#else
  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
#endif
#define     __O     volatile             /*!< Defines 'write only' permissions                */
#define     __IO    volatile             /*!< Defines 'read / write' permissions              */

/*@} end of group Cortex_M3 */



RE: Język C - co autor miał na myśli ??? - SP5FCS - 23-04-2015 21:57

(22-04-2015 11:42)SQ5KVS napisał(a):  
Kod:
typedef int points ;

Zdefiniowaliśmy alias dla zmiennej int, który się nazywa "points". Potem można robić:

Kod:
points  punkty;

To takie zastosowanie estetyczne.

Karolu, możliwość definiowania nowych typów w języku C nie wymyślono tylko w celach estetycznych. Mechanizm ten pozwala tworzyć rozbudowane struktury danych, nadawać im wygodne nazwy, przekazywać je jako parametry, zapisywać do pliku, odczytywać i przetwarzać w programie.

(22-04-2015 11:42)SQ5KVS napisał(a):  
Kod:
#ifdef __cplusplus
  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
#else
  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
#endif
#define     __O     volatile             /*!< Defines 'write only' permissions                */
#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
/*@} end of group Cortex_M3 */

Trochę to dziwne ale wychodzi na to, że w Cortex-ach __IO i volatile to samo.
Dla mnie czym innym jest zmienna do zapisu i odczytu a czym innym zmienna typu volatile. Zwykła zmienna najczęściej jest do zapisu i odczytu a nie musi być typu volatile.
Wolę klasyczny zapis:

Kod:
uint32_t  zmienna1  //zwykła zmienna odczyt/zapis
volatile uint32_t zmienna2  //zmienna odczyt/zapis ale typu volatile



RE: Język C - co autor miał na myśli ??? - SQ5KVS - 23-04-2015 23:05

(23-04-2015 21:57)SP5FCS napisał(a):  
(22-04-2015 11:42)SQ5KVS napisał(a):  (...)
To takie zastosowanie estetyczne.

Karolu, możliwość definiowania nowych typów w języku C nie wymyślono tylko w celach estetycznych. Mechanizm ten pozwala tworzyć rozbudowane struktury danych, nadawać im wygodne nazwy, przekazywać je jako parametry, zapisywać do pliku, odczytywać i przetwarzać w programie.
Często (zwłaszcza w prostych programach) typedef'u używa sie właśnie w celach "estetycznych" przez co rozumiem nadawanie nowych nazw starym typom wbudowanym, po to aby były bardziej, jakby to powiedzieć, konkretne dla kodującego .
Prosty przykład z winavr gdzie uint8t to po prostu unsigned char.
Nie napisałem jednak ze jest to wyłącznie estetyka , robienie nowych typów wskaznikowych znakomicie łagodzi ból głowy związany ze stosowaniem wskaźników albo wskaźników do funkcji, a juz w C++ niektóre konstrukcje z użyciem szablonów bez typedef powodowały by masowe samobójstwa Wink