Logo FPCode

Introducció a la programació

Conceptes bàsics sobre la programació, paradigmes, llenguatges de programació i entorns de desenvolupament.

Introducció

La programació és una de les habilitats més importants en l’àmbit de la informàtica. La seva comprensió permet dissenyar solucions automàtiques a problemes reals, estructurant dades i ordres que un ordinador pugui entendre i executar. En aquesta introducció abordarem els conceptes bàsics que sustenten la programació: què són les dades, quin paper juguen els algoritmes, com s’estructuren els programes, quins paradigmes de programació existeixen, quins llenguatges s’utilitzen, entre altres conceptes…

Referències

Índex

  1. La programació
  2. Paradigmes de programació
  3. Llenguatges de programació
  4. Diagrama de flux
  5. Eines i entorns per al desenvolupament de programes
  6. Qualitat dels programes
  7. Exercicis

1. La programació

La programació és una eina que ens permet donar instruccions a les màquines perquè realitzin tasques per nosaltres. Tot i que avui dia estem acostumats a utilitzar ordinadors i aplicacions, aquesta capacitat de comunicar-nos amb les màquines no ha existit sempre, sinó que ha estat el resultat d’una evolució llarga en el temps. La idea de seguir passos ordenats per resoldre un problema es remunta al segle IX, quan el matemàtic persa Al-Juarismi va definir les bases del que avui coneixem com a algoritmes.

1.2. Algoritmes i programes

Un algoritme és, simplement, una seqüència de passos finits i ordenats que ens porten a resoldre un problema, com quan seguim una recepta de cuina. Durant molts segles, aquests algoritmes eren executats per persones. No obstant això, amb l’avanç de la tecnologia, especialment a partir de la Revolució Industrial, vam començar a crear màquines capaces de fer aquesta feina. Al segle XIX, Ada Lovelace va escriure el que es considera el primer algoritme pensat per ser executat per una màquina, col·laborant amb Charles Babbage i la seva màquina analítica. Ja al segle XX, amb l’aparició dels primers ordinadors electrònics, va sorgir la necessitat de crear llenguatges de programació, que són formes estructurades i comprensibles de donar instruccions a un ordinador.

Aquestes instruccions, anomenades ordres o sentències, permeten realitzar accions concretes, com mostrar missatges, fer operacions matemàtiques o guardar informació. Quan agrupem diverses instruccions de manera ordenada i lògica, obtenim un programa. Un programa és la codificació concreta d’un algoritme fent servir un llenguatge de programació, que pot ser executat per un ordinador. Podem imaginar un programa com una història: cada línia és un pas que fa avançar l’acció. És important destacar que un programa no pot funcionar sense informació; per tant, les dades són la seva matèria primera. Representen informació codificada que pot ser processada per una màquina.

Si totes les instruccions estan ben escrites i col·locades en l’ordre correcte, el programa funcionarà com s’espera. Si no, poden aparèixer errors o comportaments imprevistos. Aprendre a programar és, doncs, aprendre a pensar de manera estructurada, lògica i creativa per resoldre problemes amb l’ajuda de les màquines.

2. Paradigmes de programació

Al llarg del temps, la programació ha evolucionat per adaptar-se a diferents tipus de problemes i formes de pensar. Aquesta evolució ha donat lloc al que coneixem com a paradigmes de programació, que no són més que enfocaments o estils que defineixen com organitzar i estructurar el codi per resoldre un problema.

Un paradigma no és simplement una tècnica aïllada, sinó un model que marca una manera determinada d’escriure programes, amb les seves pròpies regles, principis i formes de raonar. Alguns paradigmes es centren en com s’executen les instruccions pas a pas, mentre que altres posen el focus en quin resultat es vol aconseguir sense especificar com.

