Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 6 lut 2025, o 09:39


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 
Autor Wiadomość
PostNapisane: 26 gru 2018, o 12:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

Hej,
mam problem z warningiem, który wyskakuje mi przy kompilacji prostego programu:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Warning wyskakuje w liniach 7, 17, 18, 23 i 24. Ma on związek z przekroczeniem indeksu tablicy uint8_t *wsk[]:
"array 'wsk' assumed to have one element [enabled by default]"
"array subscript is above array bounds [-Warray-bounds]"

Kiedy w deklaracji tablicy w nawiasach kwadratowych wpiszę liczbę 3 (zgodnie z ilością elementów), wtedy warningi znikają.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Rozumiem, że wpisując ilość elementów tablicy, tworzy się już definicja i rezerwuje się pamięć.
Czy w takim razie można bez warningów zadeklarować tablicę, czy trzeba ją od razu definiować?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 12:55 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27354
Lokalizacja: Szczecin
Pomógł: 1042

dayer41 napisał(a):
Rozumiem, że wpisując ilość elementów tablicy, tworzy się już definicja i rezerwuje się pamięć.
Czy w takim razie można bez warningów zadeklarować tablicę, czy trzeba ją od razu definiować?

Źle rozumiesz - tak tworzysz tablicę wskaźników

zrób tak

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


i możesz wtedy posługiwać się wsk tak jak tab

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 13:07 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

Niestety, gdy zrobię tak jak mówisz, wyrzuca mi w tej linijce i to nie warning tylko error:

error: invalid initializer

:shock:



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 13:15 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27354
Lokalizacja: Szczecin
Pomógł: 1042

eeeeh edytowałem, sorki

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 13:24 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

Więc tym razem error wygląda tak:

"invalid type argument of unary '*' (have 'int')"

Mirku, skoro mam zdefiniować tablicę wskaźników w ten sposób bez nawiasów kwadratowych
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

to kompilator sam się skapnie, że ma to być tablica a nie zwykła zmienna wsk?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 13:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

zubik, Twój kod jak najbardziej działa i ten sposób rozumowania też u mnie działa :) Nie bardzo rozumiem rozwiązanie Mirka..

No i pozostaje bez odpowiedzi moje pytanie, czy można na początku programu zadeklarować tablicę wskaźników w ten sposób:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

czy jednak trzeba określić przynajmniej jej wielkość:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 15:37 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

Ogólnie ten mój przykład to tylko przykład skomplikowania sobie programu, ten sam rezultat uzyskałbym pomijając tablicę wskaźników, a potem w pętli głównej zamiast
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

mógłbym posługiwać się
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Jednak chciałem poćwiczyć wskaźniki.

Gdybym jednak zamiast tworzyć tablicę wskaźników stworzył wskaźnik do tablicy (tak jak Mirek pokazał), jak mógłbym poźniej w if'ie odwoływać się tym wskaźnikiem do poszczególnych rekordów tablicy tab?

mirekk36 napisał(a):
zrób tak

Składnia: [ Pobierz ] [ Ukryj ]
język c
uint8_t tab[] = {32, 16, 8};
uint8_t *wsk = tab;
GeSHi


i możesz wtedy posługiwać się wsk tak jak tab


Więc gdybym zrobił tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

to na PORTC trafiłyby adresy poszczególnych rekordów tablicy tab, a nie jej zawartość.
Natomiast tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

nie chce się skompilować, error: invalid type argument of unary '*' (have 'int')



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 19:46 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

dayer41 napisał(a):
mógłbym posługiwać się
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Więc gdybym zrobił tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

to na PORTC trafiłyby adresy poszczególnych rekordów tablicy tab, a nie jej zawartość.

Chyba się nieco pogubiłeś. W takim przypadku wyrażenia tab[0] oraz wsk[0] są sobie równoważne. Można je także zapisać jako *(tab+0) lub *(wsk+0).

