Operacje na tablicach

Operacje na tablicach
JW
  • Rejestracja:prawie 4 lata
  • Ostatnio:prawie 2 lata
  • Postów:34
0

Cześć. Dzisiaj pisałem kolokwium, niestety nie zdałem bo program nie działa :) Większość funkcji działa tak jak powinna ale jednak coś jest nie tak. Polecenie:
Napisz program, który uzupełni tablicę liczbami całkowitymi z zakresu od -15 do 10. Rozmiar tablicy ma być wprowadzony przez użytkownika i nie może być mniejszy niż 15 i nie większy niż 25. Elementy tablicy mają być w ten sposób wyświetlone, że pierwsza połowa będzie zawierać liczby pseudolosowe zwiększone o wartość 5 i posortowane malejąco, zaś druga będzie zawierać elementy ciągu arytmetycznego. Pierwszy element ciągu arytmetycznego ma być losowany z zakresu od -15 do 10, a jego różnica ma być podawana przez użytkownika.

Funkcji sprawdzającej czy rozmiar jest dobry jeszcze nie napisałem bo chciałem sprawdzić czy wszystkie główne funkcje działają. Wszystkie działają oprócz sortowania pierwszej połowy tablicy (czasami działa, czasami nie) ale kiedy wprowadzam rozmiar tablicy większy niż 12 to wyświetla mi mniej elementów albo w ogóle ich nie wyświetla (Nie mam pojęcia dlaczego). Podpowiecie co robię źle? Dzięki :)

Kopiuj
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
void uzupelnij_tablice (char *tab, int *rozmiar)
{
    srand(time(NULL));
    for(int i=0; i < *rozmiar; i++)
        tab[i]=-15 + rand()%26;
}
void wyswietl_tablice (char *tab, int *rozmiar)
{
    int i;
    for(i=0; i < *rozmiar; i++)
        printf("A[%d] = %d\n",i,tab[i]);
}
void swap (int *first, int *second)
{
    int schowek = *first;
    *first = *second;
    *second = schowek;
    return;
}
void pierwsza_polowa_plus_5 (char *tab, int *rozmiar)
{
    int srodek = *rozmiar/2;
    for(int i=0; i <= srodek-1; i++)
        tab[i]=tab[i]+5;
}
void sortuj_pierwsza_polowa (char *tab, int *rozmiar)
{
    for(int i=1;i<*rozmiar/2;i++)
    {
        int max=i-1;
        for(int j=i; j<*rozmiar/2 ; j++)
            if(tab[max]<tab[j])
                max=j;
        swap(&tab[i-1], &tab[max]);
    }
}
void arytmatyczny_druga_polowa(char *tab, int *rozmiar)
{
    srand(time(NULL));
    int i,r,a;
    a = -15+rand()%26;
    printf("Podaj roznice ciagu arytmetycznego = ");
    scanf("%d",&r);
    for(i=*rozmiar/2; i<=*rozmiar; i++)
    {
        a=a+r;
        tab[i]=a;
    }
}
int main()
{
    int size;
    char tablica[size];
    printf("Podaj rozmiar tablicy = ");
    scanf("%d",&size);
    uzupelnij_tablice(tablica,&size);
    printf("Wylosowana tablica :\n");
    wyswietl_tablice(tablica,&size);
    pierwsza_polowa_plus_5(tablica,&size);
    sortuj_pierwsza_polowa(tablica,&size);
    arytmatyczny_druga_polowa(tablica,&size);
    printf("tablica po zmianach :\n");
    wyswietl_tablice(tablica,&size);

    return 0;
}
edytowany 2x, ostatnio: Jakub Wrona
_13th_Dragon
Tablica char dla liczb, wariactwo? Po kiego size przekazujesz przez wskaźnik?
_13th_Dragon
int size; char tablica[size]; scanf("%d",&size); - może jednak poświęć trochę czasu na przeczytanie podstaw, bo z przykładów się nie uczysz.
RE
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 2 godziny
2

nie mam czasu teraz(może później) ale:
to jest przy kompilacji

main.c: In function ‘sortuj_pierwsza_polowa’:
main.c:39:14: warning: passing argument 1 of ‘swap’ from incompatible pointer type [-Wincompatible-pointer-types]
39 | swap(&tab[i-1], &tab[max]);
| ^~~~~~~~~
| |
| char *
main.c:18:17: note: expected ‘int *’ but argument is of type ‘char *’
18 | void swap (int *first, int *second)
| ~~~~~^~~~~
main.c:39:25: warning: passing argument 2 of ‘swap’ from incompatible pointer type [-Wincompatible-pointer-types]
39 | swap(&tab[i-1], &tab[max]);
| ^~~~~~~~~
| |
| char *
main.c:18:29: note: expected ‘int *’ but argument is of type ‘char *’
18 | void swap (int *first, int *second)
| ~~~~~^~~~~~

Kopiuj
    int size;
    char tablica[size];

zakładam że chciałeś mieć rozmiar tablicy w runtime, coś mnie przekonuje mnie to. No i te wysyłanie size za pomocą wskaźnika.


