Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys

13.2.4 Merkkijono, osoitin merkkiin ja vakiojono

Seuraavat esittelyt saattavat näyttää samanlaisilta

	char *p = "Kissa", jono[10] = "Kissa";

mutta näiden ero on siinä, että *p on osoitin johonkin merkkiin ja jono 10- paikkaisen merkkijonon 1. merkkiin. Osoitin p on alustettu osoittamaan vakiomerkkijonoa jossa sisältönä on " Kissa" ja 10- paikkainen merkkijono on sisällöltään alustettu arvoksi " Kissa". Osoittimen p arvoa voidaan muuttaa, osoittimen jono arvoa sen sijaan ei voida muuttaa! Osoittimen jono osoittamaa sisältöä saa ja voi muuttaa, osoittimen p osoittamaa sisältöä EI saa (eikä aina edes voi) muuttaa.

Esimerkiksi seuraava selvältä näyttävä ohjelma saattaisi tuottaa yllätyksen:

c-taul\strptr.c - varoittava esimerkki vakiojonon muuttamisesta

	#include <stdio.h> 	
	#include <string.h>
	int main(void)
	{
	  char *p="IsoKissa", jono[10];
	  strcpy(p,"Koira");          /* Tämä on tyhmää ja voi kaataa ohjelman!!! */	:-(
	  strcpy(jono,"Kissa");
	
	  printf("p: %s jono: %s\n",p,jono);
	  return 0;
	}

Ohjelma saattaa (kääntäjän optioista, kääntäjästä ja laiteympäristöstä riippuen) tulostaa:

	p: Koira jono: ra

Miksikö? Koska " IsoKissa" on vakiomerkkijono, jonka alkuun osoitin p alustetaan. Tänne osoitteeseen kopioidaan teksti " Koira". Koska kääntäjän mielestä " IsoKissa" on vakiojono ja lauseessa strcpy(jono,"Kissa") tarvitaan vakiojonoa " Kissa", päättää kääntäjä antaa käännösaikana strcpy- funktiolle osoitteen " IsoKissa" - merkkijonon sisältä!

	                     osoitin "Koira"-------------------------+  
	                     osoitin "Kissa"-------------+           |
	                     osoitin "IsoKissa"----+     |           |
	                                           v     v           v
	                                          +-----------------------------+ 
	alustus *p="IsoKissa"               p---->|I|s|o|K|i|s|s|a|0|K|o|i|r|a|0|
	                                          +-----------------------------+
	                     osoitin "Kissa"-------------+                       
	                                                 v
	                                          +-----------------------------+ 
	kopiointi strcpy(p,"Koira")         p---->|K|o|i|r|a|0|s|a|0|K|o|i|r|a|0|   
	                                          +-----------------------------+                      
	                       +-------------------------+ 
	                       |                         v
	                       |                  +-----------------------------+ 
	kopiointi strcpy(jono,"Kissa")      p---->|K|o|i|r|a|0|s|a|0|K|o|i|r|a|0|   
	 +---------------+                        +-----------------------------+                      
	 v            
	+-------------------+
	|r|a|0|?|?|?|?|?|?|?|
	+-------------------+ 

Edellisessä esimerkissä sijoitus

	p = jono;   /* OIKEIN */

on sallittu, muttei sijoitus

	jono = p;   /* VÄÄRIN */

Myös sijoitus

	p = "Koira"; 

olisi sallittu, mutta ei suinkaan sijoita osoitteeseen p jonoa " Koira", vaan sijoittaa osoittimen p osoittamaan vakiomerkkijonoon " Koira".

Eroa käsitellään vielä lisää sizeof - operaattorin kohdalla.


Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys