| Autor | Správa |
t-pack25
 Užívateľ
 Založený: 11.10.2009 Príspevky: 237 Bydlisko: Kysucké Nové Mesto Vek: 19
 | Zaslal: Ut 03.01.12 16:16 |   |
zdravim,
ucim sa na skusku z programovania, a v prednaskovych prezentaciach je nieco taketo :
celkom nechapem ako sa moze k tym ukazovatelom na premenne pristupovat tak, ako to tam je napisane.
Ani mi to nejde skompilovat.
Podla mna sa musi pole najskor alokovat a potom naplnit, ale aj tak sa nevyhnem pouzitiu fcie strcpy().
Teda takto mi to funguje (nemam presne taku istu strukturu ako je v prezentacii-nechcelo sa mi tolko pisat):
| kód: | #include <stdio.h>
#include <conio.h>
#include <string.h>
int main()
{
struct zakaznik {
char *priezvisko;
char *meno;
int cena_nakupu;
};
struct zakaznik z1;
z1.priezvisko = (char*) malloc(strlen("Mrkvicka") + 1);
if(z1.priezvisko == NULL){
printf ("chyba");
exit (-1);
}
strcpy (z1.priezvisko, "Mrkvicka");
z1.meno = (char*) malloc(strlen("Janko") + 1);
if(z1.meno == NULL){
printf ("chyba");
exit (-1);
}
strcpy (z1.meno, "Janko");
z1.cena_nakupu = 200;
printf("\t%s\n", z1.priezvisko);
printf("%s\n", z1.meno);
printf("%d\n", z1.cena_nakupu);
free (z1.priezvisko);
free (z1.meno);
z1.priezvisko = NULL;
z1.meno = NULL;
getch();
return 0;
} |
Je chyba v prezentacií alebo to ja zle chápem? |
_________________ cpu intel c2q9550, 2.83GHz @ 3.91 GHz gpu asus eah4890 hdti 1GD5 1Gb ddr5 pcx zakl.doska asus p5q e HDD samsung 1Tb sata2 32Mb ram a-data ddr2 4x2Gb 1066+MHz Extreme zdroj fortron everest 600w 80+ skrinka enermax staray blue monitor LG 23" LCD W2343T-PF 2ms FULL HD DVI reproduktory Creative T6100 5.1 | |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Ut 03.01.12 16:45 |   |
V prednaske je chyba, nema tam byt:
| kód: | stitok.priezvisko, "Novotna";
stitok.meno, "Tereza";
... |
ale ma tam byt znak rovna sa:
| kód: | stitok.priezvisko = "Novotna";
stitok.meno = "Tereza";
... |
V tomto zapise ide o to, ze v pamati iba na citanie sa vytvori retazec "Novotna", ktoreho adresa sa iba preda premennej stitok.priezvisko. Ak by si ju chcel neskor modifikovat, napr stitok.priezvisko[0] = 'R', pripadne by si volal strcpy na tuto adresu, dostal by si segmentation fault. |
| |
   |
 |
t-pack25
 Užívateľ
 Založený: 11.10.2009 Príspevky: 237 Bydlisko: Kysucké Nové Mesto Vek: 19
 | Zaslal: Ut 03.01.12 17:10 |   |
Dakujem za objasnenie.
Tak ma napada otazka, je vobec na nieco dobry takyto zapis? (Ked pises, ze retazec je iba na citanie)...alebo lepsie povedane, pouziva sa takyto zapis? (teraz neriesim, ze v praxi by sa pouzili zrejme databazy) |
_________________ cpu intel c2q9550, 2.83GHz @ 3.91 GHz gpu asus eah4890 hdti 1GD5 1Gb ddr5 pcx zakl.doska asus p5q e HDD samsung 1Tb sata2 32Mb ram a-data ddr2 4x2Gb 1066+MHz Extreme zdroj fortron everest 600w 80+ skrinka enermax staray blue monitor LG 23" LCD W2343T-PF 2ms FULL HD DVI reproduktory Creative T6100 5.1 | |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Ut 03.01.12 17:16 |   |
Takto - menit sa sice nemoze, ale len tento konkretny retazec. Premennej stitok.priezvisko mozes kedykolvek priradit iny retazec ( ci uz cez malloc alokovat novu pamat, alebo cez znak = mu pridelit inu adresu s retazcom ). Takze vyuzitie moze mat, ak napriklad potrebujes povedzme nejaku defaultnu hodnotu uz v dobe pisania programu a potom budes potrebovat novu hodnotu retazca. |
| |
   |
 |
marian_r
 Užívateľ
 Založený: 14.03.2011 Príspevky: 253 Bydlisko: Bratislava Vek: 54
 | Zaslal: Ut 03.01.12 18:18 |   |
