Mam taki problem mam program w języku c i nie wiem jak przekazać tablice do funkcji próbowałem na różne sposoby np takie
double pi[10];
pi(&pi);
void funkcja ( double *pi) {
}
Mam taki problem mam program w języku c i nie wiem jak przekazać tablice do funkcji próbowałem na różne sposoby np takie
double pi[10];
pi(&pi);
void funkcja ( double *pi) {
}
funkcja(pi);
. Poza tym przydałoby się przekazać też rozmiar tej tablicy.
Próbowałem na różne sposoby i za każdym razem wywala takie błędy
poronywanie.c: In function ‘main’:
poronywanie.c:71:23: warning: initialization from incompatible pointer type
double *wynik2 = &wynik;
^
poronywanie.c: At top level:
poronywanie.c:80:11: warning: conflicting types for ‘sortowanie_babelkowe’
void sortowanie_babelkowe(double *tab[],int n)
^
poronywanie.c:72:6: note: previous implicit declaration of ‘sortowanie_babelkowe’ was here
sortowanie_babelkowe(&wynik, 10);
^
/tmp/cc1cx3yC.o: In function `sortowanie_babelkowe':
poronywanie.c:(.text+0x2f7): undefined reference to `swap'
collect2: error: ld returned 1 exit status
Przekaż tablicę tak:
#include<stdio.h>
// albo tak:
// void foo(double tab[], size_t size)
void foo(double *tab, size_t size)
{
printf("Size: %d\n", size);
}
int main()
{
double numbers[] = { 1,2,3 };
foo(numbers, sizeof(numbers) / sizeof(numbers[0]));
return 0;
}
Tablicy nie trzeba przekazywać przez wskaźnik, bo przekazując tablicę do funkcji przekazujesz oryginał, a nie kopię. Wyobraź sobie co by się musiało dziać kiedy trzeba byłoby przekazywać kopię wielkiej tablicy. To byłoby bez sensu przecież. Modyfikując tablicę wewnątrz funkcji działasz na oryginalnych danych. Poczytaj o przekazywaniu argumentów przez wskaźnik oraz przez wartość. Zresztą w linku, który Ci podałem jest wszystko opisane.
Nadal wywala mi takie błędy
może dam cały kod
int main()
{
char *tablica[10];
tablica[0] = "to";
tablica[1] = "ja";
tablica[2] = "t";
tablica[3] = "po";
tablica[4] = "t2";
tablica[5] = "t";
tablica[6] = "me";
tablica[7] = "pi";
tablica[8] = "p";
tablica[9] = "a";
char pierwszy[100];
printf("Podaj");
scanf("%s",pierwszy);
int i;
double wynik[20];
for (i =0;i <= 10;i++) {
wynik[i] = tablica[i];
}
//double *wynik2 = &wynik;
sortowanie_babelkowe(wynik, sizeof(wynik) / sizeof(wynik[0]), 10);
printf("%f",wynik[0]);
return 0;
}
void sortowanie_babelkowe(double *tab,int n)
{ int i,j;
for( i=0;i<n;i++)
for(j=1;j<n-i;j++) //pętla wewnętrzna
if(tab[j-1]>tab[j])
//zamiana miejscami
swap(tab[j-1], tab[j]);
}
i WYWALA MI TAKIE BŁĘDY
poronywanie.c:80:11: warning: conflicting types for ‘sortowanie_babelkowe’
void sortowanie_babelkowe(double *tab,int n)
^
poronywanie.c:72:6: note: previous implicit declaration of ‘sortowanie_babelkowe’ was here
sortowanie_babelkowe(wynik, sizeof(wynik) / sizeof(wynik[0]), 10);
^
/tmp/cc4uCqxa.o: In function `sortowanie_babelkowe':
poronywanie.c:(.text+0x303): undefined reference to `swap'
collect2: error: ld returned 1 exit status
swap
?#include<stdio.h>
?main
nic nie wie o funkcji sortowanie_babelkowe
. Przenieś definicję powyżej main
lub zapisz tam prototyp funkcji sortowanie_babelkowe
;for (i =0;i <= 10;i++)
wychodzisz poza granicę dziesięcioelementowej tablicy; o jedeną iterację za dużo;To tak na pierwszy rzut oka.
Nie możesz pisać w C tak jakbyś pisał w PHP. To są dwa zupełnie różne języki, a podobieństwa są czysto składniowe.
@pol90 dajmy na to:
#include<stdio.h>
void swap(int tab[], size_t i, size_t j)
{
int temp = tab[i];
tab[i] = tab[j];
tab[j] = temp;
}
// z pamięci pisane.
void sort(int tab[], size_t size)
{
size_t i = 0;
for (; i < size; ++i)
{
size_t j = 0;
for (; j < i; ++j)
{
if (tab[i] < tab[j])
{
swap(tab, i, j);
}
}
}
}
void show(int tab[], size_t size)
{
size_t i = 0;
for (; i < size; ++i)
{
printf("%d, ", tab[i]);
}
putchar('\n');
}
int main()
{
int numbers[] = { 3, 2, 7, 4, 1, -4, 3, 1 };
size_t size = sizeof(numbers) / sizeof(numbers[0]);
sort(numbers, size);
show(numbers, size);
return 0;
}
wynik[i] = tablica[i];
Mieszasz typy danych – wynik
zawiera liczby zmiennoprzecinkowe, a tablica
ciągi znaków.
Działa mi taki kod
#include<stdio.h>
#include<string.h>
double porownaj(const char* pierwszy, const char* drugi) {
if (pierwszy != NULL && drugi != NULL)
{
int ilosc_znakow_pierwszego = strlen(pierwszy);
int ilosc_znakow_drugiego = strlen(drugi);
int prawidlowa = 0;
int ilosc_znakow_najwiekszego_stringa = 0;
if (ilosc_znakow_pierwszego > ilosc_znakow_drugiego)
ilosc_znakow_najwiekszego_stringa = ilosc_znakow_pierwszego;
else
ilosc_znakow_najwiekszego_stringa = ilosc_znakow_drugiego;
int i;
for (i =0; i < ilosc_znakow_najwiekszego_stringa; ++i)
{
if (pierwszy[i] == '\0' || drugi[i] == '\0')
break;
if (pierwszy[i] != drugi[i]) --prawidlowa;
else if (pierwszy[i] == drugi[i]) ++prawidlowa;
}
double wynik = (ilosc_znakow_pierwszego + ilosc_znakow_drugiego) / 2.0;
double finalny_wynik = prawidlowa / wynik;
return finalny_wynik;
}
return -1;
}
double sortowanie_babelkowe(double *tab,int n)
{ int i,j;
double tym;
for( i=0;i>n;i++) {
for(j=1;j>n-i;j++) {//pętla wewnętrzna
if(tab[j+1]<tab[j]) {
//zamiana miejscami
//swap(tab[j-1], tab[j]);
tym = tab[j+1];
tab[j+1] = tab[j];
tab[j] = tym;
}
printf("%f\n",tab[j]);
}
}
printf("\n\n");
for( i=0;i<n;i++) {
printf("%f\n",tab[i]);
}
//printf("\n\n");
return tab[0];
}
int main()
{
char *tablica[10];
tablica[0] = "to";
tablica[1] = "ja";
tablica[2] = "to";
tablica[3] = "po";
tablica[4] = "ti";
tablica[5] = "y";
tablica[6] = "mo";
tablica[7] = "m";
tablica[8] = "e";
tablica[9] = "w";
char pierwszy[100];
char drugi[100];
printf("Podaj pierwszy napis");
scanf("%s",pierwszy);
//printf("Podaj drugi napis");
//scanf("%s",drugi);
int i;
double wynik[20],wynik2;
for (i =0;i <= 10;i++) {
wynik[i] = porownaj(pierwszy, tablica[i]);
//printf("%f\n",wynik[i]);
}
//double *wynik2 = &wynik;
wynik2 = sortowanie_babelkowe(wynik, 10);
printf("%f",wynik2);
return 0;
}
Tylko
#include<stdio.h>
#include<string.h>
double porownaj(const char* pierwszy, const char* drugi) {
if (pierwszy != NULL && drugi != NULL)
{
int ilosc_znakow_pierwszego = strlen(pierwszy);
int ilosc_znakow_drugiego = strlen(drugi);
int prawidlowa = 0;
int ilosc_znakow_najwiekszego_stringa = 0;
if (ilosc_znakow_pierwszego > ilosc_znakow_drugiego)
ilosc_znakow_najwiekszego_stringa = ilosc_znakow_pierwszego;
else
ilosc_znakow_najwiekszego_stringa = ilosc_znakow_drugiego;
int i;
for (i =0; i < ilosc_znakow_najwiekszego_stringa; ++i)
{
if (pierwszy[i] == '\0' || drugi[i] == '\0')
break;
if (pierwszy[i] != drugi[i]) --prawidlowa;
else if (pierwszy[i] == drugi[i]) ++prawidlowa;
}
double wynik = (ilosc_znakow_pierwszego + ilosc_znakow_drugiego) / 2.0;
double finalny_wynik = prawidlowa / wynik;
return finalny_wynik;
}
return -1;
}
double sortowanie_babelkowe(double *tab,int n)
{ int i,j;
double tym;
for( i=0;i>n;i++) {
for(j=1;j>n-i;j++) {//pętla wewnętrzna
if(tab[j+1]<tab[j]) {
//zamiana miejscami
//swap(tab[j-1], tab[j]);
tym = tab[j+1];
tab[j+1] = tab[j];
tab[j] = tym;
}
printf("%f\n",tab[j]);
}
}
printf("\n\n");
for( i=0;i<n;i++) {
printf("%f\n",tab[i]);
}
//printf("\n\n");
return tab[0];
}
int main()
{
char *tablica[10];
tablica[0] = "to";
tablica[1] = "ja";
tablica[2] = "to";
tablica[3] = "po";
tablica[4] = "ti";
tablica[5] = "y";
tablica[6] = "mo";
tablica[7] = "m";
tablica[8] = "e";
tablica[9] = "w";
char pierwszy[100];
char drugi[100];
printf("Podaj pierwszy napis");
scanf("%s",pierwszy);
//printf("Podaj drugi napis");
//scanf("%s",drugi);
int i;
double wynik[20],wynik2;
for (i =0;i <= 10;i++) {
wynik[i] = porownaj(pierwszy, tablica[i]);
//printf("%f\n",wynik[i]);
}
//double *wynik2 = &wynik;
wynik2 = sortowanie_babelkowe(wynik, 10);
printf("%f",wynik2);
return 0;
}
Tylko, że on nie sortuje dobrze wartości z tablicy i druga sprawa jak przekazać do funkcji tablicę wielowymiarową, a inaczej jak zadeklarować tablicę w c, która pierwszy typ danych to są liczby zmiennoprzecinkowe a drugi to stringi ?
for (i =0;i <= 10;i++) {
Tą pętlą wychodzisz poza zakres tablicy tablica
.
W zmiennej trzymasz dziesięcio-elementową tablicę o indeksach 0, 1, 2, ..., 9
, podczas gdy Ty próbujesz się odwołać do 10
.
@pol90: co chcesz osiągnąć? Posortować alfabetycznie tablicę tablica[10]
? Nazwij problem, bo nie wiem co chcesz uzyskać? Strasznie zagmatwany jest Twój kod.
Tylko, że on nie sortuje dobrze wartości z tablicy i druga sprawa jak przekazać do funkcji tablicę wielowymiarową, a inaczej jak zadeklarować tablicę w c, która pierwszy typ danych to są liczby zmiennoprzecinkowe a drugi to stringi ?
Nie możesz mieć w C dwóch wymiarów gdzie w jednym przechowujesz liczbę, a w drugim co innego. Masz tutaj silne typowanie i musisz trzymać się sztywnych zasad (i na szczęście).
Zastosuj tablicę struktur:
#include<stdio.h>
struct wiersz
{
double liczba;
char zdanie[100];
};
int main()
{
struct wiersz tablica[] =
{
{ 12.0, "grzesiek" },
{ 5.5, "kamil" },
{ 7.0, "zosia" }
};
size_t i = 0;
size_t rozmiar = sizeof(tablica) / sizeof(tablica[0]);
for (; i < rozmiar; ++i)
{
printf("Liczba: %.2f\nZdanie: %s\n\n", tablica[i].liczba, tablica[i].zdanie);
}
return 0;
}
Dobra z tym już sobie poradziłem, teraz mi nie wychodzi przekazywanie struktury do funkcji próbowałem takim sposobem
wynik2 = sortowanie_babelkowe(tablica2, rozmiar);
Ale zwraca mi taki błąd.
poronywanie.c:127:36: warning: passing argument 1 of ‘sortowanie_babelkowe’ from incompatible pointer type
wynik2 = sortowanie_babelkowe(tablica2, rozmiar);
^
poronywanie.c:47:18: note: expected ‘double *’ but argument is of type ‘struct wiersz *’
double sortowanie_babelkowe(double *tab,int n)
#include<stdio.h>
#include<string.h>
struct wiersz
{
double liczba;
char napis[100];
};
double porownaj(const char* pierwszy, const char* drugi) {
if (pierwszy != NULL && drugi != NULL)
{
int ilosc_znakow_pierwszego = strlen(pierwszy);
int ilosc_znakow_drugiego = strlen(drugi);
int prawidlowa = 0;
int ilosc_znakow_najwiekszego_stringa = 0;
if (ilosc_znakow_pierwszego > ilosc_znakow_drugiego)
ilosc_znakow_najwiekszego_stringa = ilosc_znakow_pierwszego;
else
ilosc_znakow_najwiekszego_stringa = ilosc_znakow_drugiego;
int i;
for (i =0; i < ilosc_znakow_najwiekszego_stringa; ++i)
{
if (pierwszy[i] == '\0' || drugi[i] == '\0')
break;
if (pierwszy[i] != drugi[i]) --prawidlowa;
else if (pierwszy[i] == drugi[i]) ++prawidlowa;
}
double wynik = (ilosc_znakow_pierwszego + ilosc_znakow_drugiego) / 2.0;
double finalny_wynik = prawidlowa / wynik;
return finalny_wynik;
}
return -1;
}
double sortowanie_babelkowe(double *tab,int n)
{ int i,j;
double tym;
for( i=0;i>n;i++) {
for(j=1;j>n-i;j++) {//pętla wewnętrzna
if(tab[j+1]<tab[j]) {
//zamiana miejscami
//swap(tab[j-1], tab[j]);
tym = tab[j+1];
tab[j+1] = tab[j];
tab[j] = tym;
}
printf("%f\n",tab[j]);
}
}
printf("\n\n");
for( i=0;i<n;i++) {
printf("%f\n",tab[i]);
}
//printf("\n\n");
return tab[0];
}
int main()
{
struct wiersz tablica2[] =
{
{ 0.0, "grzesiek" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "zosia" }
};
//size_t i = 0;
size_t rozmiar = sizeof(tablica2) / sizeof(tablica2[0]);
int i;
//for (i = 0;i < rozmiar;i++) {
//tablica2[i].liczba = 2.00;
//}
char pierwszy[100];
char drugi[100];
printf("Podaj pierwszy napis");
scanf("%s",pierwszy);
//printf("Podaj drugi napis");
//scanf("%s",drugi);
//int i;
double wynik[20],wynik2;
for (i =0;i < rozmiar ;i++) {
tablica2[i].liczba = porownaj(pierwszy, tablica2[i].napis);
//printf("%f",tablica2[i].liczba);
//printf("%f\n",wynik[i]);
}
//double *wynik2 = &wynik;
wynik2 = sortowanie_babelkowe(tablica2, rozmiar);
//printf("%f",wynik2);
return 0;
}
Nie działa, bo chcesz przekazać do funkcji typ double*
zamiast struct wiersz[]
. Nie możesz od tak sobie mieszać typów w C. Tutaj są sztywne zasady w postaci silnego typowania i musisz ich przestrzegać. Nie możesz np. wsadzić jako argument funkcji obiektu typu double
kiedy ta oczekuje argumentu typu char*
Zmień sygnaturę na double sortowanie_babelkowe(struct wiersz tab[], int n)
oraz zmień ciało funkcji w taki sposób żeby korzystało w elementów struktury wiersz
.
Poza tym nie wiem czemu funkcja sortująca ma coś zwracać ale to już swoją drogą.
@pol90: patrz:
#include<stdio.h>
struct row
{
int id;
char text[200];
};
void show(struct row rows[], size_t size)
{
for (size_t i = 0; i < size; ++i)
{
printf("Id: %d, Text: %s\n", rows[i].id, rows[i].text);
}
}
int main()
{
struct row records[] =
{
{ 1, "Grzesiek" },
{ 2, "Tomasz" },
};
size_t size = sizeof(records) / sizeof(records[0]);
show(records, size);
return 0;
}
No teraz wszystko dobrze działa, ale coś to sortowanie bąbelkowe źle działa nie sortuje tak jak trzeba.
! elementem struktury jest grzesiek
grzesiek
1.000000
-0.769231
-0.769231
-0.769231
-0.769231
-0.769231
-0.769231
-0.769231
-0.769231
-0.769231
To mi zwraca dobrze bo grzesiek jest na 1 miejscu, ale jak wpiszę, ale jak wpisze kamil to mi zwraca
kamil
-0.769231
1.000000
1.000000
1.000000
1.000000
1.000000
1.000000
1.000000
1.000000
-0.600000
Czyli jak gdyby w ogóle ich nie sortował.
Dam ci kod tej funkcji
double sortowanie_babelkowe(struct wiersz tab[],int n)
{ int i,j;
double tym;
for( i=0;i>n;i++) {
for(j=1;j>n-i;j++) {//pętla wewnętrzna
if(tab[j+1].liczba<tab[j].liczba) {
//zamiana miejscami
//swap(tab[j-1], tab[j]);
tym = tab[j+1].liczba;
tab[j+1].liczba = tab[j].liczba;
tab[j].liczba = tym;
}
printf("%f\n",tab[j].liczba);
}
}
printf("\n\n");
for( i=0;i<n;i++) {
printf("%f\n",tab[i].liczba);
}
//printf("\n\n");
return tab[0].liczba;
}
Sęk w tym, że przestawiasz tylko liczby. Napisy są w dalszym ciągu na swoim miejscu. Nie zamieniasz miejscami całych komórek.
Tak
struct wiersz tablica2[] =
{
{ 0.0, "grzesiek" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "kamil" },
{ 0.0, "zosia" }
};
Sortuje nieprawidłowo, bo w pętlach for
są nieprawidłowe warunki. W obu pętlach znaki nierówności są w złą stronę.
void sortuj(struct wiersz tab[], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 1; j < n - 1; j++)
{
if (tab[j + 1].liczba < tab[j].liczba) {
double tym = tab[j + 1].liczba;
tab[j + 1].liczba = tab[j].liczba;
tab[j].liczba = tym;
}
}
}
printf("\n\n");
for (int i = 0; i < n; i++) {
printf("%f\n", tab[i].liczba);
}
}
Zmieniłem warunki i to samo już wcześniej kombinował z tymi warunkami.
"Pacz": https://ideone.com/MiZ2ly
Przecież to Twój kod, tylko ciutes przerobiony, i sortowanie działa.
Teraz właśnie zauważyłem, że sortuje dobrze, ale jak wpisze grzesiek to sortuje liczby od największej, ale jak wpisze kamil to sortuje od najmniejszej.
Bo ten algorytm sortowania coś mi śmierdzi. Popatrz czy jest prawidłowy. Porównaj z jakimś sortowaniem bąbelkowym w necie, bo ja już dostają oczopląsu przez pracowe jQuery i nawet tak prostych rzeczy nie widzę. :)
@pol90: No:
void sortuj(struct wiersz tab[], int n)
{
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n - i - 1; ++j)
{
if (tab[j].liczba > tab[j + 1].liczba) {
double tym = tab[j].liczba;
tab[j].liczba = tab[j + 1].liczba;
tab[j + 1].liczba = tym;
}
}
}
printf("\n\n");
for (int i = 0; i < n; i++) {
printf("%f\n", tab[i].liczba);
}
}
Ale już ślepy jestem ;)
Tak zmieniłem i teraz działa dobrze
double sortowanie_babelkowe(struct wiersz tab[],int n)
{ int i,j;
double tym;
for( i=0;i<n;i++) {
for(j=1;j<n-i;j++) {//pętla wewnętrzna
if(tab[j-1].liczba<tab[j].liczba) {
//zamiana miejscami
//swap(tab[j-1], tab[j]);
tym = tab[j-1].liczba;
tab[j-1].liczba = tab[j].liczba;
tab[j].liczba = tym;
}
//printf("%f\n",tab[j].liczba);
}
}
printf("\n\n");
for( i=0;i<n;i++) {
// printf("%f\n",tab[i].liczba);
}
//printf("\n\n");
return tab[0].liczba;
}
Teraz mam drugi problem próbuje zwrócić string w tej funkcji, ale jest następujący komunikat
const char * sortowanie_babelkowe(struct wiersz tab[],int n)
{ int i,j;
double tym;
char napis[100];
for( i=0;i<n;i++) {
for(j=1;j<n-i;j++) {//pętla wewnętrzna
if(tab[j-1].liczba<tab[j].liczba) {
//zamiana miejscami
//swap(tab[j-1], tab[j]);
tym = tab[j-1].liczba;
tab[j-1].liczba = tab[j].liczba;
tab[j].liczba = tym;
napis = tab[j-1].napis;
tab[j-1].napis = tab[j].napis;
tab[j].napis = napis;
}
//printf("%f\n",tab[j].liczba);
}
}
printf("\n\n");
for( i=0;i<n;i++) {
// printf("%f\n",tab[i].liczba);
}
//printf("\n\n");
return tab[0].napis;
}
Komunikat
poronywanie.c:59:11: error: assignment to expression with array type
napis = tab[j-1].napis;
^
poronywanie.c:60:20: error: assignment to expression with array type
tab[j-1].napis = tab[j].napis;
^
poronywanie.c:61:18: error: assignment to expression with array type
tab[j].napis = napis;
^
No i widzisz, jako że masz tutaj język, w którym nie ma jako takich stringów to wszystko musisz robić za pomocą odpowiednich funkcji bibliotecznych. Musisz skopiować jedną tablicę do drugiej: