Søger du en specifik kategori?

 



Oprettet man. d. 02. februar 2009 kl. 22:50

arne_v
arne_v (1.005.658 point)
Guidens karaktér
1
2
3
4
5

Fortran 77 for C/C++/Java/C# programmører

Denne artikel vil give en kort introduktion til programmerings sproget Fortran 77. Den forudsætter nogen erfaring med mindst et af sprogene C/C++/Java/C#, fordi artiklen forklarer hvordan man gør tingene i Fortran 77 ikke hvordan man programmerer.
Historie:
V1.0 - 20/07/2008 - original

Standarder

Fortran er det ældste high level language.

Første version udkom i 1957.

Sproget er standardiseret via ANSI/ISO:
- Fortran 66
- Fortran 77
- Fortran 90
- Fortran 95
- Fortran 2003

De traditionelle store platforme for Fortran var forskellige IBM systemer
og VMS VAX (oprindeligt Digital - idag ejet af HP).

Artiklen vil beskrive Fortran 77. Fortran 77 var den sidste meget udbredte
Fortran version. De nyere versioner har stået i skyggen af nyere sprog.

Mine eksempler vil gå lidt udover Fortran 77 standarden og inkludere
de mest gængse extensions. Jeg vil teste eksemplerne med GCC g77 på Windows
og HP Fortran på VMS Alpha.

Artiklen giver nok mest hvis man har en Fortran compiler man kan lege med
mens man læser artiklen.

Windows: hent GCC MinGW
Linux: GCC skulle gerne være installeret

generel program opbygning

Fortran programmer har en helt anderledes opbygning end nyere programmerings
sprog. Formatet er ikke free format men er linie orienteret og positions afhængigt.

position 1-5 bruges til numeriske labels

position 6 bruges til continuation markering
(et tegn betyder at linien er en fortsættelse af forrige linie)

Position 7-72 bruges til kode.

Position 72- er kommentarer.
(I gamle dage skrev man linienumre derude, fordi så kunne man sortere hulkortene
efter dem)

Et program stareter med PROGRAM statement og slutter med END statement.

Så er vi vist klar til helloworld.for:

      PROGRAM HELLOWORLD
      WRITE(*,*) 'Hello world !'
      END


WRITE(*,*) vil blive forklaret senere i artiklen.

Man ser at al koden starter i position 7.

Ofte skriver man Fortran kode i ren uppercase, men det er ikke nødvendigt.
(da Fortran blev lavet var der computer systemer som kun havde store bogstaver)

Kommentarer laves ved at skrive et C i position 1. Det er valgfrit hvilket tegn
man bruger som continuation markering i position 6, men det anbefales at bruge +.

Nu kan vi lave en helloworld.for som viser disse features:

C
C Dette er et hello world program i Fortran
C
      PROGRAM HELLOWORLD
      WRITE(*,*)
    +    'Hello world !'
      END


Bemærk at spaces er insignificante i Fortran.


      MYVAR=1


kan skrives som:


      M Y V A R = 1


men det bør man naturligvis aldrig gøre.

simple typer og konstanter

Fortran 77 standarden definerer data typerne:
- INTEGER
- LOGICAL
- CHARACTER
- REAL
- DOUBLE PRECISION
- COMPLEX

Men det er de facto standard at man kan kvalificere typerne med at angive deres
størrelse i bytes.

Så:


C/C++/Java/C#              Fortran
-------------              -------
short                      INTEGER*2
int                        INTEGER*4
long                        INTEGER*8
bool/boolean                LOGICAL*4
string/String              CHARACTER*n
float                      REAL*4
double                      REAL*8
-                          REAL*16
-                          COMPLEX*8
-                          COMPLEX*16


Bemærk at CHARACTER i Fortran er en fast længde streng ikke en variabel længde
streng som i de andre sprog.

Den opmærksomme læser kan nu begynde at se hvorfor Fortran er et oplagt sprog
til tal knuseri i floatng point og komplekse tal, mens at behandling af tekst
er noget besværligt.

Vi laver nu et simpelt eksempel med variabel erklæringer og nogle værdi
tildelinger.


      PROGRAM VARASGN
      INTEGER*2 V1
      INTEGER*4 V2
      INTEGER*8 V3
      LOGICAL*4 V4
      CHARACTER*16 V5
      REAL*4 V6
      REAL*8 V7
