Skocz do zawartości

[STM32][C] struktura jako argument funkcji


Pomocna odpowiedź

Napisano

Cześć

Walczę aktualnie walczę ze strukturą jako argument funkcji.

Mam taki kod:

struct mcp_struct {
    uint8_t mcp;
    uint8_t port;
    uint8_t pin;
} wcisnietyPrzycisk;

uint8_t throwButtonNumber(mcp_struct przycisk)
{
	return 0;
}

I otrzymuję błąd: "unknown type name 'mcp_struct'; did you mean 'struct'?" 

Czy mogę prosić o pomoc ?

Nic dziwnego - w funkcji musisz podać typ argumentu, a typem jest w tym przypadku "struct mcp_struct".

Czyli:

uint8_t throwButtonNumber(struct mcp_struct przycisk)

Poza tym pamiętaj, że w tym przypadku "przycisk" będzie przekazany przez wartość (tzn. wewnątrz funkcji zostanie stworzona kopia struktury) i jeśli w funkcji będziesz chciał zmienić coś w tej strukturze - po wyjściu z funkcji te zmiany zostaną zapominane. Lepiej przekazywać takie rzeczy przez wskaźnik, czyli:

uint8_t throwButtonNumber(struct mcp_struct * przycisk)
{
	// tu coś zmieniasz w "przycisk"
  return 0;
}

i wywoływać:

uint8_t wynik = throwButtonNumber(&wcisnietyPrzycisk);

 

  • Pomogłeś! 1
(edytowany)
typedef struct mcp_struct {
    uint8_t mcp;
    uint8_t port;
    uint8_t pin;
};

// lub w zależności od kompilatora

typedef struct{
    uint8_t mcp;
    uint8_t port;
    uint8_t pin;
}mcp_struct;

mcp_struct variable = {0};
uint8_t throwButtonNumber(mcp_struct*);
// int main(){
// 	while(1){

variable.mcp = 1;
throwButtonNumber(&variable);

//	 }
// }
uint8_t throwButtonNumber(mcp_struct *v){
  return v->mcp;
}

wtedy wewnątrz funkcji możesz modyfikować przekazaną strukturę za pomocą ->

Edytowano przez Gość

Warto zauważyć, że struktura to nie to samo co tablica (heh), tj. nazwa struktury nie jest wskaźnikiem do pierwszego elementu tak jak ma to miejsce w przypadku tablicy. Widzę, że wielu początkujących ma z tym kłopot. Definicję struktury trzeba traktować bardziej jak definicję typu.

Przekazywanie parametrów przez wartość ("domyślne" dla struktur) a nie przez wskaźnik ("domyślne" dla tablic) ma jeszcze tę cechę, że paskudnie obciąża procesory. Trzeba mieć dodatkowe miejsce na stosie, zbudować tam ramkę a potem ją posprzątać - to zajmuje i pamięć i czas. Oczywiście czasem tego chcemy (zrobienia kopii i przekazania przez wartość) ale warto wiedzieć co w trawie piszczy i robić to świadomie 🙂 

  • Lubię! 1
  • 1 miesiąc później...

Pojawił się kolejny problem ze strukturą tym razem ze zwracaniem z funkcji. Mam kod :

typedef struct  {
    uint8_t mcp;
    uint8_t port;
    uint8_t mask;

} mcp_out_struct;

mcp_out_struct throwOut(uint8_t out) {
	mcp_out_struct ret;

		ret.mcp = MCP23017_OUT_ADDR;
		ret.port = MCP23017_OUT_ADDR;
		ret.mask = 0;

	return ret;
}

i wywołanie

mcp_out_struct output;

output = throwOut2(2);

 

dostaję błąd:

incompatible types when assigning to type 'mcp_out_struct {aka struct <anonymous>}' from type 'int'

Pomoże ktoś ?

Prawdę mówiąc spodziewałbym się wtedy innego komunikatu o błędzie. Moim zdaniem autor pokazał nam tylko fragment programu i to nie ten, który jest używany podczas kompilacji.

Ale jak wyjaśnimy o co chodzi i z tymi nazwami, to będzie pewnie łatwiej coś doradzić.

  • Lubię! 1
(edytowany)
9 minut temu, Elvis napisał:

Prawdę mówiąc spodziewałbym się wtedy innego komunikatu o błędzie.

Jakiego (serio pytam)? Bo próba skompilowania czegoś takiego:

struct costam {
    int a;
};

int main(void)
{
    struct costam x;
    x=jakasfunkcja(2);
    return 0;
}

skończyła się:

$ gcc -o xxx xxx.c
xxx.c: In function ‘main’:
xxx.c:8:7: warning: implicit declaration of function ‘jakasfunkcja’ [-Wimplicit-function-declaration]
     x=jakasfunkcja(2);
       ^~~~~~~~~~~~
xxx.c:8:6: error: incompatible types when assigning to type ‘struct costam’ from type ‘int’
     x=jakasfunkcja(2);
      ^

czyli w sumie czymś podobnym... a wyświetlanie ostrzeżeń co poniektórzy wyłączają żeby sobie nie psuć humoru 🙂

 

Edytowano przez ethanak
  • Lubię! 1

Spodziewałem się czegoś w rodzaju tego ostrzeżenia.

Ale nie wiem jakich ustawień kompilatora używa autor wątku, w sumie nawet nie wiem jakiego kompilatora używa.

  • Lubię! 1

Dzięki za pomoc, zła nazwa wywoływanej funkcji była spowodowana różnymi próbami uruchomienia programu.

Wydawało mi się że nawet w przypadku prawidłowego wywołania pojawiał się ten błąd ale to pewnie mylne przekonanie 🙂

W między czasie przerobiłem funkcję na działającą na wskaźniku i program ruszył.

Teraz już niestety nie jestem w stanie wrócić do poprzedniej wersji ale za chwilę z ciekawości napiszę sobie ją na nowo żeby sprawdzić.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...