Un dels paradigmes més comuns és l’imperatiu, on el programador dóna instruccions explícites a la màquina sobre què ha de fer en cada moment. Dins d’aquest enfocament, trobem variants com:

  • Programació estructurada
    Organitza el codi en blocs lògics utilitzant estructures com condicions (if), bucles (while, for) i funcions o procediments. Afavoreix una lectura clara i un control precís del flux del programa.
    Exemples de llenguatges: C, Pascal, Fortran.

  • Programació modular
    Basada en la programació estructurada, divideix el programa en parts independents anomenades mòduls o paquets. Cada mòdul resol una part del problema i pot ser reutilitzat en altres programes.
    Exemples de llenguatges: Perl, Ruby.

  • Programació orientada a objectes (POO)
    Organitza el codi al voltant d’objectes que agrupen dades i comportaments relacionats. Es basa en conceptes com classes, herència, encapsulament i polimorfisme. És molt útil per desenvolupar sistemes grans i complexos.
    Exemples de llenguatges: Java, Python, C++, C#.

  • Programació orientada a esdeveniments
    El flux del programa està determinat per esdeveniments com accions de l’usuari, missatges del sistema o senyals externes. Els programes reaccionen a aquests esdeveniments mitjançant manejadors o controladors que executen codi específic. Aquest paradigma s’utilitza molt en interfícies gràfiques i aplicacions interactives.
    Exemples de llenguatges: JavaScript, Visual Basic.

En contraposició, el paradigma declaratiu es basa a dir-li a l’ordinador què es vol aconseguir, sense detallar com fer-ho. Aquí és la màquina la que s’encarrega de trobar el camí per assolir el resultat. Dins d’aquest grup trobem:

  • Programació lògica
    Es basa en la definició de fets i regles lògiques per deduir resultats. En lloc d’especificar com realitzar una tasca, es declara què és cert i la màquina infereix les respostes.
    Exemples de llenguatges: Prolog, Mercury, Oz.

  • Programació funcional
    Construeix solucions a partir de funcions pures que no tenen efectes secundaris ni modifiquen estats externs. Es centra en la composició i transformació de dades mitjançant funcions.
    Exemples de llenguatges: Haskell, Lisp, Scala.

Ambdós paradigmes, l’imperatiu i el declaratiu, representen formes molt diferents de raonar sobre els problemes, però no són excloents. De fet, molts llenguatges actuals permeten combinar idees de diversos paradigmes. Aquesta capacitat es coneix com a programació multiparadigma, i és una pràctica habitual en entorns reals. Per exemple, llenguatges com Python o Java permeten barrejar programació estructurada, orientada a objectes i, en part, funcional.

Adoptar un o altre paradigma depèn del tipus de problema que es vol resoldre, l’experiència del programador i les característiques del llenguatge utilitzat. Seguir les regles i principis d’un paradigma ajuda a escriure codi més net, comprensible i mantenible, facilitant tant el desenvolupament individual com el treball en equip.

Tot i que existeixen molts paradigmes, els més estudiats en etapes inicials de l’aprenentatge de la programació són la programació estructurada i la modular, ja que ofereixen una base per adquirir bons hàbits d’organització i pensament lògic.

3. Llenguatges de programació

En la comunicació humana utilitzem un llenguatge per transmetre informació entre un emissor i un receptor, a través d’un canal. Cada idioma té les seves pròpies regles gramaticals i estructures, però tots comparteixen una característica essencial: una sintaxi que permet que el missatge sigui entès. Aquesta organització de les paraules és el que garanteix una comunicació efectiva.

En informàtica, també s’usa el concepte de llenguatge, encara que en aquest cas el receptor no és una persona sinó una màquina. Els ordinadors funcionen a nivell bàsic mitjançant senyals elèctrics, representats com a seqüències de 0 i 1, anomenats bits. Aquests bits reflecteixen els dos possibles estats d’un transistor: encès (1) o apagat (0).

Atès que les persones no poden comunicar-se directament amb bits, es van crear llenguatges intermedis anomenats llenguatges de programació. Aquests llenguatges permeten traduir les nostres idees en instruccions comprensibles per una màquina, servint de pont entre el pensament humà i la lògica de l’ordinador.

Als inicis de la informàtica, la programació era molt rudimentària. S’utilitzaven targetes perforades amb forats que representaven instruccions en binari. Aquest procés era lent i propens a errors, però va ser el primer pas cap a formes més eficients de comunicació amb les màquines.

Amb el temps va aparèixer el llenguatge ensamblador, que va introduir instruccions més comprensibles que el binari pur, encara que seguia sent un llenguatge de baix nivell. Cada instrucció en assembler correspon directament a una operació que la CPU pot executar, com moure dades entre registres o fer sumes. Per utilitzar assembler cal conèixer bé el maquinari de la màquina.