C      REAL*16 V8
      COMPLEX*8 V9
      COMPLEX*16 V10
      V1=123
      V2=123
      V3=123
      V4=.TRUE.
      V5='Dette er en test'
      V6=123.456
      V7=123.456D0
C      V8=123.456Q0
      V9=(1.2,3.4)
      V10=(1.2D0,3.4D0)
      WRITE(*,*) V1
      WRITE(*,*) V2
      WRITE(*,*) V3
      WRITE(*,*) V4
      WRITE(*,*) V5
      WRITE(*,*) V6
      WRITE(*,*) V7
C      WRITE(*,*) V8
      WRITE(*,*) V9
      WRITE(*,*) V10
      END


(REAL*16 ikke understøttet af g77)

Bemærk at det er valgfrit om man vil erklære variable i Fortran. Ikke
erklærede variable får type efter første bogstav i variabel navnet:
- navne der starter med I-N er INTEGER
- navne der starter med andet er REAL

Denne feature kan disables med IMPLICIT NONE statement. Det anbefales at bruge
denne option !

Man kan erklære flere variable af samme type i samme statement.

Man kan erklære konstanter via PARAMETER statement.

Vi ser lige de nye features:

      PROGRAM VARASGN
      IMPLICIT NONE
      INTEGER*4 A,B,C,ZERO
      PARAMETER(ZERO=0)
      A=1
      B=2
      C=3
      WRITE(*,*) A,B,C,ZERO
      END


Der mangler stadig to features nemlig COMMON og DATA statements, men de kommer
under subroutiner/funktioner og arrays.

operatorer

Fortran har alle de normale operatorer og basale funktioner.


C/C++/Java/C#              Fortran
-------------              -------

+                          +
-                          -
*                          *
/                          /
%                          MOD funktion
pow/Pow funktion            **
abs/fabs/Abs funktion      ABS funktion
floor/Floor funktion        AINT funktion
round/Round funktion        NINT funktion
min/Min funktion            MIN funktion
max/Max funktion            MAX funktion
==                          .EQ.
!=                          .NE.
<                          .LT.
<=                          .LE.
>                          .GT.
>=                          .GE.
&&                          .AND.
||                          .OR.


Derudover har Fortran en hel stribe matematiske funktioner:

  EXP, LOG, LOG10, SQRT
  COS, SIN, TAN, ACOS, ASIN, ATAN for radian
  COSD, SIND, TAND, ACOSD, ASIND, ATAND for grader


Bemærk at disse funktioner eksisterer for alle præcisioner af floating point.

Fortran har ogsaa nogle enkelte funktioner til brug på characters:

  LEN(S) giver længden af S
  INDEX(S,'ABC') finde 'ABS' i S
  S(3:4) laver en substring med bogstav 3-4


Vi tager et eksempel:


      PROGRAM OPS
      INTEGER*4 N,M
      REAL*8 X
      CHARACTER*16 S
      N=7
      M=5
      WRITE(*,*) N+M,N-M,N*M,N/M,MOD(N,M)
      WRITE(*,*) N.EQ.M,N.NE.M,N.LT.M,N.GT.M
      X=2.5
      WRITE(*,*) SQRT(X**2),LOG(EXP(X)),LOG10(10**X)
      WRITE(*,*) ACOS(0.0),ASIN(1.0)
C      WRITE(*,*) COSD(90.0),SIND(90.0)
      S='Dette er en test'
      WRITE(*,*) LEN(S),INDEX(S,'er'),S(7:8)
      END


(trigonometriske funktioner med grader er ikke understøttet af g77)

conditional statements

Fortran har 5 forskellige varianter af IF statement.

De første 3 er ret simple og svarer til if i andre sprog:


      IF(betingelse) singlestatement



      IF(betingelse) THEN
        multistatements
      ENDIF



      IF(betingelse) THEN
        multistatements
      ELSE
        multistatements
      ENDIF


Så har man en til at hoppe til 3 forskellige steder alt efter om en værdi er
negativ, nul eller psoitiv:


      IF(value) negativlabel,nullabel,positivlabel


