2009-01-13, 21:54
  #1
Medlem
dotslashs avatar
Jag sitter och testar lite olika sätt att returnera en sträng från en funktion i C. Jag får dock inte riktigt till det i fallet med pekare. Om jag förstått det rätt ska man kunna returnera en pekare till en statisk vektor av chars exempelvis.

Någon som kan skriva ett exempel på detta lite snabbt?
Citera
2009-01-13, 22:06
  #2
Medlem
Om du verkligen vill returnera en sträng (array, fält, ...) så måste du stoppa in den i en struct. Det vettiga sättet är att anroparen av funktionen skickar in pekaren till ett förberett fält i ett av argumenten, och att funktionen fyller i strängen (eller vad som nu ska göras) på plats.
Citera
2009-01-13, 22:14
  #3
Medlem
dotslashs avatar
blir det inte lite overkill att skapa en struct för en enda sträng?
Citera
2009-01-13, 22:31
  #4
Medlem
Citat:
Ursprungligen postat av dotslash
blir det inte lite overkill att skapa en struct för en enda sträng?
Jupp, antagligen vettigare att göra nåt sånt här:
Kod:
void dinFunktion(char *ut, int antalTecken);
där strängen returneras genom pekaren *ut som redan har minne allokerat till sig när funktionen anropas. antalTecken berättar för funktionen hur många chars som är allokerade.
Citera
2009-01-13, 22:43
  #5
Medlem
Citat:
Ursprungligen postat av dotslash
blir det inte lite overkill att skapa en struct för en enda sträng?
Jo, men det är så det fungerar och det är därför ingen returnerar strängar. Men det går att göra, med hjälp av en struct.

Du nämnde statisk variabel. Det är ett sätt: deklarera en global char-array utanför både main() och din funktion, så kan du använda den som gemensamt utrymme, om du inte vill använda det konventionella sättet.
Citera
2009-01-13, 22:49
  #6
Medlem
dotslashs avatar
Jag löste det genom en pekare. För att illustrera så pastar jag hela saken här. Det den gör är att returera ett betyg beroende på poängen man fått på en tenta eller liknande:

Kod:
#include <stdio.h>

char *betyg(int points) {
	
	char *grade;

	if (points <= 29) {
		grade = "U";
	}
	
	else if (points >= 30 && points <= 39) {
		grade = "G";
	}
	
	else if (points <= 40) {
		grade = "VG";
	}

	return grade;
	
}



int main (void) {

	int points;
	
	printf("Hur många poäng uppnåddes?:  ");
	scanf("%d", &points);
	
	printf("Betyget blir: %s", betyg(points));
	
    return 0;
}

Är det något fel i detta, något som går emot konvensionen? Kompilatorn klagar inte iaf...
Citera
2009-01-13, 22:52
  #7
Medlem
Citat:
Är det något fel i detta, något som går emot konvensionen? Kompilatorn klagar inte iaf...

Ja!

Du skapar aldrig nån plats för att spara strängen du returnerar, utan den bara skriver över vafan som pekaren råkade peka på innan. (För du initialiserar ju itne pekaren heller). Och skriver potentiellt över allt möjlig anna viktig data i minnet. Funkar ens programmet?

Edit: Ovanstående är inte sant kom jag på, så skit i det. Är dock fortfarande inte rätt sätt att lösa det på.
__________________
Senast redigerad av dbshw 2009-01-13 kl. 23:16.
Citera
2009-01-13, 22:55
  #8
Medlem
dotslashs avatar
Citat:
Ursprungligen postat av dbshw
Ja!

Du skapar aldrig nån plats för att spara strängen du returnerar, utan den bara skriver över vafan som pekaren råkade peka på innan. (För du initialiserar ju itne pekaren heller). Och skriver potentiellt över allt möjlig anna viktig data i minnet. Funkar ens programmet?

Jo, det fungerar faktiskt. Men det är inte så konstigt eftersom det är i debug-miljö och sker virtuellt då.
Citera
2009-01-13, 22:57
  #9
Medlem
gadzooxs avatar
Citat:
Ursprungligen postat av dotslash
Kod:
	char *grade;
	if (points <= 29) {
	else if (points >= 30 && points <= 39) {
	else if (points <= 40) {

	return grade;
Om man har över 40 då?
Citera
2009-01-13, 22:58
  #10
Medlem
dotslashs avatar
Citat:
Ursprungligen postat av gadzoox
Om man har över 40 då?

Nä då skiter det sig.
Citera
2009-01-13, 22:59
  #11
Medlem
gadzooxs avatar
Citat:
Ursprungligen postat av dotslash
Nä då skiter det sig.
Korrekt.
Citera
2009-01-13, 23:05
  #12
Medlem
Just sånt här får man vara lite försiktig med. När man returnerar en pekare till något måste man se till att det den pekar på är globalt, och alltså inte ligger på stacken, där den utan vidare kan skrivas över vid ett senare tillfälle. Detta kan lösas med storage class specifiern static som i det här fallet, vilket ser till att datan överlever efter att funktionen har returnerat.

Kod:
#include <stdio.h>

char *get_str(void)
{
  static char mening[] = "en mening?";

  return mening;
}

int main(void)
{
  char *str;

  str = get_str();
  printf("%p - %s\n", str, str);
  return 0;
}

Just strängar är speciella eftersom de är data, och sparas i datasegmentet (inte på stacken). Det var därför inget större fel på din betygslösning i princip, men det är kanske snyggare att explicit delkarera strängarna som static:

Kod:
char *betyg(int points)
{
  static char *u = "U";
  static char *g = "G";
  static char *vg = "VG";

  if (points == 40) {
    return vg;
  }
  else if (points >= 30) {
    return g;
  }
  else {
    return u;
  }
}
Citera
  • 1
  • 2

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in