Natomiast wyrażenie:
dayer41 napisał(a):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
to błąd, ponieważ próbujesz użyć elementu tablicy o typie uint8_t jako wskaźnika. Zadziałałoby to w przypadku, gdyby zmienna wsk nie była pojedynczym wskaźnikiem, tylko tablicą wskaźników:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Oczywiście zakładam, że to rozważania teoretyczne, bo w realnym programowaniu taki kod nie sensu. Jeśli chcesz w ten (lub podobny) sposób osiągnąć jakiś rzeczywisty cel, to opisz dokładniej problem, wtedy może coś uda się doradzić.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 gru 2018, o 23:23 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

Ok, chyba zalapalem.
Oczywiscie, ze to są tylko rozważania teoretyczne, chcę po prostu poćwiczyć wskaźniki.

Wiec gdybym stworzył wskaźnik na tablicę, a później w if’ie chciałbym powołać się wskaźnikiem na jej drugi element, mogę zrobić np. w ten sposób?
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 gru 2018, o 11:59 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

dayer41 napisał(a):
Wiec gdybym stworzył wskaźnik na tablicę, a później w if’ie chciałbym powołać się wskaźnikiem na jej drugi element, mogę zrobić np. w ten sposób?
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Oczywiście że tak. Alternatywnie można użyć notacji tablicowej (indeksowej), czyli wsk[1].

Na wskaźnikach można również wykonywać operacje arytmetyczne, przypisując im nową wartość (przy założeniu, że nie zostały zadeklarowane jako const):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Wskaźniki są bardzo przydatne, jednak należy zdawać sobie sprawę z pewnych faktów.

Przykładowo:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Podobna sytuacja występuje w przypadku pobrania do wskaźnika adresu pojedynczej zmiennej, a nie adresu tablicy:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 gru 2018, o 10:23 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

andrews napisał(a):
Alternatywnie można użyć notacji tablicowej (indeksowej), czyli wsk[1].

Chyba nie rozumiem jeszcze, dlaczego ta alternatywa działa, a faktycznie działa..
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Co się dzieje powyżej, rozumiem. Skoro jest gwiazdka, to znaczy że do PORTC przypisuję to co jest pod wskaźnikiem, a nie jego adres.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Natomiast powyższego nie mogę zrozumieć. Skoro nie ma gwiazdki, to do PORTC powinien przypisać się adres drugiego elementu wskaźnika na tablicę, a nie to co pod tym wskaźnikiem jest.

Gdzie popełniam błąd myślowy?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 gru 2018, o 11:06 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

dayer41 napisał(a):
Natomiast powyższego nie mogę zrozumieć. Skoro nie ma gwiazdki, to do PORTC powinien przypisać się adres drugiego elementu wskaźnika na tablicę, a nie to co pod tym wskaźnikiem jest.

Gwiazdka jest operatorem dereferencji. W uproszczeniu można przyjąć, że nawiasy kwadratowe są alternatywnym operatorem dereferencji.
Wyrażenie wsk[n] mówi kompilatorowi: do wartości adresu zawartego we wskaźniku wsk dodaj wartość (n*rozmiar_elementu_tablicy_w_bajtach) i spod uzyskanego w ten sposób adresu odczytaj zmienną.

Działa to tak samo, jak w przypadku użycia nazwy tablicy tab[n]. W uproszczeniu można przyjąć, że nazwa tablicy też jest wskaźnikiem na pierwszy jej element, tylko że jest wartością stałą, której nie można zmienić. W przypadku nazwy tablicy nie można tak, jak w przypadku wskaźnika użyć operacji arytmetycznych przypisujących nazwie tablicy inną wartość (np. tab = tab + 1;).


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 gru 2018, o 11:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 13 kwi 2014
Posty: 58
Pomógł: 0

Niezłe uzupełnienie wiedzy z BB, dzięki, poszedł pomógł!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 7 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO