Puntatori in C contro Nessun puntatore in PHP

2

Entrambe le lingue hanno la stessa sintassi.

Perché C ha il carattere * strano che denota i puntatori (che è una sorta di indirizzo di memoria dei contenuti delle variabili?), quando PHP non ce l'ha e puoi fare praticamente le stesse cose in PHP che puoi fare in C, senza indicazioni? Immagino che il compilatore PHP lo gestisca internamente, perché C non fa lo stesso?

Questo non aggiunge complessità non necessaria in C? Ad esempio non li capisco:)

    
posta AnnaBanana 12.04.2012 - 00:24
fonte

9 risposte

24

Come tante cose, la risposta è nella forma "Perché X e Y sono cose diverse con scopi diversi".

In questo caso, i progettisti di entrambe le lingue presumevano che gli utenti delle loro lingue avessero un insieme di obiettivi molto diverso. Per C, il caso d'uso principale era "linguaggio assembly portatile", il che significa davvero scendere nel nocciolo di come il computer sta effettivamente gestendo le sue risorse. Non c'è un modo pratico per evitare la manipolazione degli indirizzi di memoria al livello più basso di astrazione, e quindi C ha un solido supporto per questo.

PHP aveva lo scopo di rendere il contenuto della pagina web dinamico il più flessibile e indolore possibile. Questo è un bel po 'di passi dal livello super-basso del mondo C; gestire la memoria è, per gli scopi che il PHP intende affrontare, un livello troppo basso per essere di molto interesse. Qualsiasi tipo di gestione automatica della memoria andrebbe bene, fintanto che è robusto e affidabile, e rimane fuori mano. Questa è esattamente la situazione che vedi in PHP; gli oggetti vengono allocati automaticamente, quando necessario, e la garbage collection quando non sono più utilizzabili, e tutto avviene senza l'intervento del programmatore PHP.

Forse è interessante osservare che PHP è esso stesso scritto in C! il nocciolo della gestione della memoria è scritto in C, che fornisce gli strumenti necessari per fare quel genere di cose, in modo che il linguaggio creato non richieda al programmatore di fare molto da solo.

    
risposta data 12.04.2012 - 00:36
fonte
12

In realtà non puoi fare le stesse cose in PHP, se si tratta di hardware (fisico, non finto virtuale) e / o bitmap video (ecc.) in indirizzi fisici fissi non rimappati, forse in un numero limitato di Cicli della CPU.

I siti Web non sono le uniche cose gestite dal software.

    
risposta data 12.04.2012 - 01:20
fonte
4

PHP è in realtà un linguaggio estremamente limitato. Può fare bene una cosa - produrre pagine Web - perché è stato progettato solo per fare una cosa sola. Ma se volessi creare un gioco in 3D, o scrivere un sistema operativo, o creare un concorrente in Photoshop, non vorrai farlo in PHP!

C, d'altra parte, è un linguaggio generico. Inizialmente è stato progettato per costruire sistemi operativi, che forniscono un'interfaccia tra l'hardware e il resto del software. Per fare ciò, è necessario un concetto di accesso diretto alla memoria. Ad esempio, se si desidera inviare qualcosa a una stampante, è necessario essere in grado di inviare dati su una rete, è necessario essere in grado di scrivere direttamente nella posizione in cui si trova il buffer di input dell'hardware di rete. a cosa servono realmente i puntatori.

Il problema con i puntatori in C, e la cosa che li rende difficili da capire, è che in C vengono usati come "martello magico". Le lingue precedenti avevano modi migliori per fare certe cose che in C sono disponibili solo usando i puntatori. (FORTRAN aveva un pass-per-riferimento, e ALGOL e Pascal avevano matrici reali, per esempio: C non ha né; devi fingere entrambi con i puntatori abusivi.) Dal momento che sono usati dappertutto per molte cose diverse che possono e dovrebbe essere fatto in altri modi, rende difficile capire di cosa si tratta.

    
risposta data 12.04.2012 - 00:39
fonte
3

