Ohjelmointi++ 2002/ 4.2

Demo 3



Tehtävät


Viitteissä tyyliin "Luvun 8.5" noudatetaan luentomonisteen numerointia.

1.
Kirjoita algoritmi joka tarkistaa onko merkkijono sama kuin kysymysmerkkejä sisältävä merkkijono (? = mikä merkki vaan). Kysymysmerkki tarkoittaa siis mitä tahansa yhtä kirjainta.
 jono        maski
"Kissa"     "K?ss?"    => samat
"Kiss"      "K?ss?"    => ei samat
Kokeile osaatko tehdä C++-toteutusta (vapaaehtoinen, yksi bonuspiste, eli jos on algoritmi ja C++ toteutus, niin tehtävästä saa merkitä yhteensä 2 pistettä).
2*.
Kirjoita algoritmi, jolle annetaan kaksi merkkijonoa ja joka poistaa toisesta jonosta kaikki toisen jonon esiintymät. Lopputulokseen ei saa jäädä enää yhtään poistettavan merkkijonon esiintymää (vihje: tee "runsaasti" apualiohjelmia):
 jono      poista        tulos
Catcat      at      =>    Cc
Paatti      at      =>    Pi
Puatit      at      =>    Puit 
Kokeile osaatko tehdä C++-toteutusta (vapaaehtoinen +1 bonuspiste, eli jos algoritmi JA C++-toteutus, voit merkitä yhteensä kaksi pistettä. Pelkällä C++ toteutuksella vain yksi piste).

3*.
Miten esikääntäjä muuttaisi seuraavan tiedoston? Onko muodostuvassa koodissa virheitä? Mitä ohjelma tulostaisi (mahdolliseten korjausten jälkeen)? (Mukaeltu koekysymys kevät-93)
#define pois return 0;
#include <stdio.h>
#define HALPA=HINTA;
#define auto "Mosse"
#define Tul "Terve"
#define kaa  "tuloa"
#define TASTA int main(void){
#define TAHAN pois }
#define VAHAN
#define PP ;
#define VEROJA (1+40 prosenttia) PP
#define plus *
#define on =
#define HINTA=7;
#define lf "\n"
#define prosenttia / 100.0

TASTA int maksu on HALPA plus VAHAN VEROJA printf("auto on vanha, mutta halpa: %d!\n",maksu) PP printf(Tulkaa " kyytiin!" lf) PP TAHAN


4a)
Mitkä seuraavista muuttujien esittelyistä ovat syntaktisesti oikeita. Mitkä syntaktisesti oikeista ovat hyviä:
int    luku1,luku2,luku3,luku4,luku5,luku6;
int    o,l,I;
double lyhyt,short,kort;
int    i,j;
double varpaan_pituus,räpylän_leveys;
int    kissa1,_2_kanaa,3_koiraa;

b)
Keksi hyvät muuttujat kuvaamaan seuraavia tilanteita (ja kirjoita muuttujien esittely):
lasketaan kuorma-autoja ja henkilöautoja
mitataan huoneen "strategiset" tiedot ja lasketaan pinta-ala
5*.
Suunnittele ja kirjoita C++-ohjelma (käyttäen stdio.h:n funktioita, ei iostream.h:n), joka kysyy huoneesta mitatut tiedot ja tulostaa sitten näiden perusteella huoneen pinta-alan ja tilavuuden. Toteuta ohjelma monisteen 8.5 luvun mukaisesti aliohjelmia käyttäen (parametrin välitys osoittimien avulla, vrt. moniste 8.5.4). Katso malliksi matka_a2.c.
6*
Tee edellisen tehtävän huone-ohjelmasta tietovirroin ja viitemuuttujien avulla toteutettu C++ -ohjelma (vrt. matka_ar.cpp, iostream.h ja 8.5.5).
7*.
Näytä kuvan avulla (piirrä kuva kunkin sijoituksen jälkeen uudelleen) mitä ovat muuttujien arvot seuraavien sijoitusten jälkeen (kun muuttujat ovat sijoittuneet muistipaikkoihin kuten kuvassa). Piirrä kuvaan myös mihin osoittin p loogisesti aina osoittaa.

int a,b,c;
int *p;
int e;
/* 1 */    a = 19;
/* 2 */    p = &b;
/* 3 */   *p = a+2;
/* 4 */    p = p+1;  /* Tekee käytännössä p=p+2 */
/* 5 */   *p = 7;
/* 6 */    p = p+2;  /* Tekee käytännössä p=p+4 */
/* 7 */   *p = p-3;  /* Käytännössä p-6         */
/* 8 */  **p = 199;
     
    /* 1 */    /* 2 */  /* 3 */  /* 4 */  /* 5 */  /* 6 */  /* 7 */  /* 8 */  
    +-----+    +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  
