Toon posts:

[C] functies

Pagina: 1
Acties:

Verwijderd

Topicstarter
Is het ook mogelijk om een string als return waarde te geven bij een functie?
want overal zie ik alleen maar integers die worden teruggegeven..
Maar eigenlijk wil ik een functie die zo werkt:

char s[10];

s = functie();


Kan dat?

Verwijderd

ja

edit:
een handige website voor dit soort dingen is Google
en de bibliotheek en/of boekenwinkel wil ook weleens helpen

[ Voor 132% gewijzigd door Verwijderd op 07-05-2003 17:41 ]


Verwijderd

ja, volgens mij kan dat gewoon. Ik zal eens kijken of ik zo snel een voorbeeltje kan vinden.

edit:
je kunt het natuurlijk ook gewoon uitproberen in C ;)

[ Voor 124% gewijzigd door Verwijderd op 07-05-2003 17:42 ]


  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 08-06 11:02
char * functie(void);
is dan de declaratie van die functie om een string terug te geven

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Verwijderd

voorbeelde ;):
C:
1
2
3
4
5
6
7
8
9
10
11
char *dagnaam(int n){
    static char *naam[] =
    { "zondag", "maandag", "dinsdag", "woensdag", 
        "donderdag", "vrijdag", "zaterdag", 
        "nietbestaande dag" };

    if (n<0 || n > 6)
        return (naam[7]);
    else
        return (naam[n]);
}

  • windancer
  • Registratie: Maart 2000
  • Laatst online: 18-08 22:36
Wat moet de functie precies doen ?

Je zult de functie dan altijd een char* moeten laten retourneren en je kunt dan kiezen om geheugen te reseveren in de functie zelf, of om een pointer te retourneren naar een stuk statisch geheugen.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdlib.h>

char* functie1()
{
   char* r = NULL;
   r = malloc(10);
   /* Vul het geheugen, bijvoorbeeld met */
   /* strcpy(r, "NietTeLang"); */
   return r;
}

char* functie2()
{
   static char r[10] = "";
   /* Wijzig de inhoud van de array, bijvoorbeeld met : */
   /* strcpy(r, "Statisch"); */
   return r;
}

int main()
{
   char* stringetje = NULL;

   stringetje = functie1(); /* stringetje wijst nu naar "NietTeLang" */
   stringetje = functie2(); /* stringetje wijst nu naar "Statisch" */

   return 0;
}

Verwijderd

Topicstarter
Verwijderd schreef op 07 May 2003 @ 17:38:
ja

edit:
een handige website voor dit soort dingen is Google
en de bibliotheek en/of boekenwinkel wil ook weleens helpen
ik heb hier 3 boeken, + 2 uitgeprinte boeken (nee, ik hoor niet bij die reclame van die gast die alle boeken uitprint en de bieb niet kent ;))

Verwijderd

Topicstarter
Wat de functie moet doen is een regel (string) filteren, en een gefilterde string returnen.
Dit is ivm het uitlezen van een CSV bestand, en om dit te laden in een programma.

Ik had zelf al geprobeerd om gewoon een return waarde te geven, maar dan kreeg ik allerlei errors, en als ik er een int van maakte, dan was het opeens goed.
En vanwege het feit dat ik nergens het terug kon vinden voor strings, dacht ik dat het standaard niet zou kunnen..

Maar allemaal bedankt voor de uitleg :)

  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 09:12

johnwoo

3S-GTE

Verwijderd schreef op 07 mei 2003 @ 17:37:
Is het ook mogelijk om een string als return waarde te geven bij een functie?
want overal zie ik alleen maar integers die worden teruggegeven..
Maar eigenlijk wil ik een functie die zo werkt:

char s[10];

s = functie();


Kan dat?
Het zal best compilen, maar volgens mij kom je nu aardig in de knoop met je geheugen.

Je maakt ruimte voor 10 chars, de pointer naar dat stukje geheugen noem je s. Vervolgens wijs je aan s een andere waarde toe (whatever die functie berekent). Aan die ruimte voor 10 chars heb je nu dus niks meer (de functie zal zelf geheugen alloceren en een pointer daarnaartoe teruggeven, je 10 bytes heb je dus voor noppes gealloceerd en ben je kwijt), al zal die denk ik nog wel opgeruimd worden zodra s out of scope gaat (zo niet dan heb je nog een memory leak ook). Twee methodes:
C:
1
2
3
4
5
6
char *s;
s = functie();
...
// doe iets met s
...
free(s);
Hierbij laat je de functie geheugen alloceren, dat je later zelf weer vrij geeft.