Og så har man en til at hoppe til forskellige labels alt efter om en værdi
er 1,2,3,4,... (svarer til en switch som kun kan tage fortløbne integer værdier):


      GOTO(label1,label2,label3,label4) value


Der er vist brug for et eksempel:


      PROGRAM COND
      INTEGER*4 V
      V=2
C single statement IF
      IF(V.GT.1) WRITE(*,*) 'V > 1'
C block statement IF ELSE
      IF(V.GT.1) THEN
        WRITE(*,*) 'V > 1'
      ELSE
        WRITE(*,*) 'V <= 1'
      ENDIF
C arithmentic IF
      IF(V) 100,200,300
100  WRITE(*,*) 'V < 0'
      GOTO 400
200  WRITE(*,*) 'V = 0'
      GOTO 400
300  WRITE(*,*) 'V > 0'
400  CONTINUE
C  computed GOTO
      GOTO (500,600,700,800) V
500  WRITE(*,*) 'V = 1'
      GOTO 900
600  WRITE(*,*) 'V = 2'
      GOTO 900
700  WRITE(*,*) 'V = 3'
      GOTO 900
800  WRITE(*,*) 'V = 4'
      GOTO 900
900  CONTINUE
      END


(der bruges også simple GOTO statements, men det er vel indlysende hvordan de fungerer)

Den opmærksomme læser har nok opdaget nu, at Fortran kan blive noget forfærdeligt
spagetti kode. Det kan imidlertid laves rimeligt strutureret, hvis man vil.

løkker

Fortran har standard kun en enkelt løkke type nemlig DO løkken som
svarer til hvad man i andre sprog kalder en for løkke (i den simple
udgave af for løkken):


      DO label counter=start,end
        multistatements
label CONTINUE



      DO label counter=start,end,step
        multistatements
label CONTINUE


Men de fleste Fortran 77 dialekter har også en DO WHILE løkke:


      DO WHILE expression
        multistatement
      ENDDO


Lad os se et eksempel:


      PROGRAM LOOPS
      INTEGER*4 I
      DO 100 I=1,5
        WRITE(*,*) I
100  CONTINUE
      DO 200 I=1,5,2
        WRITE(*,*) I
200  CONTINUE
      I=1
      DO WHILE(I.LE.5)
        WRITE(*,*) I
        I=I+2
      ENDDO
      END


Hvis disse løkker ikke er tilstrækkelige (fordi man skal bruge do while eller en
kompleks for løkke), så bruger man bare IF og GOTO.

subroutiner/funktioner

I Fortran skelner man mellem subroutiner (void functions) og funktioner
(som returnerer en værdi).

Syntaxen ses nemmest med et eksempel:


      PROGRAM SUB
      INTEGER*4 I
      DO 100 I=1,10
        CALL TESTFAC(I)
100  CONTINUE
      END
C
      SUBROUTINE TESTFAC(N)
      INTEGER*4 N
      INTEGER*4 FAC
      EXTERNAL FAC
      WRITE(*,*) N,FAC(N)
      RETURN
      END
C
      INTEGER*4 FUNCTION FAC(N)
      INTEGER*4 N
      INTEGER*4 RES,I
      RES=1
      DO 100 I=1,N
        RES=RES*I
100  CONTINUE
      FAC=RES
      RETURN
      END


EXTERNAL bruges til at understrege at en funktion ikke er en af
de indbyggede funktioner.

En vigtig detalje er at standard Fortran 77 ikke understøtter rekursion og
at lokale variable kan være på heap og dermed bevare deres værdier mellem kald
som default (man kan tvinge dem til det med SAVE statement). De fleste
Fortran compilere idag putter dog lokale variable på stack som default og
kan dermed tillade rekursion.

Fortran har ikke rigtige globale variable som man kender det fra C/C++ eller
kan simulere i Java/C# med public static fields.

Fortran har en ret avanceret export/import metode kaldet common blokke til
mere selektivt at expose og bruge data mellem forskellige subroutiner/funktioner.


      COMMON /commonnavn/var1,var2,var3


Vi tager et lille eksempel:


      PROGRAM COMM
      INTEGER*4 I,J,K
      COMMON /B1/I
      COMMON /B2/J
      COMMON /B3/K
      I=123
      J=456
      K=65537
      CALL SUB1
      CALL SUB2
      CALL SUB3
      END