Sì a tutti i precedenti. Ma ci sono altre cose da considerare.

(type *T) list ~ (type T) list[]  // pointer can be used as an alias for an array

L'unica differenza è che un array è un puntatore costante, il che significa che non può essere riassegnato per puntare a qualcos'altro. E,

*(list + n) = list[n].

Per ordinare una lista, specialmente una multidimensionale, è più efficiente per spostare semplicemente i puntatori. Non è necessario copiare e trascinare i dati.

Cosa (* = deferenza) significa dipende dal contesto. I puntatori sono sempre dichiarati che lo usano, per esempio. char *p , int *n , struct record *rec .

In una dichiarazione (*) restituisce il valore puntato a. Così.

char ch = *p;   // ch = value p is currently pointing at.

In C ++ è possibile utilizzare i puntatori per ottenere dati o metodi della classe base da una classe derivata, a condizione che le classi siano definite correttamente.

Certamente, la comprensione dei puntatori richiede tempo, ma la necessità spesso facilita usi fantasiosi.

Confrontalo con PHP che è progettato principalmente per essere un back-end linguaggio. Sebbene possa essere sofisticato nell'implementazione, non è stato progettato per calcolo robusto.

    
risposta data 23.09.2012 - 05:14
fonte
2

I puntatori in C servono a tre scopi principali:

Fake pass-by-reference

C passa tutti gli argomenti della funzione in base al valore; i parametri formali e i parametri attuali sono oggetti diversi nella memoria, quindi le modifiche al parametro formale non si riflettono nel parametro attuale. Se si desidera che una funzione modifichi il valore di qualcosa nel chiamante, è necessario passare il puntatore a tale oggetto:

void swap(int *a, int *b)
{
  int tmp = *a;
  *a = *b;
  *b = tmp;
}

int main(void)
{
  int x = 3, y = 4;
  swap(&x, &y);
  return 0;
}

Le espressioni *a e *b in swap corrispondono agli oggetti x e y in main , quindi scrivendo a *a aggiorna x e scrivendo su *b updates y .

Tracciamento memoria allocata dinamicamente

Le funzioni di allocazione della memoria C malloc , calloc e realloc tutti i puntatori di ritorno al primo elemento del buffer allocato dinamicamente.

int *arr = malloc(sizeof *arr * N); // allocates a block of memory large
                                    // enough to hold N ints

È possibile applicare l'operatore di pedice a un puntatore come se fosse un array (l'operazione di pedice a[i] è equivalente a *(a + i) , ovvero offset i elementi da a e dereferenzia il risultato).

Creazione di strutture dati auto-referenziali

Sebbene generazioni di programmatori di Fortran stessero costruendo liste, alberi, code, pile, ecc., senza di essi, i puntatori rendono molto facile la costruzione di strutture autoreferenziali, come questo nodo ad albero binario:

struct tnode {
  K key;                // for some arbitrary type K
  T data;               // for some arbitrary type T
  struct tnode *left;   // explicitly points to left subtree
  struct tnode *right;  // explicitly points to right subtree
};

Non ho familiarità con PHP per dire come faresti queste cose in quella lingua. Vorrei sottolineare che C precede PHP di almeno un paio di decenni e che PHP è piuttosto specifico per un particolare dominio.

Riguardo al perché C non gestisce tutto questo automaticamente ...

Una delle filosofie guida di C è mantenere la lingua il più semplice possibile, rendendola relativamente facile da implementare. La gestione automatica della memoria aggiungerebbe un po 'di complessità al linguaggio (certamente l'aggiunta della libreria di threading in C11). Senza contare che la gestione automatica della memoria può anche giocare all'inferno con un codice critico per le prestazioni.

    
risposta data 12.04.2012 - 04:48
fonte
1

PHP ti permette di usare i puntatori, come puoi vedere nella documentazione ufficiale su Riferimenti .

Non è esattamente la stessa cosa di C, poiché quest'ultimo ti consente di allocare la memoria in modo molto preciso, ma i puntatori sono presenti in molte lingue.