100 |     | a  |     |  |     |  |     |  |     |  |     |  |     |  |     |   
    +-----+    +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  +-----+   
102 | ??  | b  |     |  |     |  |     |  |     |  |     |  |     |  |     |   
    +-----+    +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  +-----+   
104 | ??  | c  |     |  |     |  |     |  |     |  |     |  |     |  |     |   
    +-----+    +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  
106 | ??  | p  |     |  |     |  |     |  |     |  |     |  |     |  |     |  
    +-----+    +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  +-----+   
108 | ??  | e  |     |  |     |  |     |  |     |  |     |  |     |  |     |   
    +-----+    +-----+  +-----+  +-----+  +-----+  +-----+  +-----+  +-----+   

Osoitinaritmetiikassa p=p+1 tarkoitetaan että osoitin p siirtyy seuraavaan "olioon". Siksi käytännössä 16-bittisessä koneessa muistipaikan arvo kasvaakin kahdella.


8.
Kirjoita C++ -ohjelma (eli saa ja PITÄÄ käyttää string-luokkaa), joka lukee yhden merkkijonon (rivin) ja tulostaa toisen merkkijonon siten, että merkkijonon 1. ja 2. sana ovat aakkosjärjestyksessä. Tulostetaan aina vain kaksi sanaa, vaikka syötetyssä merkkijonossa olisi useampikin sana. Toteutus mielellään funktion jarjesta_1_2 -avulla (eli kirjoita ko. funktio, vrt demo 2.9 vastaus).

B1.
Kirjoita algoritmi (vrt. tehtävä 1) joka tarkistaa onko merkkijono sama kuin mahdollisesti YHDEN (tai ei yhtään, mutta ei enempää, jos saa olla monta *, niin asia vaikeutuu oleellisesti) *-merkin sisältävä jono (*:n kohdalla voi siis olla miten monta, myös 0, ja mitä merkkiä tahansa)
 jono        maski
"Kissa"     "K*a"    => samat
"Kissa"     "K*i"    => ei samat
"Kissa"     "K*"     => samat
"Lintu"     "K*"     => ei samat

G1-2
Hae tiedosto n:\kurssit\cpp\demot\demo02\demo1\users.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<base target=m1>
...
93 <a href="vesal/index.html?r=">Vesa Lappalainen</a> = 8.5<br>
94 <a href="mattim/index.html?r=">Matti Meikäläinen</a> = 8<br>
95 <a href="teppot/index.html?r=">Teppo Teikäläinen</a> = 9<br>
...

ja tee sitten ohjelma, joka lukee tiedoston ja tulostaa sen muodossa:
93 Vesa Lappalainen = 8.5 - vesal
94 Matti Meikäläinen = 8  - mattim
95 Teppo Teikäläinen = 9  - teppot
eli riisuu pois kaikki rivit, joissa ei ole linkkiä ja linkkiriveistä tulostetaan em. tiedot em. muodossa

C++ vinkkejä

Miten merkkijono luetaan:
// luejono.cpp
#include <iostream.h>
#include <string>
using namespace std;

int main(void) { string jono; cout << "Anna merkkijono >"; getline(cin,jono); cout << "Annoit jonon: '" << jono << "'" << endl; return 0; }

Tiedosto luetaan:
/* tiedosto.cpp */
/* Lukee ja tulostaa tiedoston */
/* Vesa Lappalainen 29.1.2001 */
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

/****************************************************************************/ int main(void) { string rivi; ifstream f("tiedosto.cpp"); // Tähän luettavan tiedoston nimi if ( !f ) { cout << "Tiedosto ei aukea\n"; return 1; }

while ( getline(f,rivi) ) { cout << rivi << "\n"; } return 0; }



Merkkijonon muuttaminen numeroksi ks. 17.6.1:

// luvtesti.cpp
// 25.1.2002/vl
// Testataan funktion luvuksi toimintaa.
#include <iostream>
#include <string>
using namespace std;
#include "mjonotpp.h"

int main(void) { string s; double d; int i;

cout << "Anna reaaliluku > "; getline(cin,s); luvuksi(s,d); luvuksi(s,i); cout << "Antamasi luku reaalilukuna: " << d << " ja kokonaislukuna: " << i << endl; return 0; }