Nerozumiem aká je výhoda zápisu
| kód: | | z1.priezvisko = (char*) malloc(strlen("Mrkvicka") + 1); |
Alokuješ pamäť presne na KONŠTANTU čo si uviedol.
V tých príkladoch je to normálne, alokuje sa 40 bajtov...
// pridané po 7 minútach od posledného príspevku
| Fico napísal: | | Takto - menit sa sice nemoze, ale len tento konkretny retazec. Premennej stitok.priezvisko mozes kedykolvek priradit iny retazec ( ci uz cez malloc alokovat novu pamat, alebo cez znak = mu pridelit inu adresu s retazcom ). Takze vyuzitie moze mat, ak napriklad potrebujes povedzme nejaku defaultnu hodnotu uz v dobe pisania programu a potom budes potrebovat novu hodnotu retazca. |
No, ak je to alokovaný buffer, aj strcpy by malo zafungovať, nie?
Ak je to pointer, tak sa jeho hodnota prepíše iným pointrom.
? |
| |
    |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Ut 03.01.12 18:24 |   |
| marian_r napísal: | | No, ak je to alokovaný buffer, aj strcpy by malo zafungovať, nie? |
Nie nie, praveze strcpy robi to, ze na adresu, ktora je predana ako prvy parameter zacne zapisovat znaky pocnuc adresou, ktoru predame ako druhy parameter. Ale kedze je tento retazec ulozeny v read-only pamati, program spadne so Segmentation fault ( pretoze sa pokusame zapisovat na nepristupnu pamat ). Skuste si nasledujuci priklad pre ilustraciu:
| kód: | #include <stdio.h>
#include <string.h>
int main()
{
char *text = "Toto je text ulozeny v pamati na citanie";
strcpy( text, "Pokus prepisat konstantny text" );
return 0;
} |
Nasledujuci kod uz ale pojde, pretoze premennej pridelime novu adresu, ktora nie je v read-only sekcii:
| kód: | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *text = "Toto je text ulozeny v pamati na citanie";
text = malloc( 100 );
if ( text != NULL )
{
strcpy( text, "Toto uz je platny zapis, pretoze text ma pridelenu novu adresu" );
printf( "%s\n", text );
}
free( text );
return 0;
} |
|
| |
   |
 |
marian_r
 Užívateľ
 Založený: 14.03.2011 Príspevky: 253 Bydlisko: Bratislava Vek: 54
 | Zaslal: Ut 03.01.12 18:35 |   |
| t-pack25 napísal: |
Podla mna sa musi pole najskor alokovat a potom naplnit, ale aj tak sa nevyhnem pouzitiu fcie strcpy().
|
Lenže tým zápisom s ukazovateľmi JE naalokované. Na ukazovatele a hodnotu ukazovateľa môžeš prepísať inou hodnotou ukazovateľa smerujúceho na iný reťazec.
// pridané po 3 minútach od posledného príspevku
| Fico napísal: | | Nie nie, praveze strcpy robi to, ze na adresu, ktora je predana ako prvy parameter zacne zapisovat znaky pocnuc adresou, ktoru predame ako druhy parameter. |
S tým nemám problém, je mi jasné že nemôže/nemal by zapisovať do alokovanej konštanty.
Ak má alokovanú premennú char[40] tak strcpy
ak má pointer char * tak =
.
Nie? O to išlo v tých ukážkach. |
| |
    |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Ut 03.01.12 18:38 |   |
| marian_r napísal: | Ak má alokovanú premennú char[40] tak strcpy
ak má pointer char * tak =
.
Nie? O to išlo v tých ukážkach. |
Presne tak, len ak mame smernik char*, mozme pouzit aj dynamicku alokaciu pomocou malloc. |
| |
   |
 |
t-pack25
 Užívateľ
 Založený: 11.10.2009 Príspevky: 237 Bydlisko: Kysucké Nové Mesto Vek: 19
 | Zaslal: Ut 03.01.12 21:12 |   |
Vdaka Vam vsetkym, uz tomu rozumiem |
_________________ cpu intel c2q9550, 2.83GHz @ 3.91 GHz gpu asus eah4890 hdti 1GD5 1Gb ddr5 pcx zakl.doska asus p5q e HDD samsung 1Tb sata2 32Mb ram a-data ddr2 4x2Gb 1066+MHz Extreme zdroj fortron everest 600w 80+ skrinka enermax staray blue monitor LG 23" LCD W2343T-PF 2ms FULL HD DVI reproduktory Creative T6100 5.1 | |
   |
 |
|
Nemôžete pridávať nové témy do tohto fóra. Nemôžete odpovedať na témy v tomto fóre. Nemôžete upravovať svoje príspevky v tomto fóre. Nemôžete mazať svoje príspevky v tomto fóre. Nemôžete hlasovať v tomto fóre.
|
|