suma.asm
section .data
; Definim els dos nombres a sumar
num1 db 5 ; Nombre 1 (5 en decimal)
num2 db 10 ; Nombre 2 (10 en decimal)
section .text
global _start
_start:
; Carreguem els nombres als registres
mov al, [num1] ; Carreguem el valor de num1 al registre AL
add al, [num2] ; Sumem el valor de num2 al registre AL
; El resultat de la suma està ara al registre AL
; (AL és un registre de 8 bits en l’arquitectura x86)
; Per finalitzar el programa
mov ebx, 0 ; Codi de sortida 0
mov eax, 1 ; Número de la crida al sistema per sortir
int 0x80 ; Interrupció per fer la crida al sistema

Tot i que en veure codi ensamblador sembla que fem servir paraules humanes com mov, add o int, la màquina no entén aquestes paraules tal qual. El que realment processa són codis binaris que representen aquestes instruccions. Per exemple, una instrucció simple com mov al, [num1] es tradueix en una seqüència de bits que pot ocupar 48 o més, depenent de l’arquitectura. Això ens dóna una idea de la gran quantitat de zeros i uns que hi ha darrere de qualsevol programa, fins i tot el més senzill.

Gràcies a l’evolució de la informàtica, avui disposem de llenguatges de programació de nivell més alt, com C, Python o Java, que ens permeten centrar-nos en la lògica dels programes sense haver de preocupar-nos pel maquinari. Aquests llenguatges segueixen tenint regles i sintaxi pròpies, però fan que programar sigui més accessible, més ràpid i menys propens a errors.

3.2. Classificació

Els llenguatges de programació es poden classificar de diverses maneres segons diferents criteris, com el nivell d’abstracció, la forma en què s’executen o com es processen abans de l’execució.

Segons el nivell d’abstracció:

Llenguatges de baix nivell

Són aquells que estan molt a prop del llenguatge màquina, és a dir, del codi binari que entén directament el processador. Un exemple típic són els llenguatges ensamblador (assembly), que utilitzen instruccions simbòliques que representen operacions bàsiques del maquinari. Els llenguatges de baix nivell permeten un control molt precís sobre el maquinari i la memòria, però són més difícils d’aprendre i escriure, ja que requereixen conèixer l’arquitectura interna de l’ordinador.

Llenguatges d’alt nivell

Aquests llenguatges estan dissenyats per ser més abstractes i llegibles per als humans, ocultant els detalls complexos del maquinari. Permeten expressar algoritmes i estructures de manera més intuïtiva i propera al llenguatge natural. Alguns exemples són Python, Java i JavaScript. Els llenguatges d’alt nivell faciliten el desenvolupament ràpid, la mantenibilitat i la portabilitat del codi entre diferents sistemes.

Segons la manera com s’executen:

Llenguatges compilats

En aquest tipus de llenguatges, el codi font que escriu el programador es tradueix completament a codi màquina mitjançant un programa anomenat compilador, abans que s’executi. El resultat és un fitxer executable independent que l’ordinador pot executar directament. Això sol oferir millor rendiment, ja que la traducció està optimitzada i només es fa una vegada. Llenguatges com C, C++, Go o Rust són exemples típics de llenguatges compilats.

Llenguatges interpretats

En els llenguatges interpretats, el codi font no es converteix directament a codi màquina. En lloc d’això, un programa anomenat intèrpret llegeix i executa el codi línia per línia en temps real. Això facilita la depuració i la portabilitat, ja que el codi pot executar-se en qualsevol màquina que tingui l’intèrpret adequat, sense necessitat de recompilar. Python, PHP, JavaScript i Ruby són exemples de llenguatges interpretats.

3.3. Exemples

  • C Sharp
Logo de C#

Llenguatge de programació desenvolupat per Microsoft, orientat a objectes i utilitzat principalment en el desenvolupament d’aplicacions d’escriptori, videojocs amb Unity i programari empresarial dins de l’ecosistema .NET.

suma.cs
using System;
class Program
{
static void Main()
{
int num1 = 5;
int num2 = 10;
int suma = num1 + num2;
Console.WriteLine($"La suma de {num1} y {num2} es: {suma}");
}
}
  • Java