In sostanza, ricorda che ogni volta che crei un array o una classe in un linguaggio orientato agli oggetti (C ++, C #, Java, ...) crei effettivamente un puntatore che è memorizzato nella variabile. Ciò che ti consente di saltare gli operatori * è una specie di zucchero sintattico.

    
risposta data 12.04.2012 - 00:41
fonte
1

C è un linguaggio di programmazione dei sistemi, che può essere usato per creare cose come driver di dispositivo, software embedded e sistemi operativi.

PHP è un linguaggio di scripting usato per creare siti web.

Non sono affatto la stessa cosa. Mele e arance.

Non è vero che entrambe le lingue hanno la stessa sintassi. Il linguaggio C richiede che le variabili siano esplicitamente dichiarate. PHP deduce il tipo di una variabile dal suo utilizzo. Il passaggio dei parametri è diverso. Le regole sull'ambito della variabile sono diverse. Ci sono alcune somiglianze sintattiche, ma non è vero che usano la stessa sintassi.

Le operazioni orientate agli indirizzi (abilitate dalla disponibilità di puntatori) sono richieste da molte attività di basso livello utilizzate per il linguaggio C.

    
risposta data 12.04.2012 - 03:02
fonte
1

È possibile ottenere gran parte delle funzionalità dei puntatori utilizzando le operazioni su interi su un indice di array. Questo indice intero è spesso chiamato cursore .

Invece di manipolare un valore del puntatore char *p , puoi manipolare il cursore int i e indicizzare l'array arr[i] per ottenere il valore in quella cella di memoria.

In una certa misura, questo è solo mettere nomi di fantasia su fatti ovvi. Ma avere nomi dà credibilità a una tecnica valida che può essere facilmente trascurata. :)

Il vero vantaggio è che la familiarità con questo ti permette di tradurre il codice usando i puntatori in lingue che non li hanno.

    
risposta data 31.07.2013 - 09:27
fonte
0

C è un linguaggio di basso livello, è praticamente un passo rimosso da Assembly (e C è stato progettato per essere un assembly portatile). È un'astrazione della macchina, e usa i puntatori perché consente di operare a livello di macchina, e quindi utilizzeresti puntatori per accedere direttamente alla memoria (la memoria virtuale ha reso questa pratica per lo più arcana).

Si noti che C è stato creato negli anni '70, quando i computer erano molto più semplici di adesso, e l'indirizzamento diretto della memoria era il modo in cui il software funzionava. I puntatori sono anche usati per cose come gli array (si potrebbe dire che gli array sono zucchero sintattico per i puntatori in C) e l'allocazione dinamica della memoria per creare dati le cui dimensioni potrebbero essere sconosciute in fase di compilazione.

PHP è molto più recente di C (fine anni '90) ed è strongmente influenzato da C nella sua progettazione, ma, come molti altri linguaggi più recenti di C, astrae l'uso del puntatore grezzo e utilizza invece cose come Riferimenti , che sono come puntatori limitati, in quanto possono fare riferimento ad altri dati, ma non puoi fare cose come eseguire l'aritmetica del puntatore, né rappresentano gli indirizzi.

PHP è stato progettato per essere facile da imparare per le persone, e un punto critico che molti programmatori hanno quando usano C (o C ++) è puntatori, quindi PHP e molti altri linguaggi distruggono i puntatori e usano riferimenti, oggetti, allocazione implicita dell'heap, ecc. per nascondere l'utilizzo del puntatore da parte dell'utente. Internamente, PHP utilizzerà i puntatori (dopo tutto è scritto in C), ma tu stesso non devi preoccupartene.

Come complicare la C? Penso che C sia un linguaggio piuttosto semplice (il libro di fatto è di 300 pagine e più corto della maggior parte degli altri libri di lingue), ma i puntatori fanno un po 'di lavoro mentale per capire.

    
risposta data 12.04.2012 - 00:40
fonte

Leggi altre domande sui tag