• 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

+2 głosów
876 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,420 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,730 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,420 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ź 807 wizyt
pytanie zadane 3 listopada 2019 w C i C++ przez Julka_99 Użytkownik (540 p.)
0 głosów
1 odpowiedź 626 wizyt
pytanie zadane 4 czerwca 2019 w C i C++ przez Joe Nowicjusz (200 p.)
0 głosów
1 odpowiedź 1,000 wizyt
pytanie zadane 3 czerwca 2019 w C i C++ przez zaliczenie14 Użytkownik (620 p.)

93,754 zapytań

142,715 odpowiedzi

323,363 komentarzy

63,350 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

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...