C
      SUBROUTINE SUB1
      INTEGER*4 I
      COMMON /B1/I
      WRITE(*,*) I
      RETURN
      END
C
      SUBROUTINE SUB2
      INTEGER*4 J
      COMMON /B2/J
      WRITE(*,*) J
      RETURN
      END
C
      SUBROUTINE SUB3
      INTEGER*2 K1,K2
      COMMON /B3/K1,K2
      WRITE(*,*) K1,K2
      RETURN
      END


Nummer 3 illusterer en grim lille detalje. Common blokke er reelt bare at sted
i memory, der er ikke noget type check af at de to parter opfatter det sted i
memory som samme type.

For at gøre det lidt nemmere at styre, så understøtter de fleste Fortran 77 dialekter
bruge af INLUDE statement.


      INTEGER*4 I,J
      COMMON /B/I,J



      PROGRAM COMM
      INCLUDE 'comm2.inc'
      I=123
      J=456
      CALL SUB1
      CALL SUB2
      END
C
      SUBROUTINE SUB1
      INCLUDE 'comm2.inc'
      WRITE(*,*) I
      RETURN
      END
C
      SUBROUTINE SUB2
      INCLUDE 'comm2.inc'
      WRITE(*,*) J
      RETURN
      END


IO

Fortran IO er lidt speciel men faktisk ret kraftfuldt.

De to primære IO statements er READ og WRITE.

De findes i mange varianter bl.a.:


      READ(*,*) var1,var2,...
      READ(n,*) var1,var2,...
      READ(*,formatlabel) var1,var2,...
      READ(n,formatlabel) var1,var2,...
      READ(UNIT=n,FMT=formatlabel) var1,var2,...
      WRITE(*,*) var1,var2,...
      WRITE(n,*) var1,var2,...
      WRITE(*,formatlabel) var1,var2,...
      WRITE(n,formatlabel) var1,var2,...
      WRITE(UNIT=n,FMT=formatlabel) var1,var2,...


UNIT er et fil nummer. * betyder console. 5 er console input
og 6 er console output per en meget gammel tradition.

En formatlabel består af:


label FORMAT(formatinfo)


hvor format info består af et antal komma separerede formate angivelser af formen:

nX = n mellemrum
Iw = integer med bredden w
Fw.d = floating point med bredden w og antal decimaler d
A = character
Aw = character med bredden w
'xxx' = konstant tekst streng
nHxxx = konstant tekst streng
n(...) = n forekomster af underformat
$ = undlad linieskift for output (ikke standard men almindelig understøttet)

Bemærk at per meget gammel tradition så bruges første kolonne i output
til printer styring:
  1 = side skift
  mellemrum = normal ny linie

Det er faktisk lidt komplekst, så vi tager lige et eksempel:


      PROGRAM IO
      INTEGER*4 I,N
      INTEGER*4 FAC
      EXTERNAL FAC
      WRITE(6,1000)
      READ(5,1100) N
      DO 100 I=1,N
        WRITE(6,1200) I,FAC(I)
100  CONTINUE
1000  FORMAT(1X,'Indtast max. værdi: ',$)
1100  FORMAT(I2)
1200  FORMAT(1X,I2,1X,I8)
      END
C
      INTEGER*4 FUNCTION FAC(N)
      INTEGER*4 N
      INTEGER*4 RES,I
      RES=1
      DO 100 I=1,N
        RES=RES*I
100  CONTINUE
      FAC=RES
      RETURN
      END


Og et eksempel som er en lille smule mere avanceret:


      PROGRAM IO
      INTEGER*4 I,N
      INTEGER*4 FAC
      EXTERNAL FAC
      WRITE(6,1000)
      READ(5,1100) N
      DO 100 I=1,N
        WRITE(6,1200) 'I=',I,'FAC(I)=',FAC(I),
    +                'I=',N+I,'FAC(I)=',FAC(N+I)
100  CONTINUE
1000  FORMAT(1X,'Indtast max. værdi: ',$)
1100  FORMAT(I2)
1200  FORMAT(1X,2(A2,I2,1X,A7,I8,1X))
      END
C
      INTEGER*4 FUNCTION FAC(N)
      INTEGER*4 N
      INTEGER*4 RES,I
      RES=1
      DO 100 I=1,N
        RES=RES*I