Logo de Java

Llenguatge de propòsit general, orientat a objectes i àmpliament utilitzat en aplicacions empresarials, desenvolupament mòbil (Android) i sistemes distribuïts. Es caracteritza per la seva portabilitat gràcies a la màquina virtual de Java (JVM).

suma.java
public class Suma {
public static void main(String[] args) {
int num1 = 5;
int num2 = 10;
int suma = num1 + num2;
System.out.println("La suma de " + num1 + " y " + num2 + " es: " + suma);
}
}
  • Python
Logo de Python

Llenguatge d’alt nivell, fàcil d’aprendre i amb una sintaxi clara. S’utilitza en desenvolupament web, ciència de dades, intel·ligència artificial, automatització i més. La seva versatilitat i les seves àmplies biblioteques el fan molt popular.

suma.py
num1 = 5
num2 = 10
suma = num1 + num2
print(f"La suma de {num1} y {num2} es: {suma}")
  • JavaScript
Logo de Javascript

Llenguatge de programació essencial per al desenvolupament web, utilitzat principalment en el costat del client per crear interfícies dinàmiques. Amb Node.js, també s’utilitza al backend.

suma.js
let num1 = 5;
let num2 = 10;
let suma = num1 + num2;
console.log(`La suma de ${num1} y ${num2} es: ${suma}`);
  • PHP
Logo de PHP

Llenguatge de scripting àmpliament utilitzat en desenvolupament web per a la creació de llocs i aplicacions dinàmiques. És el motor de moltes plataformes com WordPress i Laravel.

suma.php
<?php
$num1 = 5;
$num2 = 10;
$suma = $num1 + $num2;
echo "La suma de $num1 y $num2 es: $suma";
?>

3.4. Llenguatge d’aprenentatge (Pseudocodi)

Quan comencem a aprendre a programar o dissenyem una solució abans d’escriure codi, el nostre objectiu principal és estructurar i planificar la lògica per resoldre un problema sense preocupar-nos per la sintaxi específica d’un llenguatge de programació. En aquesta etapa inicial, no utilitzem llenguatges formals que requereixen un coneixement detallat de regles, estructures i símbols, sinó que fem servir una forma de comunicació més propera al nostre llenguatge natural.

Aquest llenguatge intermedi s’anomena pseudocodi. El pseudocodi ens permet descriure la lògica d’un programa de forma clara i senzilla, utilitzant paraules i expressions fàcils d’entendre per a les persones, però sense les estrictes regles d’un llenguatge de programació real. Així, podem centrar-nos en pensar quins passos ha de seguir el programa per complir la seva funció, sense preocupar-nos encara pels detalls tècnics o sintàctics.

És important destacar que el pseudocodi no es pot executar directament en un ordinador, ja que no té una traducció directa a codi binari. En canvi, actua com un pont entre la idea o l’algoritme que volem implementar i el llenguatge de programació concret que utilitzarem per escriure el codi real. Un cop definit el pseudocodi, es realitza una traducció cap al llenguatge escollit, adaptant les instruccions perquè l’ordinador les pugui processar i executar correctament.

A continuació, es mostra un exemple senzill de pseudocodi per sumar dos números:

suma.txt
Inici
Definir num1 com a Enter
Definir num2 com a Enter
Definir suma com a Enter
Assignar 5 a num1
Assignar 10 a num2
suma ← num1 + num2
Mostrar "La suma de ", num1, " i ", num2, " és: ", suma
Fi

Aquest exemple reflecteix com, mitjançant pseudocodi, podem expressar la lògica del programa de manera comprensible i ordenada abans de passar a la fase de programació pròpiament dita.

4. Diagrames de flux

Els diagrames de flux són una eina gràfica que ens permet representar visualment la seqüència lògica i el flux d’un algoritme o procés. Consten de símbols connectats per fletxes que indiquen l’ordre en què s’executen les instruccions o decisions dins del programa.

En utilitzar diagrames de flux, podem visualitzar de forma clara i senzilla com es resol un problema, facilitant la comprensió i planificació abans de començar a escriure codi en un llenguatge de programació concret. Aquesta representació gràfica ajuda a detectar errors lògics o passos innecessaris de manera precoç.

