← Índex del curs Exercicis

Unitat 1. Estructura d'un Programa i Elements Bàsics

Unitat Didàctica 1:

En aquesta unitat aprendràs:

Sortida per pantalla amb IO.println()
Literals: enters, decimals, booleans, caràcters i textos
Variables: declaració, assignació, var i constants final
Operadors aritmètics, relacionals i lògics
Operador ternari ? :
Expressions switch
Conversió de tipus (càsting i parsing)
Entrada interactiva de dades per consola amb IO.readln()

El teu primer programa amb Java 26

El HelloWorld!™️ es el clàssic primer programa que veu tot programador. Aquí el tens en Java 26:

void main() { IO.println("Hola, Món!"); }

Observa la sintaxi:

1. Literals

Un literal és un valor fix que apareix directament escrit al codi font del programa. La màquina distingeix diferents tipus de dades segons la seva naturalesa:

Nombres Enters

Són números sense part decimal. Poden ser positius o negatius. Per millorar la llegibilitat de nombres llargs, Java permet fer servir guions baixos (_):

println(42); println(-17); println(1_000_000); // Un milió

Nombres Decimals

S'escriuen amb un punt (.) com a separador decimal (no amb una coma):

println(3.14159); println(-0.5);

Text (Strings)

Qualsevol seqüència de caràcters envoltada entre cometes dobles ("..."):

println("Benvinguts al curs de programació!"); println("El resultat és: " + 10); // L'operador + concatena textos

Caràcters individuals

Un sol caràcter envoltat entre cometes simples ('...'):

println('A'); println('9');

Booleans (Cert o Fals)

Només poden tenir dos valors: true o false. Són la base per a prendre decisions:

println(true); println(false);

2. Variables

Per recordar dades que necessitarem més endavant, reservem un espai a la memòria RAM i li donem un nom. Aquest espai s'anomena variable.

int edat = 20; double pes = 68.5; boolean teCarnet = true; char lletra = 'A'; String nom = "Laura";

Com es veu a la memòria de l'ordinador?

edat: 20 pes: 68.5 teCarnet: true lletra: 'A' nom: "Laura"

Inferència de tipus amb var:

En Java modern podem utilitzar la paraula clau var quan inicialitzem la variable immediatament. El compilador dedueix el tipus automàticament:

var edat = 20; // El compilador dedueix que és un int var pes = 68.5; // El compilador dedueix que és un double var teCarnet = true; // El compilador dedueix que és un boolean var lletra = 'A'; // El compilador dedueix que és un char var nom = "Laura"; // El compilador dedueix que és un String

3. Operadors

Un operador és un símbol especial que indica a l'ordinador que realitzi una operació matemàtica, relacional o lògica sobre un o diversos valors, anomenats operands.

La combinació d'operadors, variables i literals s'anomena expressió. Tota expressió, en avaluar-se, produeix un únic valor d'un tipus concret.

3.1 Operadors Aritmètics

Són els operadors matemàtics bàsics per realitzar càlculs numèrics:

Precedència aritmètica: Igual que a les matemàtiques escolars, *, / i % tenen prioritat respecte a + i -. Pots fer servir parèntesis ( ) per forçar o clarificar l'ordre d'avaluació:

int r1 = 2 + 3 * 4; // Dóna 14 (primer 3 * 4 = 12, després + 2) int r2 = (2 + 3) * 4; // Dóna 20 (primer 2 + 3 = 5, després * 4)

Tipus dels operands i divisió entera:

El tipus del resultat depèn del tipus dels operands utilitzats:

println(7 / 2); // 3 (divisió entera: es descarta el .5!) println(7.0 / 2); // 3.5 (com que 7.0 és double, el resultat és double) println(7 / 2.0); // 3.5 println(7 % 2); // 1 (el residu de dividir 7 entre 2: 7 = 3 * 2 + 1)

Ús de suma i resta amb cadenes (String) i caràcters (char):

Operadors d'assignació composta (+=, -=, *=, /=, %=):

Són una drecera molt habitual per modificar el valor d'una variable i reassignar el resultat a ella mateixa en un sol pas:

int punts = 10; punts += 5; // Equivalent a: punts = punts + 5; (ara val 15) punts -= 3; // Equivalent a: punts = punts - 3; (ara val 12) punts *= 2; // Equivalent a: punts = punts * 2; (ara val 24) punts /= 4; // Equivalent a: punts = punts / 4; (ara val 6) punts %= 5; // Equivalent a: punts = punts % 5; (ara val 1)

Operadors unaris d'increment i decrement (++, --):

Permeten sumar o restar 1 a una variable numèrica de manera ràpida. S'escriuen després del nom de la variable (post-increment i post-decrement):

int vides = 3; vides++; // vides passa a valdre 4 vides--; // vides torna a valdre 3

3.2 Operadors Relacionals (de Comparació)

Permeten comparar dos valors entre si. El resultat d'una comparació és SEMPRE un valor booleà (boolean: true o false):