We are the 4p. Existence, as you know it, is over. We will add your biological and technological distinctiveness to our own. Resistance is futile
edytowany 1x, ostatnio: revcorey
JW
Jeśli chodzi o wysyłanie size za pomocą wskaźnika to tak nas uczyli i na kolosie program miał być napisany funkcjami i zawierać wskaźniki. A jeśli chodzi o int size; char tablica[size]; to jak to można zastąpić, żeby nie było w runtime?
ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
3

debuger w ręce i tyle, nikt tego nie zrobi za ciebie

Z pomniejszych: dlaczego argumenty rozmiar przez int *, jeśli to proste przekazanie liczby, bez jej zmiany?
Ja bym sortowanie zrobił jedno, i tylko "zasilał" funkcję sotrujacą wybranymi odcinkami tablicy. Akurat ta wada (błędogenny ficzer jezyka) C tu ma szansę być zastosowana pozytywnie.

czyli

Kopiuj
void sortu_drugą_polowe(tab ... )
{
    sortuj_generyczne( tab + n/2, n/2 (plus minus jeden) )
}

W sortowaniu tablicę traktujesz od jedynki, w innym od zera. Nie wiem, słusznie czy nie - ja w tym nie umiem wyczytać, jaki wzorzec sortowania ma to robić.
Mając jedno SORTOWANIE, masz (w razie błędu) ten błąd wyrazistszy, wiesz co poprawiasz itd...


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
edytowany 1x, ostatnio: ZrobieDobrze
Zobacz pozostałe 3 komentarze
ZD
@enedil: na momet pisania nie miałem świadomości, jaka sieczka z tym kodem (nie kompilowałem)
ZD
@Jakub Wrona: Re: "i znając życie ma jakieś drobne błędy", no nie, popi... pointery to gwarancja katastrofy wcześniej czy PÓŹNIEJ
ZD
@Jakub Wrona: żebyś ty wiedział, ile prostututek pada w sytuacji "tym bardziej ze program jest prawie napisany "
enedil
@ZrobieDobrze: jak nie wiesz czy jest jakieś UB to najpewniej jest, więc zaczynanie od debuggera jest raczej głupie.
ZD
@enedil: na pomylonym typie pointera debuger ślczinie pokaże podbną do ludzi wartośc na pierwszej pozycji (niekoniecznie identyczną) i zupełnie fikcyjne następne. Ale tak, prawda, najpierw czysta kompilacja "programu prawie gotowego"
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:mniej niż minuta
6
Kopiuj
int main()
{
    int size;
    char tablica[size];

To jest UB jak nic! W końcu wartośći size nie jest zdefiniowana w momencie deklaracji tablicy VLA.

Na dodatek to warning wykrywa poważny błą ze wskaźnikami https://godbolt.org/z/7TPTG4Mnb :

Kopiuj
<source>: In function 'sortuj_pierwsza_polowa':
<source>:42:14: error: passing argument 1 of 'swap' from incompatible pointer type [-Werror=incompatible-pointer-types]
   42 |         swap(&tab[i-1], &tab[max]);
      |              ^~~~~~~~~
      |              |
      |              char *
<source>:19:17: note: expected 'int *' but argument is of type 'char *'
   19 | void swap (int *first, int *second)
      |            ~~~~~^~~~~
<source>:42:25: error: passing argument 2 of 'swap' from incompatible pointer type [-Werror=incompatible-pointer-types]
   42 |         swap(&tab[i-1], &tab[max]);
      |                         ^~~~~~~~~
      |                         |
      |                         char *
<source>:19:29: note: expected 'int *' but argument is of type 'char *'
   19 | void swap (int *first, int *second)

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
BG
  • Rejestracja:prawie 6 lat
  • Ostatnio:dzień
  • Postów:289
1
Kopiuj
    int size;
    char tablica[size];

To jest niepoprawne, wartość zmiennej size nie jest znana w momencie deklaracji tablicy.
Skoro size zgodnie z założeniami nie przekroczy 25, to po prostu stwórz tablicę 25-elementową i wykorzystuj tylko jej fragment.

Dlaczego zadeklarowałeś tablicę jako char skoro planujesz przechowywać w niej liczby ? Przy 25 elementach oszczędność pamięci jest pomijalnie mała, a niepotrzebnie zaciemniasz kod.

Kopiuj
srand(time(NULL));

Tej konstrukcji używasz tylko raz na początku działania programu. Zanotuj sobie - raz, na początku funkcji main() i nigdy więcej. Jak zdobędziez troszkę doświadczenia to dowiesz się kiedy możesz chcieć użyć srand wielokrotnie.

A tak na koniec...

Jeśli tablica ma 15 elementów, to ile elementów ma jej pierwsza połowa ?

JW
No właśnie z tą połową z 15 się zastanawiałem jak to ma być zrobione skoro liczba jest nieparzysta XD
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:mniej niż minuta
2

Po poprawkach z budowaniem jest buffer overflow: https://godbolt.org/z/nh9enbYEb
Bo warunek pętli jest zły.naprawionde na głupa.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22
KS
  • Rejestracja:prawie 4 lata
  • Ostatnio:około godziny
  • Postów:594
2

Wszyscy już dużo popisali ale powiem Ci, jasne masz niby przedział mały ale jednak jak bym miał liczby całkowite do umieszczenia w tablicy, nawet małe
To bym zrobił
int tab[ xxx ];

W porywach int8_t

edytowany 1x, ostatnio: ksh
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)