Relació entre el pseudocodi i els diagrames de flux

Ambdós són formes d’expressar la lògica d’un algorisme sense dependre de la sintaxi específica d’un llenguatge de programació. Mentre que el pseudocodi utilitza una notació escrita propera al llenguatge natural per descriure els passos de l’algorisme, el diagrama de flux ofereix una representació visual d’aquests mateixos passos.

En aquesta primera unitat, aprendre a dissenyar tant pseudocodi com diagrames de flux és necessari, ja que constitueixen la base per comprendre com estructurar i organitzar algorismes abans de traduir-los a codi d’un llenguatge de programació concret que l’ordinador pugui executar.

5. Eines i entorns per al desenvolupament de programes

Per crear programes de manera eficient i ordenada, els desenvolupadors no escriuen codi directament en un bloc de notes, sinó que utilitzen diverses eines i entorns que faciliten l’escriptura, prova, depuració i manteniment del codi. Aquestes eines no només agiliten el procés de desenvolupament, sinó que també contribueixen a millorar la qualitat del programari produït.

Entre les eines més comunes destaquen:

  • Editors de text: Són aplicacions que permeten escriure i modificar codi font de forma senzilla. Alguns editors populars són NotePad++, Visual Studio Code (VS Code), Sublime Text i Atom. Aquests editors solen incloure funcionalitats com ressaltat de sintaxi, autocompletat i extensions que amplien les seves capacitats.

  • Entorns de desenvolupament integrats (IDE): Són plataformes més completes que, a més de l’edició de codi, integren eines per compilar, executar i depurar programes. Alguns exemples:

    • Eclipse, IntelliJ IDEA i NetBeans: IDEs populars per a Java i altres llenguatges basats en la JVM.
    • Visual Studio: Molt utilitzat per al desenvolupament en C#, .NET, C++ i aplicacions web, especialment en entorns Windows.
    • PyCharm: IDE especialitzat per a Python, amb funcionalitats avançades per a desenvolupament científic i web.
    • Xcode: IDE oficial d’Apple per al desenvolupament en Swift, Objective-C i aplicacions per a iOS, macOS, watchOS i tvOS.
    • Android Studio: Basat en IntelliJ IDEA, és l’entorn oficial per desenvolupar aplicacions Android amb Java o Kotlin.
    • RubyMine: IDE per a Ruby i Ruby on Rails, que facilita el desenvolupament ràpid d’aplicacions web amb aquest llenguatge.
    • WebStorm: Orientat al desenvolupament web amb JavaScript, TypeScript, React, Angular, entre altres.
    • CLion: IDE per a desenvolupament en C i C++, amb suport per a CMake i depuració avançada.
  • Sistemes de control de versions: Eines com Git o SVN permeten portar un seguiment detallat dels canvis realitzats en el codi, facilitant el treball col·laboratiu i la gestió de diferents versions del programari.

  • Depuradors: Són eines que ajuden a identificar i corregir errors durant l’execució d’un programa. Permeten aturar l’execució, inspeccionar variables i seguir el flux del codi per trobar fallades lògiques o de comportament. La gran majoria d’IDEs ja en disposen incorporats.

  • Gestors de paquets: Aquests sistemes faciliten la instal·lació, actualització i gestió de biblioteques o dependències que utilitza un projecte. Alguns exemples són npm per a JavaScript, pip per a Python i Maven per a Java.

Aquestes eines es treballaran amb profunditat en altres unitats o assignatures.

6. Qualitat dels programes

Quan desenvolupem programes o algorismes, no n’hi ha prou que simplement funcionin per resoldre un problema. És necessari que el programari tingui una qualitat adequada, cosa que significa que estigui lliure d’errors, sigui eficient en l’ús dels recursos, fàcil de mantenir i comprendre, i que compti amb una bona documentació per facilitar la feina d’altres desenvolupadors en el futur.

Un programa de bona qualitat aporta diversos beneficis importants. Ajuda a reduir la quantitat d’errors i fallades que poden afectar el seu funcionament, facilita la tasca de mantenir i modificar el codi a mesura que canvien els requisits, millora l’experiència de l’usuari evitant comportaments inesperats i genera més confiança que el programari compleix correctament la seva funció.

Tipus d’errors

Els errors, també anomenats bugs, són un dels principals enemics de la qualitat del programari. Es poden classificar en tres tipus bàsics:

  • Errors de sintaxi: Es produeixen quan el codi no respecta les regles del llenguatge de programació, com oblidar un punt i coma o escriure malament una paraula reservada. Aquests errors impedeixen que el programa es compili o interpreti adequadament. Normalment, les eines de desenvolupament els detecten ràpidament.

  • Errors d’execució: Apareixen mentre el programa està en funcionament, com intentar dividir un nombre per zero o accedir a una variable que no té un valor assignat (null). Aquests errors poden fer que el programa s’aturi de forma inesperada o que generi resultats incorrectes.

  • Errors lògics: Són més difícils de detectar perquè el programa s’executa sense fallades, però no realitza correctament la tasca per a la qual va ser dissenyat. Això passa quan la lògica implementada no és l’adequada per resoldre el problema plantejat.

Com millorar la qualitat

Per aconseguir un programari de qualitat, es recomana seguir certes pràctiques que ajuden a prevenir i corregir errors:

  • Fer proves constants: És important aplicar diferents tipus de proves, com proves unitàries (per a cada part petita del codi), proves d’integració (per verificar que les parts funcionen bé juntes) i proves funcionals (per validar que el programa compleix amb els requisits).

  • Revisió de codi: Revisar el codi ajuda a detectar errors, millorar la lògica i aprendre millors formes de resoldre problemes.

  • Adoptar bones pràctiques de programació: Escriure codi clar, modular (dividit en parts petites i reutilitzables) i ben documentat facilita la comprensió i el manteniment a llarg termini.

7. Exercicis

Exercici 1: Algorismes vs Programes

🔍 Objectiu: Comprendre la diferència entre un algorisme i un programa.

✏️ Instruccions:

  1. Explica amb les teves pròpies paraules què és un algorisme i què és un programa.
  2. Indica quina és la diferència principal entre tots dos.
  3. ✨ Dona un exemple pràctic d’un algorisme quotidià (per exemple, com preparar un cafè).
  4. Explica com aquest algorisme podria convertir-se en un programa informàtic.
Exercici 2: Codi espagueti

🔍 Objectiu: Investigar i comprendre què és el codi espagueti i la seva relació amb els paradigmes de programació.

✏️ Instruccions:

  1. Investiga i defineix què és el codi espagueti.
  2. Explica per què sol aparèixer amb més freqüència en certs paradigmes o estils de programació.
  3. Justifica en quin paradigma és més comú trobar-lo i per què passa.
Exercici 3: Llenguatges de programació

🔍 Objectiu: Conèixer diferents llenguatges de programació, la seva història i la seva popularitat actual.

✏️ Instruccions:

  1. Fes una taula amb almenys 10 llenguatges de programació, incloent per a cadascun:
      • 📝 Nom del llenguatge
      • 👤 Creador/a
      • 📅 Any de creació
      • 🧭 Paradigmes que suporta (imperatiu, orientat a objectes, funcional, etc.)
  1. Investiga en una font de referència quins són els llenguatges més utilitzats actualment.

  2. 📈 Anàlisi final:

      • Tria el llenguatge més popular de la llista i analitza:
        • Les seves característiques principals
        • Avantatges i usos habituals
        • Per què ocupa el primer lloc en popularitat
Exercici 4: La importància d’aprendre programació en l’era de la Intel·ligència Artificial

🔍 Objectiu: Reflexionar sobre la rellevància de la programació en un món cada vegada més automatitzat per la intel·ligència artificial.

✏️ Instruccions:

  1. Explica per què continua sent necessari aprendre a programar encara que la IA estigui cada cop més present a les nostres vides i feines.
  2. Reflexiona sobre aspectes com:
    • 🛠️ Control sobre la tecnologia
    • 💡 Capacitat d’adaptar solucions
    • 🧠 Desenvolupament del pensament lògic i crític
    • 🤝 Col·laboració entre persona i màquina
  3. Dona exemples concrets de com la programació complementa l’ús de la IA en diferents àmbits, com ara:
    • Ciència de dades
    • Educació
    • Salut
    • Negocis
    • Entreteniment