C:
1
2
3
4
char s[10];
functie(s, 10);
...
// doe iets met s
Hierbij alloceer je zelf geheugen, en geeft een pointer naar dat geheugen mee aan de functie, die er voor jou wat inzet. Om ervoor te zorgen dat de functie niet teveel kopieert naar dat stukje geheugen (buffer overflow), geef je ook de grootte mee. De Windows API maakt vaak van deze methode gebruik.
of om een pointer te retourneren naar een stuk statisch geheugen.
Dat kan in bepaalde gevallen wel, maar ik raad het je wel af; het zorgt namelijk al gauw voor side effects (bv als je een aanroep naar zo'n functie twee keer doet als argument voor een andere functie) en is niet bepaald thread-safe te noemen :P

[ Voor 18% gewijzigd door johnwoo op 07-05-2003 18:16 ]

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


Verwijderd

Verwijderd schreef op 07 May 2003 @ 17:58:
[...]


ik heb hier 3 boeken, + 2 uitgeprinte boeken (nee, ik hoor niet bij die reclame van die gast die alle boeken uitprint en de bieb niet kent ;))
En daar staat het niet in??!! Hmmmm. Ik heb één boek over C en daar staan al dit soort dingen toch vrij duidelijk in. Kheb het net even opgezocht en de hierbovenstaande suggestie wordt ook door mijn boek gegeven.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarbij de 2e sterk is aan te raden. Allereerst is de eerste gevoeliger voor memory leaks. Degene die jouw functies gebruiken moeten zelf het geheugen vrijgeven. En dat terwijl ze het niet gealloceerd hebben. Dit kan nogal verwarrend zijn, en het dient dan ook goed gedocumenteerd te worden. Bovendien zit je aan de limiet dat je altijd met malloc () op de heap gealloceerd geheugen moet gebruiken.

De 2e variant is een veel betere oplossing omdat je het geheugenmanagement aan de aanroepende code overlaat. Deze kan dan bijvoorbeeld zelf geheugen alloceren, maar andere dingen zijn ook mogelijk, zoals gewoon op de stack, of ergens in device memory.
Nadeel van deze variant is weer wel dat je voor de functie-aanroep de grootte van de buffer al moet weten, terwijl dat eigenlijk alleen maar in de functie zelf bekend is. Maar hier is wel omheen te werken door bijvoorbeeld NULL op te geven als buffer, waarna de functie gewoon alleen de gewenste grootte retourneert.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 09:12

johnwoo

3S-GTE

Verwijderd schreef op 07 mei 2003 @ 17:55:
voorbeelde ;):
C:
1
2
3
4
5
6
7
8
9
10
11
char *dagnaam(int n){
    static char *naam[] =
    { "zondag", "maandag", "dinsdag", "woensdag", 
        "donderdag", "vrijdag", "zaterdag", 
        "nietbestaande dag" };

    if (n<0 || n > 6)
        return (naam[7]);
    else
        return (naam[n]);
}
Dit is idd een van de (weinige) situaties waarbij je een static variabele zou kunnen retourneren; bij het teruggeven van constanten. Alleen is het dan wel netjes om er even
C:
1
const char *dagnaam(int n) {
van te maken; het zou natuurlijk uit den boze zijn als de caller gaat proberen te schrijven naar dat stukje geheugen ;)
.oisyn schreef op 07 May 2003 @ 22:16:
[...]


Waarbij de 2e sterk is aan te raden. Allereerst is de eerste gevoeliger voor memory leaks. Degene die jouw functies gebruiken moeten zelf het geheugen vrijgeven. En dat terwijl ze het niet gealloceerd hebben. Dit kan nogal verwarrend zijn, en het dient dan ook goed gedocumenteerd te worden. Bovendien zit je aan de limiet dat je altijd met malloc () op de heap gealloceerd geheugen moet gebruiken.

De 2e variant is een veel betere oplossing omdat je het geheugenmanagement aan de aanroepende code overlaat. Deze kan dan bijvoorbeeld zelf geheugen alloceren, maar andere dingen zijn ook mogelijk, zoals gewoon op de stack, of ergens in device memory.
...
Voor een string-retournerende functie zou ik inderdaad zeker de tweede methode gebruiken, maar voor functies die bijvoorbeeld handles teruggeven (waarvoor wellicht ook eigen Destroy functies zijn) zou je best de handle terug kunnen geven.

[ Voor 45% gewijzigd door johnwoo op 07-05-2003 22:36 ]

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Mee eens, maar een handle is natuurlijk heel wat anders dan een pointer naar een stuk geheugen waar de caller wat mee doet (ook al is die handle zelf misschien ook wel een pointer, maar dan voor intern gebruik). Goed voorbeeld hiervan is de FILE*

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1