int edat = 18; boolean esMajor = edat >= 18; // true boolean esMenor = edat < 18; // false boolean teDivuit = edat == 18; // true boolean noTeVint = edat != 20; // true // Els caràcters també es comparen pel seu ordre alfabètic/Unicode: boolean ordre = 'a' < 'b'; // true (97 < 98)

Molt important: Com es comparen les cadenes de text (String)?

L'operador == en cadenes de text no compara el text contingut, sinó si les dues variables apunten exactament a la mateixa referència física a la memòria RAM. Si compares cadenes amb ==, el teu programa tindrà errors imprevisibles!

Per comparar el contingut d'un text cal utilitzar sempre el mètode .equals() o .equalsIgnoreCase():

String clauIntroduida = "admin"; String clauCorrecta = "admin"; // CORRECTE: Compara els caràcters del text boolean accioPermesa = clauIntroduida.equals(clauCorrecta); // true // Per comparar sense distingir majúscules de minúscules: boolean coincideix = "java".equalsIgnoreCase("JAVA"); // true // INCORRECTE per a Strings: // boolean fallara = (clauIntroduida == clauCorrecta); // NO utilitzar per comparar contingut!

3.3 Operadors Lògics o Booleans

A diferència dels aritmètics i relacionals (que ja coneixes de les matemàtiques bàsiques), els operadors lògics són nous per a molts estudiants. S'utilitzen per combinar múltiples condicions o invertir-ne el resultat. Els seus operands han de ser de tipus boolean i retornen sempre un boolean:

Avaluació en curtcircuit (Short-circuit Evaluation):

Java optimitza l'avaluació d'expressions lògiques d'esquerra a dreta i s'atura tan bon punt el resultat final ja és segur:

Això és clau per escriure condicions segures, com ara evitar divisions per zero:

int divisor = 0; // Com que (divisor != 0) és false, Java NO avalua la divisió i no es produeix cap error ArithmeticException: boolean divisioSegura = (divisor != 0) && (100 / divisor > 2); // false (sense errors)

Precedència entre operadors lògics:

