• 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

Object Storage Arubacloud
+2 głosów
407 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,320 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,320 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ź 478 wizyt
pytanie zadane 3 listopada 2019 w C i C++ przez Julka_99 Użytkownik (540 p.)
0 głosów
1 odpowiedź 410 wizyt
pytanie zadane 4 czerwca 2019 w C i C++ przez Joe Nowicjusz (200 p.)
0 głosów
1 odpowiedź 568 wizyt
pytanie zadane 3 czerwca 2019 w C i C++ przez zaliczenie14 Użytkownik (620 p.)

92,605 zapytań

141,451 odpowiedzi

319,743 komentarzy

61,985 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...