Récemment, j'ai vu deux articles disant "J'ai écrit une liste de liens en langage C". Tous ont été écrits en langage C, j'ai donc commenté le style d'écriture orienté objet.
J'ai décidé d'écrire cet article en espérant qu'écrire dans un style orienté objet m'aiderait à comprendre orienté objet. Sans la difficile façon de penser orientée objet, nous utilisons les classes comme une version étendue du type structure = user-defined.
Voir d'autres articles et sites pour une liste de liens. Référence: https://ja.wikipedia.org/wiki/ Liste liée
Tout d'abord, préparez deux types de structures à utiliser pour la liste de liens.
struct node
: éléments de listestruct list
: Gestion de la liste de liens pour node
Utilisez les règles suivantes pour écrire dans un style orienté objet.
typedef
le pointeur vers la structure ** comme ** nom de classe **nouveau
**new
, cette fonction est appelée" ** constructeur ** "#include <stdio.h>
#include <stdlib.h>
typedef const char *String;
void *new(size_t size)
{
void *memory = malloc(size);
if (memory == NULL) {
fprintf(stderr, "Out of memory\n");
exit(8);
}
return memory;
}
/*
* class Node {
*/
typedef struct node {
int data;
struct node *next;
} *Node;
Node Node_new(int data)
{
Node node = new(sizeof(*node));
node->data = data;
node->next = NULL;
return node;
}
void Node_output(Node node, String separator) {
printf("%d%s", node->data, separator);
}
void Node_free(Node node)
{
node->next = NULL;
free(node);
}
/* } */
/*
* class List {
*/
typedef struct list {
Node head;
Node tail;
} *List;
List List_new()
{
List list = new(sizeof(*list));
list->head = NULL;
list->tail = NULL;
return list;
}
void List_add(List list, int data)
{
Node node = Node_new(data);
if (list->head == NULL) {
list->head = node;
list->tail = node;
} else {
list->tail->next = node;
list->tail = node;
}
}
void List_input(List list)
{
int size;
if (scanf("%d", &size) != 1) {
fprintf(stderr, "Invalid size\n");
exit(1);
}
for (int i = 0; i < size; i++) {
int data;
if (scanf("%d", &data) != 1) {
fprintf(stderr, "Invalid data\n");
exit(2);
}
List_add(list, data);
}
}
void List_output(List list)
{
for (Node node = list->head; node != NULL; node = node->next) {
Node_output(node, " ");
}
printf("\n");
}
void List_free(List list)
{
Node node = list->head;
while (node != NULL) {
Node next = node->next;
Node_free(node); // cannot access node members after here
node = next;
}
list->head = NULL;
list->tail = NULL;
free(list);
}
/* } */
int main(void)
{
List list = List_new();
List_input(list);
List_output(list);
List_free(list);
}
Le tableau ci-dessous montre les différences entre le langage C et Python.
Langage C | Python |
---|---|
Déclaration de variable | Inutile Lorsque vous affectez une variable, elle devient un dictionnaire de variables {Nom de variable:valeur} Les variables sont enregistrées sous la forme de. |
Définition de la structure | Inutile Vous pouvez librement affecter des variables à l'instance |
Définition du typetypedef |
Définition de classe Entier 123 Automatiquementint Du moule123 Une instance est créée. |
Opérateur d'accès aux membres du pointeur-> |
Opérateur d'accès aux membres de l'instance. |
NULL | None |
Le bloc de traitement est{ Quand} Entourez de |
Le bloc de traitement abaisse le retrait |
printf une fonction |
print une fonctionCependant, il sera automatiquement cassé. Quand il n'y a pas de saut de ligne end Spécifiez à la place du caractère de saut de ligne dans l'argument. |
malloc une fonction |
nom de la classe() class定義するとメモリ確保une fonction(コンストラクタ)が自動的に作られる nom de la classeがメモリ確保une fonction名になる。 |
free une fonction |
Inutile Les zones de mémoire qui ne sont plus utilisées sont automatiquement renvoyées. del Vous pouvez également le renvoyer de force avec une phrase. |
scanf une fonction| inputune fonction<br>Lisez une ligne de chaîne de caractères.<br>Conversion d'entiers intune fonction。<br>Division à blanc split`Méthode. |
A titre de comparaison, nous avons défini une classe new
qui réserve une zone mémoire vide (instance).
class new:
pass
#
# class Node {
#/
def Node_new(data):
node = new()
node.data = data
node.next = None
return node
def Node_output(node, separator):
print(node.data, end=separator)
# }
#
# class List {
#/
def List_new():
list = new()
list.head = None
list.tail = None
return list
def List_add(list, data):
node = Node_new(data)
if list.head is None:
list.head = node
list.tail = node
else:
list.tail.next = node
list.tail = node
def List_input(list):
size = int(input()) #Non utilisé en Python
for data in input().split():
List_add(list, int(data))
def List_output(list):
node = list.head
while node is not None:
Node_output(node, " ")
node = node.next
print()
# }
def main():
list = List_new()
List_input(list)
List_output(list)
del list
if __name__ == '__main__':
main()
En définissant Node et List en tant que classes, la mémoire sera allouée pour chaque classe, éliminant ainsi le besoin de la nouvelle classe.
Le processus d'initialisation est écrit dans la méthode __init __
. Il sera appelé automatiquement après l'allocation de mémoire par le constructeur.
Un espace de noms est créé en définissant une classe, et les fonctions définies dans la classe peuvent être utilisées comme des fonctions différentes même si les noms entrent en conflit avec les fonctions d'autres classes, donc "** nom de classe et trait de soulignement **" Retirer.
J'ai écrit nom de la classe_ nom de la méthode (instance, autres arguments)
Si vous écrivez ʻinstance.method (autre argument) , Il appelle
nom de classe.nom de méthode (instance, autres arguments)`.
Il est habituel de nommer la variable d'instance comme premier argument de la méthode à «self».
class Node:
def __init__(self, data):
self.data = data
self.next = None
def output(self, separator):
print(self.data, end=separator)
class List:
def __init__(self):
self.head = None
self.tail = None
def add(self, data):
node = Node(data)
if self.head is None:
self.head = node
self.tail = node
else:
self.tail.next = node
self.tail = node
def input(self):
size = int(input()) #Non utilisé en Python
for data in input().split():
self.add(int(data))
def output(self):
node = self.head
while node is not None:
node.output(" ")
node = node.next
print()
def main():
list = List()
list.input()
list.output()
del list
if __name__ == '__main__':
main()
La grammaire de base est la même que celle du langage C. Considérez une classe comme une version étendue d'une structure. Vous pouvez écrire des définitions de fonction dans la structure et définir librement des membres et des méthodes sans vous soucier des conflits de noms avec d'autres classes. L'argument d'instance du premier argument de la méthode n'a pas besoin d'être décrit, et le premier argument implicite «this» est automatiquement défini et l'instance est affectée. La même méthode que le nom de la classe sera le constructeur. Étant donné que l'instance est définie implicitement, il n'est pas nécessaire de décrire le type de retour ou le retour. scanf est remplacé par la classe Scanner.
LinkedList.java
import java.util.Scanner;
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
void output(String separator) {
System.out.print(this.data + separator);
}
}
class List {
Node head;
Node tail;
List() {
this.head = null;
this.tail = null;
}
void add(int data) {
Node node = new Node(data);
if (this.head == null) {
this.head = node;
this.tail = node;
} else {
this.tail.next = node;
this.tail = node;
}
}
void input() {
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
for (int i = 0; i < size; i++) {
int data = scanner.nextInt();
add(data);
}
}
void output() {
for (Node node = this.head; node != null; node = node.next) {
node.output(" ");
}
System.out.print("\n");
}
}
public class LinkedList {
public static void main(String[] args) {
List list = new List();
list.input();
list.output();
}
}
Recommended Posts