100  CONTINUE
      FAC=RES
      RETURN
      END


Skal man bruge filer, så skal man udover READ og WRITE også bruge
OPEN og CLOSE statements.

Det kan vil illustrere med et lille fil copy program:


      PROGRAM FCOPY
      INTEGER*4 IX
      CHARACTER*80 LINE
      OPEN(UNIT=1,FILE='ind.txt',STATUS='OLD')
      OPEN(UNIT=2,FILE='ud.txt',STATUS='NEW')
100  READ(UNIT=1,FMT=1000,END=300) LINE
      IX=80
200  IF(LINE(IX:IX).EQ.' ') THEN
        IX=IX-1
        GOTO 200
      ENDIF
      WRITE(UNIT=2,FMT=1100) LINE(1:IX)
      GOTO 100
300  CLOSE(UNIT=2)
      CLOSE(UNIT=1)
1000  FORMAT(A)
1100  FORMAT(A)
      END


En speciel features with Fortran IO er at standarden supporterer unformatted IO
og direct access til fixed length files, hvilket faktisk er et helt lille
database system.

Det illustreres nok også bedst med et eksempel:


      PROGRAM DIRCRE
      INTEGER*4 I
      CHARACTER*80 BUF
      OPEN(UNIT=1,FILE='db.dat',STATUS='NEW',
    +    FORM='UNFORMATTED',ACCESS='DIRECT',RECL=80)
      DO 100 I=1,100
        WRITE(BUF,1000) I
        WRITE(UNIT=1,REC=I) BUF
100  CONTINUE
      CLOSE(UNIT=1)
1000  FORMAT('Dette er record ',I3)
      END



      PROGRAM DIRLOOKUP
      INTEGER*4 R,IX
      CHARACTER*80 BUF
      OPEN(UNIT=1,FILE='db.dat',STATUS='OLD',
    +    FORM='UNFORMATTED',ACCESS='DIRECT',RECL=80)
      WRITE(6,1000)
      READ(5,1100) R
      READ(UNIT=1,REC=R) BUF
      IX=80
100  IF(BUF(IX:IX).EQ.' ') THEN
        IX=IX-1
        GOTO 100
      ENDIF
      WRITE(6,1200) BUF(1:IX)
      CLOSE(UNIT=1)
1000  FORMAT(1X,'Indtast record number: ',$)
1100  FORMAT(I3)
1200  FORMAT(1X,A)
      END


arrays

Fortran understøtter naturligvis også arrays.

Faktisk har Fortran en af de bedste understøttelser af multi dimensionelle
arrays.

Syntaxen for erlæring af arrays er simpel:


      type navn(dim)
      type navn(dim1,dim2)


Og syntaxen for brug af elementer er:

navn(index)
navn(index1,index2)

Bemærk at i Fortran starter array index med 1 ikke med 0 !

Lad os først se et simpelt eksempel:


      PROGRAM ARR
      INTEGER*4 N
      PARAMETER(N=10)
      INTEGER*4 I
      REAL*8 X(N)
      DO 100 I=1,N
        X(I)=SQRT(1.0D0*I)
100  CONTINUE
      DO 200 I=1,N
        WRITE(*,*) I,X(I)
200  CONTINUE
      END


Og lad os så se et multi dimensionelt eksempel med brug af subroutine/funktioner:


      PROGRAM MULTIARR
      INTEGER*4 N,M
      PARAMETER(N=10,M=10)
      INTEGER*4 I,J
      REAL*8 X(N,M)
      REAL*8 MXSUM
      EXTERNAL MXSUM
      DO 200 I=1,N
        DO 100 J=1,M
          X(I,J)=I*J
100    CONTINUE
200  CONTINUE
      WRITE(*,*) MXSUM(X,N,M)
      END
C
      REAL*8 FUNCTION MXSUM(X,N,M)
      INTEGER*4 N,M
      REAL*8 X(N,M)
      INTEGER*4 I,J
      REAL*8 RES
      RES=0
      DO 200 I=1,N
        DO 100 J=1,M
          RES=RES+X(I,J)
100    CONTINUE
200  CONTINUE
      MXSUM=RES
      END


Til sidst skal lige vises initialisering af arrays med DATA statement og
implied loop i output:


      PROGRAM MOREARR
      INTEGER*4 N,M
      PARAMETER(N=10,M=10)
      INTEGER*4 I,J
      REAL*8 X(N,M)
      DATA X/1*1.0d0,2*2.0d0,4*3.0d0,8*4.0d0,16*5.0d0,32*6.0d0,37*7.0/
      DO 100 I=1,N
        WRITE(6,1000) (X(I,J),J=1,M)
100  CONTINUE
1000  FORMAT(1X,10(F4.2,1X))
      END


Når man studerer output ser man at Fortran gemmer 2 dimensionelle arrays
kolonnevis og ikke rækkevis som de fleste andre sprog.

afsluttende bemærkninger

Denne artikel er naturligvis ikke en komplet gennemgang af alle features i
Fortran 77, men det skulle dække alle de mest almindelige features til at man
kan komme igang.

Ikke dækkede features inkluderer:
- statement function
- assigned GOTO
- EQUIVALENCE
- BACKSPACE
- ENTRY
- BLOCK DATA

De er nemme at opgoogle information på, hvis man har brug for det.

Skrevet søn. d. 20. juli 2008 kl. 20:47| #1

virkelig god og gennemarbejdet artikkel, meget interessant læsning :) keep up the good work!

Skrevet søn. d. 20. juli 2008 kl. 23:12| #2


Skrevet tor. d. 28. august 2008 kl. 20:38| #3

blacktiger (11.605 point)
Du skriver at fortran lige siden 77 har stået i skyggen af nyere sprog. Det vil de færreste sikkert være uenige i, men jeg synes lige det er værd at påpege fortran (desværre?) lever i bedste velgående hvis man omgås folk i de rigtige kredse. F.eks. er fortran næsten de facto sproget hvis man laver astrofysik.

Skrevet søn. d. 19. oktober 2008 kl. 19:45| #4


Skrevet ons. d. 10. juni 2009 kl. 23:26| #5

acore (11.729 point)
Hvor blev jeg nostalgisk, da jeg læste denne her udmærkede artikel.

Hvis beregnings-hastigheden er vigtig og man arbejder med fler-dimensionelle data, så er der ikke meget, der slår FORTRAN.

Og helt enig med blacktiger - det er svært at gøre op med tradition og eksisterende kode-biblioteker.

Skriv en kommentar



Mest populære guides

Guidens karakter
!!!Karaktér: 3
12 stemmer
31/01 - 2011
Af: heinzdmx

Dropbox - gratis online lagerplads

Jeg vil i denne guide forklare lidt om hvad Dropbox er og også hvordan du får mest mulig plads på Dropbox. Dropbox er kort sagt en service hvor du har dine data lagt til backup på både nettet og din egen computer.
Guidens karakter
!!!Karaktér: 4
33 stemmer
02/02 - 2009
Af: jkrons

Dato- og tidsberegninger i Excel

En introduktion til simple beregninger med dato og tid i Excel. Opdateret med afsnit om beregning af tillæg.
Excel  |  Læs »
Guidens karakter
!!!Karaktér: 4
21 stemmer
06/11 - 2011
Af: fromsej

Sådan fjerner du virus og malware

Udviklingen går stærkt på "skidt"fronten, så vi har sammensat en ny og effektiv programpakke til fjernelse af det.
Virus  |  Læs »

Log ind

   

   

Seneste guides

Installer win 7
Den gode bruger


   




Tips & Tricks fra PC World

Teaser billede

Her er fem sjove danske websider du skal kende

Trænger dine lattermuskler til en omgang fitness på dansk? Vi viser vej til fem websider fyldt med humor og vanvittig satire.


Anmeldelser fra PC World

Teaser billede

Test: Denne super-tablet er iPads hårdeste konkurrent

Eee Pad Transformer Prime er frygtindgydende med sin quadcore processor og evne til at trylle sig om til bærbar. Apple bør kigge i bagspejlet, for Asus' tablet-pc kommer buldrende - og gør det...


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Nu kan du snart hente Windows 8

Den nye offentlige betaversion af Windows 8 er klar i denne måned.


Nyheder fra Computerworld

Teaser billede

Måske snart slut med Androids helt store problem

Android-platformen har længe været plaget af et særligt problem. Men måske er problemet nu ved at være elimineret.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger