• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wskaźnik typu void, konwersja typu

VPS Starter Arubacloud
+2 głosów
381 wizyt
pytanie zadane 26 grudnia 2021 w C i C++ przez Dynamic Bywalec (2,910 p.)

Witam, wspólnie z kolega z naszej grupy na doscodrdzie napisaliśmy funkcje, która dostaje dwie tablice jednakowego typu i je scala, z tym, że nie wiadomo jakie typy dostanie (ma działać dla każdego typu)

Nagłówek funkcji wygląda tak:

void *scalanie(int r, void* tabA, void* tabB, int typ)
{
    char* tab = malloc(r * typ);

    for (size_t i=0, j=0; i<r; ++j)
    {
        if(j==typ)
        {
            j=0;
            ++i;
        }
        tab[i*typ*2+j]=((char*)tabA)[i*typ+j];
        tab[i*typ*2+j+typ]=((char*)tabB)[i*typ+j];
    }
    return tab;
}

Sprawdzałem to dla różnych typów tablic, głosy, double, char i na wszystkich działa, jednak ja nie rozumiem jak. 

Jeżeli funkcja dostaje tablice intow (wskaźnik ) to w jaki sposób jest to zapisane jako tablica char, przecież typ char mieści wartości do 255(?) Gdyby ktoś był tak miły i spróbował mi to wytłumaczyć byłbym wdzięczny 

komentarz 26 grudnia 2021 przez Oscar Nałogowiec (29,290 p.)
Każda, nawet największa zmienna składa się z bajtów, więc kopiowanie bajt/char po bajcie skopiuje dowolną zmienną.

2 odpowiedzi

+1 głos
odpowiedź 27 grudnia 2021 przez Chess Szeryf (76,710 p.)
edycja 27 grudnia 2021 przez Chess
A <-- 255 wskazywacz

[675,245,2666,42] int each

Tablica, start na 0.

char *A = [T+0]; // 675

char *A = [T+4]; // 245

Wskaźnik ma maks. miejsce na adres o wartości 255.

256 jak wskaźnik miałby, wyplułby błąd o przekroczeniu zakresu typu.

Typ int rezerwuje całą dostępną przestrzeń, nawet niewykorzystaną.

0xFFFFFFFF -- 32 bity

Jak program ma liczbę 675, to po x bicie nie zapisuje do pamięci następnych danych, tylko po 32.

Po 32, czyli na 33 miejscu w pamięci zapisuje nowe dane. Ogólnie na 1 miejscu następnej kratki w pamięci. Wskaźnik pokazuje +4 bajty, czyli omija całą dostępną pamięć zarezerwowaną dla typu int, gdybyś zechciał wrzucić większą wartość, której zapisanie jest pojemniejsze.

Nie trzeba się bawić w ręczne ustawianie.

+3, +6, +8, itp., bo to się pisze w assembly, maksymalną wydajność, nie tracąc wolnego miejsca.

//----//

|F|F|F|F|F|F|0|0| => strata jednego bajta, 8 bitów

int rezerwuje 32 bity, więc te wolne 8 zostaje jako stała rezerwacja

|F|F|F|F|F|F| => bez straty, ani jednego bita

int_custom1 = ,{6*4}s,b = 24 bity

int_custom1 [T=875, int T=56];

T == FFFFFF, FFFFFFFF

56 bitów w tablicy, 24 bity jest bezstratnym opracowaniem niestandardowego typu.

Tablica T, pierwszy element jest typem niedomyślnym, ma 3 bajty, 24 bity pojemności. Drugi element jest zwykłym typem int, zawsze 4 bajty, 32 bity pojemności.
0 głosów
odpowiedź 27 grudnia 2021 przez Dynamic Bywalec (2,910 p.)

Napisałem taki programik, żeby sprawdzić, czy dobrze to rozumiem.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int tabA[5]={3000,2,3,4,5};
    void * ptabA = &tabA;
    char * tab = malloc(5*sizeof(tabA));
    for (int i=0; i<20; i++)
    {
        tab[i]=((char*)ptabA)[i];
    }
    for(int i=0; i<20; i++)
    {
        printf("%d", tab[i]);
        printf("\n");
    }
}

1. rezerwuję tablice typu char dla 5 zmiennych typu int.(5*4=20 bajtów).

2. tworzę wskaźnik wskazujący na pierwyszy element tablicy int,

3. przypisuję bajt po bajcie zawartość tabA do tab.

jeśli dobrze zrozumiałem to w pamięci zarezerwowałem 20 bajtów

jeśli chodzi o iterację to na intach tabA[0], tabA[1], tabA[2], tabA[3], tabA[4]

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0|

jeśli chodzi o iterację to na charach tab[0], tab[1], tab[2], tab[3], tab[4]... tab[20]

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0|

mam jednak jeszcze pytanie jak to jest, że w tablicy typu char możliwe jest zapisanie liczb wiekszych niż 255, bo jesli próbuję to zrobić dla zmiennej pojawiają mi się ujemne liczby.

 

1
komentarz 27 grudnia 2021 przez Oscar Nałogowiec (29,290 p.)

W 1. zaallokowałeś 5 razy miejsce na tablice 5 elementową, czyli w sumie na 25 intów, ale "od przybytku głowa nie boli" (ale też "co za dużo to niezdrowo").

malloc(5*sizeof(tabA[0]));

Jeśli nie chcesz bawić się z ujemnymi char-ami użyj unsigned char. Można ustawić w opcjach kompilatora czy char na być signed czy unsigned.

C ogólnie nie sprawdza zakresów liczb (najwyżej kompilator rzuci warning).

komentarz 27 grudnia 2021 przez Dynamic Bywalec (2,910 p.)
Myślałem, że sizeof zwróci ilość bajtów jakie zajmuje TabA[0] czyli to tak samo jakbym wpisał sizeof(int)

Podobne pytania

0 głosów
1 odpowiedź 463 wizyt
pytanie zadane 3 listopada 2019 w C i C++ przez Julka_99 Użytkownik (540 p.)
0 głosów
1 odpowiedź 404 wizyt
pytanie zadane 4 czerwca 2019 w C i C++ przez Joe Nowicjusz (200 p.)
0 głosów
1 odpowiedź 550 wizyt
pytanie zadane 3 czerwca 2019 w C i C++ przez zaliczenie14 Użytkownik (620 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...