Si s'escriuen diversos operadors lògics seguits sense parèntesis, l'ordre d'avaluació és:

  1. ! (Negació: màxima prioritat)
  2. && (AND: té prioritat sobre l'OR, equivalent a la multiplicació)
  3. || (OR: menor prioritat, equivalent a la suma)
// L'expressió: boolean res = true || false && false; // S'avalua com: true || (false && false) -> true || false -> true! // Si vols forçar que s'avaluï primer l'OR, utilitza parèntesis: (true || false) && false -> false

3.4 Combinació d'Operadors i Ordre de Precedència General

Als programes reals és habitual combinar operadors aritmètics, de comparació i lògics en una única expressió. Java resol cada part seguint una jerarquia de precedència estricta:

int edat = 19; double notaMitjana = 8.5; double ingressosFamiliars = 14_000.0; boolean teExpedientDisciplinari = false; // Comprovació de beca universitària: boolean teBeca = edat <= 25 && (notaMitjana >= 8.0 || ingressosFamiliars < 15_000.0) && !teExpedientDisciplinari; println("Té dret a beca? " + teBeca); // true

Jerarquia de precedència general en Java (de major a menor prioritat):

  1. Parèntesis ( ): Màxima prioritat absoluta. Utilitza'ls sempre per garantir l'ordre desitjat i facilitar la lectura del codi!
  2. Operadors unaris: ++, --, !, (càsting)
  3. Aritmètics multiplicatius: *, /, %
  4. Aritmètics additius: +, - (i concatenació de text +)
  5. Relacionals d'ordre: <, >, <=, >=
  6. Relacionals d'igualtat: ==, !=
  7. Lògic AND: &&
  8. Lògic OR: ||
  9. Operador ternari: ? : i Expressions switch
  10. Assignació: =, +=, -=, *=, /=, %= (prioritat mínima)

4. L'Operador Ternari (? :)

L'operador ternari és una construcció concisa i elegant que permet escollir entre dos valors possibles segons una condició booleana. És l'únic operador del llenguatge que compta amb tres operands:

condicio ? valor_si_cert : valor_si_fals

Com funciona?

  1. S'avalua la condicio (que ha de resultar en un boolean: true o false).
  2. Si la condició és true, l'operador retorna el resultat de l'expressió situada abans dels dos punts (:).
  3. Si la condició és false, l'operador retorna el resultat de l'expressió situada després dels dos punts.

Tipus de retorn: Les dues branques (valor cert i valor fals) han de retornar valors de tipus compatibles entre si (per exemple, ambdues cadenes String o ambdues valors numèrics):

// Exemple 1: Aprovat o suspès segons la qualificació int nota = 7; String resultat = (nota >= 5) ? "Aprovat" : "Suspès"; println(resultat); // Imprimeix: Aprovat // Exemple 2: Determinar el màxim de dos nombres int num1 = 45; int num2 = 78; int maxim = (num1 > num2) ? num1 : num2; // valdrà 78 // Exemple 3: Pluralització gramatical de missatges int fitxersTrobats = 1; println("S'ha trobat " + fitxersTrobats + (fitxersTrobats == 1 ? " fitxer" : " fitxers"));

5. Expressions switch

Mentre que l'operador ternari (? :) és ideal per escollir entre dos valors segons una condició booleana, les expressions switch permeten avaluar un valor i seleccionar el resultat corresponent entre múltiples opcions possibles d'una forma molt neta, segura i directa.

A diferència de les estructures tradicionals, una expressió switch:

// Exemple 1: Obtenir el tipus de jornada segons el dia de la setmana int dia = 3; String tipusJornada = switch (dia) { case 1, 2, 3, 4, 5 -> "Dia feiner"; case 6, 7 -> "Cap de setmana"; default -> "Número de dia incorrecte"; }; println(tipusJornada); // Imprimeix: Dia feiner // Exemple 2: Determinar l'estació de l'any a partir del mes int mes = 4; String estacio = switch (mes) { case 12, 1, 2 -> "Hivern"; case 3, 4, 5 -> "Primavera"; case 6, 7, 8 -> "Estiu"; case 9, 10, 11 -> "Tardor"; default -> "Mes desconegut"; }; println("L'estació és: " + estacio); // L'estació és: Primavera // Exemple 3: Assignació d'un descompte basat en un codi de text String codiClient = "VIP"; double descompte = switch (codiClient) { case "VIP" -> 0.20; // 20% case "PREMIUM" -> 0.15; // 15% case "STANDARD" -> 0.05; // 5% default -> 0.0; };

6. Conversió de Tipus: Càsting i Parsing

Quan treballem amb dades, molt sovint necessitem transformar un valor d'un tipus a un altre. En Java hem de distingir dos escenaris clarament diferenciats segons la naturalesa de les dades:

  1. Càsting: Conversió directa entre tipus primitius compatibles (per exemple, nombres entre si com int i double).
  2. Parsing: Interpretació i extracció d'un valor numèric a partir d'un text (String).

6.1 Càsting entre tipus primitius

Quan convertim entre tipus numèrics primitius, trobem dues situacions:

6.2 Parsing: Conversió de cadenes de text (String) a nombres

Què passa si tenim el text "42" i volem tractar-lo com a nombre? Un String NO és un tipus primitiu numèric, sinó una seqüència de caràcters de text emmagatzemada com a objecte. Per tant, no és possible fer un càsting directe:

// int num = (int) "42"; // ERROR DE COMPILACIÓ: Tipus incompatibles (inconvertible types)

Per obtenir el valor numèric real a partir dels caràcters d'un text cal interpretar o analitzar el text símbol a símbol. Aquest procés s'anomena en informàtica parsing. Java proporciona funcions estàndard per fer aquest procés:

String textEdat = "25"; int edat = Integer.parseInt(textEdat); // Ara edat és un int que val 25 String textPreu = "19.95"; double preu = Double.parseDouble(textPreu); // Ara preu és un double que val 19.95

Compte amb el contingut del text!

Si el text que passem a Integer.parseInt() o Double.parseDouble() no és un número vàlid (per exemple, conté lletres com "hola" o caràcters invàlids), el programa s'aturarà amb un error en temps d'execució (NumberFormatException) perquè la màquina no pot interpretar caràcters no numèrics com a xifres.

7. Entrada de Dades per Teclat: IO.readln()

Fins ara, els nostres programes només mostraven informació fixa amb println(). Però els programes reals són interactius: demanen dades a l'usuari a través de la consola i calculen respostes segons el que aquest introdueixi.

En Java 26 podem llegir el que l'usuari escriu pel teclat mitjançant la instrucció IO.readln():

void main() { String nom = IO.readln("Com et dius? "); println("Hola, " + nom + "! Benvingut/da al curs de programació."); }

Com funciona IO.readln()?

Lectura de nombres combinant IO.readln() i Parsing

Com que el que l'usuari escriu és sempre un String, si intentem fer operacions matemàtiques directament amb l'operador +, Java concatenarà el text en lloc de sumar-lo:

String edatText = IO.readln("Quina edat tens? "); // L'usuari escriu 20 println("L'any que ve tindràs: " + (edatText + 1)); // Imprimirà "201", NO 21!

Per poder operar amb nombres introduïts per l'usuari, apliquem el que hem après a la secció anterior: fem servir el parsing (Integer.parseInt() o Double.parseDouble()) sobre el text llegit:

void main() { // Demanem un enter i fem el parsing directament: int n1 = Integer.parseInt(IO.readln("Introdueix el primer número enter: ")); // Demanem un decimal: double n2 = Double.parseDouble(IO.readln("Introdueix el segon número decimal: ")); // Ja podem operar matemàticament amb n1 i n2! println("Suma: " + (n1 + n2)); println("Resta: " + (n1 - n2)); println("Multiplicació: " + (n1 * n2)); println("Divisió: " + (n1 / n2)); println("Residu: " + (n1 % n2)); }

Exercicis Pràctics i Qüestionaris

Posa a prova el que has après completant els qüestionaris interactius auto-avaluables i els reptes de programació.

Exercicis