Wikilibros eswikibooks https://es.wikibooks.org/wiki/Portada MediaWiki 1.47.0-wmf.11 first-letter Medio Especial Discusión Usuario Usuario discusión Wikilibros Wikilibros discusión Archivo Archivo discusión MediaWiki MediaWiki discusión Plantilla Plantilla discusión Ayuda Ayuda discusión Categoría Categoría discusión TimedText TimedText talk Módulo Módulo discusión Evento Evento discusión Wikilibros:Café 4 9 427881 427804 2026-07-15T19:04:11Z Antimundo 74354 /* Estandarización de las categorías de libros */ Respuesta 427881 wikitext text/x-wiki {{Wikilibros:Café/Cabecera}} {{Usuario:MABot/config |archive = Wikilibros:Café/Archivo/%(year)s |algo = old(45d) |counter = 1 |archiveheader = {{Archivo}} |minthreadsleft = 0 |minthreadstoarchive = 1 }} == Petición para renombrar los «Proyectos» a «Wikiproyectos» == Propongo renombrar los actuales «Proyectos» a «Wikiproyectos». Y que usen su propio espacio de nombres. Por ejemplo, en vez de «Wikilibros:Proyecto mantenimiento», pasaría a llamarse «Wikiproyecto:Mantenimiento» al igual que en otros proyectos de Wikimedia. Hasta donde he podido investigar, el nombre «Proyectos» se empezó a usar en 2008 porque así los llamó el usuario que los creó, sin una consulta o consenso previo documentado. Personalmente, considero que «Wikiproyecto» es un término mas claro y preciso. Cuando hablamos de un «Wikiproyecto» se entiende inmediatamente que nos referimos a un espacio concreto de coordinación dentro de la wiki, no a un proyecto en el sentido abstracto y general. Además, considero que sería positivo por consistencia con otros proyectos de Wikimedia. Históricamente, muchos usuarios valiosos de Wikilibros eran colaboradores de Wikipedia en español, donde se llaman «Wikiproyectos». Mantener una terminología familiar facilita la adaptación de un proyecto a otro y evita confusiones innecesarias por diferencias arbitrarias de nomenclatura. En varias ediciones de Wikilibros y Wikipedia en otros idiomas también se utiliza esta denominación: * En Wikibooks y Wikipedia en inglés se llaman «WikiProjects». * En Viquillibres y Wikipedia en catalán se llaman «Viquiprojectes». * En Wikiliburuak y Wikipedia en euskera se llaman «wikiproiektuak». * En Wikipedia en gallego se llaman «Wikiproxectos». También es cierto que no todas las ediciones de Wikilibros usan este concepto, por ejemplo, algunas como la francesa o la italiana ni si quiera tienen ninguna estructura equivalente de «Wikiproyectos». Pero muchas sí la tienen y, especialmente en proyectos como Wikipedia en Español, de donde surgen muchos colaboradores de esta wiki sí se llaman así. Hacer el traslado, además, sería muy sencillo, ya que actualmente solo existen 7 páginas en el actual «Wikilibros:Proyectos». Por eso quería plantearlo aquí primero y conocer si alguien mas está de acuerdo antes de realizar el traslado. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 07:55 23 jun 2026 (UTC) : No veo necesario realizar este cambio. : En primer lugar, creo que es importante distinguir qué es un Wikiproyecto y cuál es la realidad actual de Wikilibros. Históricamente, los Wikiproyectos surgieron en Wikipedia como espacios de coordinación de grupos de editores que comparten un interés temático o una meta editorial común. Su objetivo principal es organizar esfuerzos colectivos para desarrollar contenidos específicos, establecer estándares y coordinar trabajo entre varios participantes. : Si observamos la definición utilizada en Wikibooks en inglés, en la página "[[b:Wikibooks:WikiProject|WikiProject]]", estos espacios se describen principalmente como lugares destinados a coordinar la creación y desarrollo de libros. Es decir, se trata de iniciativas colaborativas enfocadas en la construcción de contenido, más que en la existencia de grupos reducidos dedicados a tareas administrativas o de mantenimiento. : La situación actual de Wikilibros en español es bastante distinta. Actualmente no existe una comunidad activa y numerosa que participe de manera sostenida en proyectos temáticos o grupos de trabajo especializados. Los espacios existentes funcionan más como páginas organizativas o de coordinación puntual que como verdaderos Wikiproyectos en el sentido en que se entiende el término dentro del movimiento Wikimedia. : Por ello, considero que adoptar la denominación «Wikiproyecto» podría incluso resultar confuso, ya que transmite la idea de una estructura comunitaria activa y consolidada que actualmente no existe. El nombre «Proyecto» cumple adecuadamente la función de identificar estos espacios sin atribuirles una naturaleza que, en la práctica, no poseen. : Tampoco veo una necesidad funcional que justifique crear un espacio de nombres específico. El sistema actual funciona correctamente, las páginas son pocas y su localización resulta sencilla. El cambio no resolvería ningún problema operativo ni facilitaría tareas que actualmente sean difíciles de realizar. : Respecto a la consistencia con otros proyectos Wikimedia, si bien es cierto que muchas Wikipedias utilizan el término «Wikiproyecto», también es cierto que cada proyecto ha desarrollado históricamente sus propias convenciones organizativas. La mera existencia de una denominación distinta en otros proyectos no constituye, por sí sola, una razón suficiente para modificar una estructura local que lleva años funcionando sin inconvenientes. : Finalmente, si el principal motivo es una cuestión estética o de preferencia terminológica, considero que no debería procederse al cambio. Los cambios de nomenclatura y espacios de nombres deberían responder a una necesidad práctica, organizativa o técnica claramente identificable. En este caso, no observo un beneficio concreto para los usuarios ni para el desarrollo de Wikilibros que justifique el traslado de páginas y la modificación de una convención establecida. [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 18:23 23 jun 2026 (UTC) ::Bien argumentado, me has convencido. Tienes razón en que estos «Proyectos» en Wikilibros sirven actualmente como espacio de coordinación puntual para tareas administrativas y de mantenimiento generales, y funcionan de manera distinta a cómo lo hacen los «Wikiproyectos» de otras wikis donde son espacios temáticos o grupos de trabajos especializados. ::Dicho esto, considero que si en un futuro surgiesen estos espacios y tuviesen el mismo propósito que tienen los Wikiproyectos en otras wikis como la Wikipedia en español, si me parecería que en tal caso deberían llamarse «Wikiproyectos» por lo que argumenté en mi primer mensaje. ::Pero estoy de acuerdo contigo en que, como esa no es la realidad ahora como bien has señalado, por mí queda consensuado que de momento los actuales proyectos se pueden quedar con ese nombre. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 18:55 23 jun 2026 (UTC) == RFC about AI-generated content in Wikimedia Commons == <bdi lang="en" dir="ltr">Apologies for writing in English, please help translate this message to your language. You are invited to participate in a [[c:Commons:Requests for comment/Policy update for AI content|request for comment on Wikimedia Commons about a policy update for AI content]]. This may affect files that are uploaded to Wikimedia Commons for use on this project. Thank you. [[m:User:Codename Noreste|Codename Noreste]] ([[m:User talk:Codename Noreste|discusión]])</bdi> 17:11 23 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Codename Noreste@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 --> == Incorporación del enlace «Contactos legales y de seguridad» en el pie de página de vuestra wiki == <section begin="Message"/> '''Contactos legales y de seguridad''' Hola a toda la comunidad: la Fundación Wikimedia ha puesto a vuestra disposición una [[wmf:Special:MyLanguage/Legal:Wikimedia Foundation Legal and Safety Contact Information|página única de contacto sobre cuestiones legales y de seguridad]], que debéis incluir en el pie de página de vuestra wiki para garantizar el acceso a información jurídica precisa. Se trata de un requisito normativo. Ya hemos implementado enlaces a las wikis en inglés, alemán, italiano, español y otros idiomas de Wikipedia, y pronto los implementaremos en vuestra wiki. [[m:Special:MyLanguage/Wikimedia_Foundation_Legal_and_Safety_Contacts_FAQ|Por favor, leed más información en la página del proyecto]] y dejad vuestros comentarios en este hilo o en la [[m:Special:MyLanguage/Talk:Wikimedia Foundation Legal and Safety Contacts FAQ|página de discusión]]. <section end="Message"/> -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 13:30 25 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Sannita (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=30731267 --> == Petición para establecer una política sobre inteligencia artificial == Buenas. En el tiempo que llevo en Wikilibros, he observado varias páginas editadas mediante copias directas de texto generado por chatbots de IA (como ChatGPT, Copilot, Claude, Gemini, o Grok). Esto me preocupa, ya que este tipo de ediciones pueden resultar muy perjudiciales, y mientras que en muchas otras wikis ya se han establecido políticas sobre el uso de IA, en Wikilibros aún no tenemos ninguna política específica al respecto. Wikilibros en inglés cuenta con una política prohibiendo explícitamente esta clase de ediciones, que además explica el daño que pueden llegar a hacer, traduzco: {{Cita|Solicitar a un chatbot que escriba un libro o un ensayo puede dar lugar a la producción de [[W:Alucinación (inteligencia artificial)|invenciones completas]], incluyendo referencias ficticias. El resultado puede ser sesgado, difamar a personas reales, infringir derechos de autor o simplemente ser de mala calidad. <br>...<br> Estos problemas pueden volverse rápidamente problemáticos en comunidades y entornos grandes donde la transferencia de conocimiento, la verificabilidad, la rendición de cuentas y el pensamiento crítico son importantes. En particular, el alto volumen y la velocidad a la que los LLM pueden generar contenido, todo el cual debe ser verificado, implica que su uso supone un riesgo considerable. Por lo tanto, los materiales de aprendizaje de idiomas no deben utilizarse para generar o resumir material e ideas en Wikibooks, y no se debe confiar ciegamente en sus fuentes. |[https://en.wikibooks.org/wiki/Wikibooks:Artificial_intelligence Extraído y traducido de la política de Wikibooks (en inglés) sobre el uso de IA.] }} Wikipedia en Español también [[w:Wikipedia:Redacción de artículos con modelos de lenguaje grandes|cuenta con una política sobre este asunto]] que me parece correcta. Como Wikilibros en Español es una wiki tan pequeña, quizás sea mas adecuado adaptar o traducir la política de Wikibooks en inglés, o simplemente redirigir o adaptar la política de Wikipedia en español. En mi opinión, las políticas de estas wikis son sólidas, y además, han sido redactadas y consensuadas por más usuarios de los que tenemos aquí, por lo que cuentan con un buen consenso, y están más desarrolladas y probadas en comunidades más grandes. Quedo a la escucha de comentarios, y espero que podamos avanzar en este frente. Menciono a @[[Usuario:Mazbel|Mazbel]] que siempre es de gran ayuda. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 17:33 27 jun 2026 (UTC) :Creo que sí sería conveniente que Wikilibros contara con una política específica sobre el uso de la IA, no tanto porque sea una tecnología distinta a otras herramientasd e edición, sino por la escala a la que permite generar contenido. A diferencia de Wikipedia, aquí no construimos artículos independientes, sino libros completos y materiales de aprendizaje, donde la estructura, la coherencia y la progresión de los contenidos son partwe esencial de la calidad de la obra. Un texto generado por IA puede ser correcto en términos generales y, aun así, presentar problemas de organización, inconsistencias entre capítulos, ejemplos poco adecuados o explicaciones que no responden a un criterio didáctico claro. Detectar ese tipo de problemas exige una revisión completa del libro, algo que en una comunidad pequeña como eswikibooks rara vez es posible cuando se incorporan grandes cantidades de contenido. :Por ello, considero que una política debería ser relativamente estricta con la incorporación de texto generado por IA. No porque toda utilización de estas herramientas sea necesariamente perjudicial, sino porque el riesgo de publicar contenido insuficientemente revisado es mayor que la capacidad que tiene la comunidad para detectarlo y corregirlo. En mi opinión, la IA puede tener cabida como herramienta de apoyo durante el proceso de redacción, pero no debería emplearse para generar de forma directa partes sustanciales de un libro destinadas a su publicación. En un proyecto con pocos editores activos, resulta más prudente priorizar la calidad y el mantenimiento de los libros que facilitar un aumento rápido de contenido cuya revisión efectiva no puede garantizarse. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:49 27 jun 2026 (UTC) ::Estoy de acuerdo con todo lo que has dicho, especialmente con tu segundo párrafo, del que suscribo cada palabra al 100%. ::Lo de adaptar una política de otra wiki, lo mencioné en gran medida, no por la dificultad en sí de redactarla, si no porque en estos lugares ya existe consenso, y así puede ser más fácil ponerse de acuerdo. Pero si en Wikilibros en español también estamos todos más o menos de acuerdo, no veo por qué no podríamos redactar la nuestra propia. ::Concuerdo totalmente en que habría que ser relativamente estricto, porque por los chatbots de IA pueden generar enormes cantidades de texto, y al ser una comunidad tan pequeña no tenemos capacidad para pararnos a revisar un libro que se generase con IA. ::En este sentido, la política de enWikibooks me parece suficientemente estricta, además, [https://en.wikibooks.org/wiki/Wikibooks_talk:Artificial_intelligence/Archive_1 se puede leer el debate que tuvieron para alcanzar tal consenso (en inglés)] que es muy interesante. ::Según la política enWikibooks: ::# Se advierte brevemente de que el contenido de IA puede ser inexacto, inventado o de baja calidad. (Personalmente creo que además podría advertirse de los posibles problemas de copyright que puede llegar a causar). ::# No se permite usar IA para generar, resumir o traducir contenido. ::# Está explícitamente prohibido hacer ediciones que consistan en copiar y pegar texto de IA en páginas. ::# Se avisa de que el contenido debe ser siempre verificado y escrito por humanos. ::# No se prohíbe que alguien consulte o haga uso de la IA como apoyo externo, lo que está prohibido es que la IA genere el contenido, pero uno puede usarla para consulta externa si lo desea. ::Considero que podríamos basarnos en la política de enWikibooks y traducirla y adaptarla a nuestra versión. Si estamos más o menos de acuerdo en que es adecuada, sería muy sencillo incorporar esta política. Si os parece bien esto, podría escribirla basándome en enWikibooks y luego mencionaros para que la reviséis. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:47 27 jun 2026 (UTC) : De acuerdo a que en conjunto establezcamos una política en base al uso de IA. Es algo que se debe de tocar acá y me parece buen puerto, el guiarnos de la política establecida desde enWikibooks [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 02:29 28 jun 2026 (UTC) ::Buenas @[[Usuario:Mazbel|Mazbel]] y @[[Usuario:Divinations|Divinations]] he tomado la iniciativa y redactado la página «''[[Wikilibros:Política sobre el uso de inteligencia artificial generativa]]''» (que de momento está marcada como un borrador). Esta página está traducida y adaptada de la versión de enWikibooks, me he inspirado también en la conversación que hemos tenido por aquí, y en la misma política en la Wikipedia en español. ::Os agradecería si pudieseis revisar esta página, sentíos libres de editarla si lo consideráis, y os invito a continuar esta conversación en la discusión de esta página. Gracias por vuestra colaboración en este asunto. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 09:33 28 jun 2026 (UTC) :::<s>Gracias, [[Usuario:Antimundo|Antimundo]]. Añadí un atajo para que pueda ser encontrada más fácilmente. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 17:47 28 jun 2026 (UTC)</s> ::::Parece que se borró. Creo que me adelanté antes de tiempo, mejor esperar a obtener un mejor consenso comunitario más allá de solo tres usuarios. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:44 28 jun 2026 (UTC) : Me temo que antes de formarse como una política dentro de Wikilibros, debe ser llevada a votación, un aviso tanto para @[[Usuario:Antimundo]] como para @[[Usuario:Divinations]]. Estoy adaptando el contenido para que se proceda a votación. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 20:52 28 jun 2026 (UTC) ::Entendido, gracias por iniciar el procedimiento. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:01 28 jun 2026 (UTC) == Votación sobre nueva política sobre el uso de la inteligencia artificial == En relación con el hilo anterior, se abrió una página de votación para establecer como una nueva política dentro de Wikilibros en Español. El enlace de la votación se encuentra acá: [[Wikilibros:Votaciones/Política sobre el uso de inteligencia artificial generativa]]. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 21:24 28 jun 2026 (UTC) == Clarificar el propósito de las plantillas infraesbozo y contextualizar == Buenas, en esWikilibros contamos con las plantillas {{tlx|Infraesbozo}} y {{tlx|Contextualizar}} que se adaptaron desde esWikipedia en 2015. Sin embargo, la forma en la que están redactadas en Wikilibros, sumada a la falta de documentación, hace que resulten demasiado similares entre sí y sus propósitos se solapen. Estas plantillas en esWikipedia tienen [[w:Wikipedia:Infraesbozo|propósitos claramente diferenciados]]: * [[w:Plantilla:Infraesbozo|Infraesbozo]]: Se utiliza para páginas cuyo contenido es insuficiente para constituir un esbozo válido. No depende de la longitud del texto, si no de que el artículo tenga algo de información mínima para desarrollar el tema. Se sugieren las siguientes preguntas para establecer si una página: *# ¿El artículo está contextualizado en tema, lugar y tiempo?, es decir ¿entiendo exactamente de qué habla? *# ¿El artículo aporta alguna, aunque sea mínima, información adicional enciclopédicamente pertinente? (Adicional a la imprescindible para contextualizar y marcar relevancia, se entiende). *# ¿El artículo muestra la relevancia de su tema? * [[w:Plantilla:Contextualizar|Contextualizar]]: Se utiliza para artículos que no proporcionan el contexto suficiente para un lector general. Su objetivo es solicitar que se añada información introductoria, explicaciones o contexto que permitan entender adecuadamente el tema tratado, sin que ello implique que el artículo sea demasiado corto. Quiero empezar señalando la importancia que, en mi opinión, tiene borrar los infraesbozos, especialmente en esWikilibros. En el proyecto existen muchísios libros muy incompletos y abandonados que se escribieron hace 10 o 20 años que a penas contienen una portada y, como mucho, un par de frases. En la mayoría de casos está claro que su autor no va a regresar para terminarlo, por lo que permanecen indefinidamente en ese estado. Mantener todos estos libros dificulta considerablemente el mantenimiento del proyecto. Por un lado, incrementa enormemente el número de páginas que requieren seguimiento sin aportar contenido útil. Por otro, complica la identificación de libros que realmente cuentan con algo de desarrollo o que tienen posibilidades de completarse. Además, transmiten una imagen de falta de mantenimiento y puede dificultar la navegación y el descubrimiento de obras que sí ofrecen un contenido aprovechable. A todo esto se suma, que estos infraesbozos rara vez sirven como punto de partida para futuros colaboradores, cuando alguien decide crear un libro sobre un tema que ya cuenta con un infraesbozo, lo habitual es que el contenido existente sea tan escaso que no resulte útil para construir sobre él. En la práctica, el trabajo consiste en rehacer el libro desde el principio, ya que apenas hay material que conservar o desarrollar. En estos casos, la existencia del infraesbozo ni si quiera facilita la creación del libro. Sin embargo, en Wikilibros, nuestra plantilla de «''Infraesbozo''» dice «''Este libro es demasiado reducido y carece de información básica que permita saber de qué se trata.''» Pero esto habla de contexto, y para contexto ya existe la plantilla «''Contextualizar''». Voy a poner algún ejemplo sobre por qué considero esto problemático: * Existe el libro de [[Vim]] que tiene una portada y '''absolutamenete nada''' de contenido. Está clarísimo que el libro pretende tratar sobre [[w:Vim|el editor de texto Vim]], su problema no es que «''carece de información básica que permita saber de qué se trata.''», sé perfectamente de qué quiere tratar. Pero sencillamente no contiene información útil. No hay ningún texto útil que desarrollar, ampliar o contextualizar, ni puede aportar absolutamente nada a ningún lector. Además, lleva once años sin recibir ediciones, por lo que es muy poco probable que su autor original vaya a volver en ningún momento a completarlo. Este tipo de «libros» me parecen problemáticos por lo que comenté anteriormente. * Hay muchos casos similares en Wikilibros. Por ejemplo, existe un libro de [[Vida saludable]] que contiene una portada y una breve frase introductoria, pero nada más. De nuevo, el problema no es que «''carece de información básica que permita saber de qué se trata.''», cualquiera entiende que el libro pretende tratar sobre la vida saludable. Lo que ocurre es que ese contenido no constituye ninguna base útil para un libro. No desarrolla el tema, no aporta información aprovechable al lector y, en la práctica, cualquier editor que quisiera escribir un libro sobre ese tema tendría que empezar de cero. Además hace 16 años que no se edita, no parece que su autor original vaya a volver para completarlo. Por ello, sugiero adaptar estas plantillas para que sus propósitos queden claramente diferenciados, siguiendo el criterio de esWikipedia. En concreto, que «''Infraesbozo''» se reserve para señalar libros cuyo contenido es insuficiente para constituir un esbozo válido, independientemente de que el tema esté claramente identificado, y que «''Contextualizar''» se utilice únicamente cuando el problema sea la falta de contexto o de información introductoria que dificulte la comprensión del contenido existente. De este modo, ambas plantillas dejarían de solapar sus funciones y su uso resultaría mucho más claro y coherente. Además, creo que el origen del problema probablemente sea bastante trivial y ni si quiera responde a ninguna decisión deliberada: simplemente se trata de un pequeño cambio de redacción que se introdujo al adaptar las plantillas desde esWikipedia hace once años, sin que hubiera una intención concreta detrás. Con el tiempo, esa pequeña diferencia ha acabado generando este solapamiento entre ambas plantillas. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:30 30 jun 2026 (UTC) :Han pasado ocho días desde que planteé esto y, dado que no ha habido ninguna objeción y tampoco considero que se trate de un cambio especialmente controvertido, voy a hacer el ajuste que propuse para clarificar la redacción de las plantillas, de forma similar a como ya está escrito en esWikipedia, tal y como expliqué anteriormente. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 16:16 8 jul 2026 (UTC) == Un pequeño hito que quería compartir == ¡Buenas! quería compartir con orgullo un pequeño hito conseguido en Wikilibros, solo por informar de las tareas que ando haciendo. 😊 Últimamente he estado arreglando literalmente '''miles''' de errores de sintaxis que reporta el [[:mw:Extension:Linter|linter]] de Wikilibros. Si entráis en la [[Especial:Errores_de_sintaxis|lista de errores de sintaxis]] podréis ver que la mayoría de categorías de errores graves están a 0, o se han reducido también drásticamente. Arreglar estos errores puede parecer poco llamativo porque no cambia en nada el contenido de las páginas, pero corregirlos hace que Wikilibros sea más fácil de mantener, más compatible con futuras actualizaciones de MediaWiki, cumpla los estándares modernos de accesibilidad y reduce la posibilidad de que las páginas no se rendericen correctamente. No puedo arreglar ''todos'' los errores porque muchos están en páginas protegidas que no puedo editar al no ser bibliotecario, además son muy numerosos (muchos miles) y algunos son complejos de arreglar. Pero ando trabajando en ello en mis ratos libres. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:14 8 jul 2026 (UTC) == Estandarización de las categorías de libros == En esWikilibros tenemos un problema grave con la catalogación de los libros, que en enWikibooks no existe gracias a una simple convención a la hora de nombrar las categorías. Ya expuse este asunto en [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|un escrito en mi página de usuario]]. ''(Nótese que voy a usar enWikibooks de ejemplo, pero que esa misma solución se usa en otras ediciones de Wikilibros como en alemán o portugués).'' Tanto en esWikilibros como en enWikibooks, los libros tienen dos clases de categorías: # '''Categoría para ''agrupar'' el libro''': Todas las páginas de un mismo libro se agrupan bajo una categoría con el mismo nombre del libro. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Book:C programming]]. # '''Categoría para ''catalogar'' el libro''': El libro en sí mismo se cataloga bajo una o varias categorías. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Shelf:C programming language]] que agrupa todos los libros sobre programación en C, como [[:en:Linear Algebra and the C Language]] o [[:en:A Little C Primer]]. Habréis notado que en enWikibooks usan los prefijos: # '''''Book''''': Para ''agrupar'' las páginas del libro. # '''''Shelf''''': Para ''catalogar'' libros. En esWikilibros, hacemos exactamente lo mismo, con la diferencia de que no usamos estos prefijos. Lo cual es un problema porque esto genera innumerables errores como los siguientes: * El libro [[Programación en C++]] se agrupa bajo la categoría [[:Categoría:Programación en C++]]. * Pero a su vez, la [[:Categoría:Programación en C++]] también se usa para catalogar libros relacionados con programación en C++, por lo que esta categoría incluye también el libro [[Desarrollo de videojuegos para PSP con C++ y SDL]] y [[Programación con Qt4]]. Es decir, la [[:Categoría:Programación en C++]] solapa dos propósitos distintos, y este problema ocurre con una gran cantidad de libros en esWikilibros, y hace que sea muy confuso navegar por las categorías de esWikilibros. ;La solución Usar el mismo sistema que usan en otras ediciones de Wikilibros, donde los libros se agrupan bajo una categoría llamada ''Libro:'' (de forma que quedaría ''Categoría:Libro:Programación en C++''), y los libros a su vez se catalogan mediante ''Shelf:'' o en español ''Estante:'' (de forma que quedaría ''Categoría:Estante:Programación en C++''). Curiosamente, ya ha existido algún tímido intento de usar este sistema en esWikilibros, por eso, por ejemplo, tenemos la categoría de catalogación [[:Categoría:Estante:Lenguajes de programación]] y el libro de [[Haskell]] está agrupado bajo la categoría [[:Categoría:Libro:Haskell]]. Pero esto no lo tenemos estandarizado, porque directamente no seguimos ningún sistema en particular [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|como ya expliqué en mi reciente escrito]]. ; Conclusión En consecuencia, propongo adoptar esta convención como estándar en esWikilibros: * Las categorías destinadas a agrupar las páginas de un libro pasarán a usar el prefijo «Libro:». * Las categorías destinadas a catalogar libros por temática pasarán a usar el prefijo «Estante:». Las categorías existentes se irán trasladando progresivamente a esta estructura, corrigiendo los casos en los que actualmente ambos usos se solapan. Se trata de un pequeño cambio principalmente organizativo, que no modifica el contenido de los libros, pero sí hace que la estructura de categorías sea mucho más clara, coherente y fácil de mantener, y que además ya se usa en otras ediciones de Wikilibros. Voy a esperar unos días por si alguien quiere dejar algún comentario sobre este asunto, tras los cuales mi intención es comenzar a usar esta convención y dejarla documentada para que pueda aplicarse de forma consistente en el futuro. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:18 15 jul 2026 (UTC) :Mientras trabajaba en este asunto, me he fijado también en que en Wikilibros tenemos dos «categorías raíz»: :# [[:Categoría:Categorías]] :# [[:Categoría:Principal]] :Ambas dicen ser «la categoría raíz de nuestro sistemas de categorías». Esta duplicidad es un error por motivos obvios. :Mi sugerencia es que nos quedemos sólo con [[:Categoría:Categorías]]. Por los siguientes motivos: :# «Categorías» es mucho mas claro que «Principal». ¿Qué significa principal? ¿Principal qué? «Categorías» deja bastante claro, que esa categoría alberga categorías. :# Por coherencia con otras wikis, ya que en esWikipedia la categoría raíz de otras categorías también se llama «Categorías». Y en enWikibooks se llama «Categories». :[[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:04 15 jul 2026 (UTC) j6nrywv0kwxenvd1vduq2rmttzbk0dj 427889 427881 2026-07-16T01:47:29Z Mazbel 57931 /* Petición para renombrar los «Proyectos» a «Wikiproyectos» */ archive to [[Wikilibros:Café/Archivo/2026#Petición para renombrar los «Proyectos» a «Wikiproyectos»]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]]) 427889 wikitext text/x-wiki {{Wikilibros:Café/Cabecera}} {{Usuario:MABot/config |archive = Wikilibros:Café/Archivo/%(year)s |algo = old(45d) |counter = 1 |archiveheader = {{Archivo}} |minthreadsleft = 0 |minthreadstoarchive = 1 }} == RFC about AI-generated content in Wikimedia Commons == <bdi lang="en" dir="ltr">Apologies for writing in English, please help translate this message to your language. You are invited to participate in a [[c:Commons:Requests for comment/Policy update for AI content|request for comment on Wikimedia Commons about a policy update for AI content]]. This may affect files that are uploaded to Wikimedia Commons for use on this project. Thank you. [[m:User:Codename Noreste|Codename Noreste]] ([[m:User talk:Codename Noreste|discusión]])</bdi> 17:11 23 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Codename Noreste@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 --> == Incorporación del enlace «Contactos legales y de seguridad» en el pie de página de vuestra wiki == <section begin="Message"/> '''Contactos legales y de seguridad''' Hola a toda la comunidad: la Fundación Wikimedia ha puesto a vuestra disposición una [[wmf:Special:MyLanguage/Legal:Wikimedia Foundation Legal and Safety Contact Information|página única de contacto sobre cuestiones legales y de seguridad]], que debéis incluir en el pie de página de vuestra wiki para garantizar el acceso a información jurídica precisa. Se trata de un requisito normativo. Ya hemos implementado enlaces a las wikis en inglés, alemán, italiano, español y otros idiomas de Wikipedia, y pronto los implementaremos en vuestra wiki. [[m:Special:MyLanguage/Wikimedia_Foundation_Legal_and_Safety_Contacts_FAQ|Por favor, leed más información en la página del proyecto]] y dejad vuestros comentarios en este hilo o en la [[m:Special:MyLanguage/Talk:Wikimedia Foundation Legal and Safety Contacts FAQ|página de discusión]]. <section end="Message"/> -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 13:30 25 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Sannita (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=30731267 --> == Petición para establecer una política sobre inteligencia artificial == Buenas. En el tiempo que llevo en Wikilibros, he observado varias páginas editadas mediante copias directas de texto generado por chatbots de IA (como ChatGPT, Copilot, Claude, Gemini, o Grok). Esto me preocupa, ya que este tipo de ediciones pueden resultar muy perjudiciales, y mientras que en muchas otras wikis ya se han establecido políticas sobre el uso de IA, en Wikilibros aún no tenemos ninguna política específica al respecto. Wikilibros en inglés cuenta con una política prohibiendo explícitamente esta clase de ediciones, que además explica el daño que pueden llegar a hacer, traduzco: {{Cita|Solicitar a un chatbot que escriba un libro o un ensayo puede dar lugar a la producción de [[W:Alucinación (inteligencia artificial)|invenciones completas]], incluyendo referencias ficticias. El resultado puede ser sesgado, difamar a personas reales, infringir derechos de autor o simplemente ser de mala calidad. <br>...<br> Estos problemas pueden volverse rápidamente problemáticos en comunidades y entornos grandes donde la transferencia de conocimiento, la verificabilidad, la rendición de cuentas y el pensamiento crítico son importantes. En particular, el alto volumen y la velocidad a la que los LLM pueden generar contenido, todo el cual debe ser verificado, implica que su uso supone un riesgo considerable. Por lo tanto, los materiales de aprendizaje de idiomas no deben utilizarse para generar o resumir material e ideas en Wikibooks, y no se debe confiar ciegamente en sus fuentes. |[https://en.wikibooks.org/wiki/Wikibooks:Artificial_intelligence Extraído y traducido de la política de Wikibooks (en inglés) sobre el uso de IA.] }} Wikipedia en Español también [[w:Wikipedia:Redacción de artículos con modelos de lenguaje grandes|cuenta con una política sobre este asunto]] que me parece correcta. Como Wikilibros en Español es una wiki tan pequeña, quizás sea mas adecuado adaptar o traducir la política de Wikibooks en inglés, o simplemente redirigir o adaptar la política de Wikipedia en español. En mi opinión, las políticas de estas wikis son sólidas, y además, han sido redactadas y consensuadas por más usuarios de los que tenemos aquí, por lo que cuentan con un buen consenso, y están más desarrolladas y probadas en comunidades más grandes. Quedo a la escucha de comentarios, y espero que podamos avanzar en este frente. Menciono a @[[Usuario:Mazbel|Mazbel]] que siempre es de gran ayuda. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 17:33 27 jun 2026 (UTC) :Creo que sí sería conveniente que Wikilibros contara con una política específica sobre el uso de la IA, no tanto porque sea una tecnología distinta a otras herramientasd e edición, sino por la escala a la que permite generar contenido. A diferencia de Wikipedia, aquí no construimos artículos independientes, sino libros completos y materiales de aprendizaje, donde la estructura, la coherencia y la progresión de los contenidos son partwe esencial de la calidad de la obra. Un texto generado por IA puede ser correcto en términos generales y, aun así, presentar problemas de organización, inconsistencias entre capítulos, ejemplos poco adecuados o explicaciones que no responden a un criterio didáctico claro. Detectar ese tipo de problemas exige una revisión completa del libro, algo que en una comunidad pequeña como eswikibooks rara vez es posible cuando se incorporan grandes cantidades de contenido. :Por ello, considero que una política debería ser relativamente estricta con la incorporación de texto generado por IA. No porque toda utilización de estas herramientas sea necesariamente perjudicial, sino porque el riesgo de publicar contenido insuficientemente revisado es mayor que la capacidad que tiene la comunidad para detectarlo y corregirlo. En mi opinión, la IA puede tener cabida como herramienta de apoyo durante el proceso de redacción, pero no debería emplearse para generar de forma directa partes sustanciales de un libro destinadas a su publicación. En un proyecto con pocos editores activos, resulta más prudente priorizar la calidad y el mantenimiento de los libros que facilitar un aumento rápido de contenido cuya revisión efectiva no puede garantizarse. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:49 27 jun 2026 (UTC) ::Estoy de acuerdo con todo lo que has dicho, especialmente con tu segundo párrafo, del que suscribo cada palabra al 100%. ::Lo de adaptar una política de otra wiki, lo mencioné en gran medida, no por la dificultad en sí de redactarla, si no porque en estos lugares ya existe consenso, y así puede ser más fácil ponerse de acuerdo. Pero si en Wikilibros en español también estamos todos más o menos de acuerdo, no veo por qué no podríamos redactar la nuestra propia. ::Concuerdo totalmente en que habría que ser relativamente estricto, porque por los chatbots de IA pueden generar enormes cantidades de texto, y al ser una comunidad tan pequeña no tenemos capacidad para pararnos a revisar un libro que se generase con IA. ::En este sentido, la política de enWikibooks me parece suficientemente estricta, además, [https://en.wikibooks.org/wiki/Wikibooks_talk:Artificial_intelligence/Archive_1 se puede leer el debate que tuvieron para alcanzar tal consenso (en inglés)] que es muy interesante. ::Según la política enWikibooks: ::# Se advierte brevemente de que el contenido de IA puede ser inexacto, inventado o de baja calidad. (Personalmente creo que además podría advertirse de los posibles problemas de copyright que puede llegar a causar). ::# No se permite usar IA para generar, resumir o traducir contenido. ::# Está explícitamente prohibido hacer ediciones que consistan en copiar y pegar texto de IA en páginas. ::# Se avisa de que el contenido debe ser siempre verificado y escrito por humanos. ::# No se prohíbe que alguien consulte o haga uso de la IA como apoyo externo, lo que está prohibido es que la IA genere el contenido, pero uno puede usarla para consulta externa si lo desea. ::Considero que podríamos basarnos en la política de enWikibooks y traducirla y adaptarla a nuestra versión. Si estamos más o menos de acuerdo en que es adecuada, sería muy sencillo incorporar esta política. Si os parece bien esto, podría escribirla basándome en enWikibooks y luego mencionaros para que la reviséis. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:47 27 jun 2026 (UTC) : De acuerdo a que en conjunto establezcamos una política en base al uso de IA. Es algo que se debe de tocar acá y me parece buen puerto, el guiarnos de la política establecida desde enWikibooks [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 02:29 28 jun 2026 (UTC) ::Buenas @[[Usuario:Mazbel|Mazbel]] y @[[Usuario:Divinations|Divinations]] he tomado la iniciativa y redactado la página «''[[Wikilibros:Política sobre el uso de inteligencia artificial generativa]]''» (que de momento está marcada como un borrador). Esta página está traducida y adaptada de la versión de enWikibooks, me he inspirado también en la conversación que hemos tenido por aquí, y en la misma política en la Wikipedia en español. ::Os agradecería si pudieseis revisar esta página, sentíos libres de editarla si lo consideráis, y os invito a continuar esta conversación en la discusión de esta página. Gracias por vuestra colaboración en este asunto. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 09:33 28 jun 2026 (UTC) :::<s>Gracias, [[Usuario:Antimundo|Antimundo]]. Añadí un atajo para que pueda ser encontrada más fácilmente. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 17:47 28 jun 2026 (UTC)</s> ::::Parece que se borró. Creo que me adelanté antes de tiempo, mejor esperar a obtener un mejor consenso comunitario más allá de solo tres usuarios. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:44 28 jun 2026 (UTC) : Me temo que antes de formarse como una política dentro de Wikilibros, debe ser llevada a votación, un aviso tanto para @[[Usuario:Antimundo]] como para @[[Usuario:Divinations]]. Estoy adaptando el contenido para que se proceda a votación. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 20:52 28 jun 2026 (UTC) ::Entendido, gracias por iniciar el procedimiento. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:01 28 jun 2026 (UTC) == Votación sobre nueva política sobre el uso de la inteligencia artificial == En relación con el hilo anterior, se abrió una página de votación para establecer como una nueva política dentro de Wikilibros en Español. El enlace de la votación se encuentra acá: [[Wikilibros:Votaciones/Política sobre el uso de inteligencia artificial generativa]]. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 21:24 28 jun 2026 (UTC) == Clarificar el propósito de las plantillas infraesbozo y contextualizar == Buenas, en esWikilibros contamos con las plantillas {{tlx|Infraesbozo}} y {{tlx|Contextualizar}} que se adaptaron desde esWikipedia en 2015. Sin embargo, la forma en la que están redactadas en Wikilibros, sumada a la falta de documentación, hace que resulten demasiado similares entre sí y sus propósitos se solapen. Estas plantillas en esWikipedia tienen [[w:Wikipedia:Infraesbozo|propósitos claramente diferenciados]]: * [[w:Plantilla:Infraesbozo|Infraesbozo]]: Se utiliza para páginas cuyo contenido es insuficiente para constituir un esbozo válido. No depende de la longitud del texto, si no de que el artículo tenga algo de información mínima para desarrollar el tema. Se sugieren las siguientes preguntas para establecer si una página: *# ¿El artículo está contextualizado en tema, lugar y tiempo?, es decir ¿entiendo exactamente de qué habla? *# ¿El artículo aporta alguna, aunque sea mínima, información adicional enciclopédicamente pertinente? (Adicional a la imprescindible para contextualizar y marcar relevancia, se entiende). *# ¿El artículo muestra la relevancia de su tema? * [[w:Plantilla:Contextualizar|Contextualizar]]: Se utiliza para artículos que no proporcionan el contexto suficiente para un lector general. Su objetivo es solicitar que se añada información introductoria, explicaciones o contexto que permitan entender adecuadamente el tema tratado, sin que ello implique que el artículo sea demasiado corto. Quiero empezar señalando la importancia que, en mi opinión, tiene borrar los infraesbozos, especialmente en esWikilibros. En el proyecto existen muchísios libros muy incompletos y abandonados que se escribieron hace 10 o 20 años que a penas contienen una portada y, como mucho, un par de frases. En la mayoría de casos está claro que su autor no va a regresar para terminarlo, por lo que permanecen indefinidamente en ese estado. Mantener todos estos libros dificulta considerablemente el mantenimiento del proyecto. Por un lado, incrementa enormemente el número de páginas que requieren seguimiento sin aportar contenido útil. Por otro, complica la identificación de libros que realmente cuentan con algo de desarrollo o que tienen posibilidades de completarse. Además, transmiten una imagen de falta de mantenimiento y puede dificultar la navegación y el descubrimiento de obras que sí ofrecen un contenido aprovechable. A todo esto se suma, que estos infraesbozos rara vez sirven como punto de partida para futuros colaboradores, cuando alguien decide crear un libro sobre un tema que ya cuenta con un infraesbozo, lo habitual es que el contenido existente sea tan escaso que no resulte útil para construir sobre él. En la práctica, el trabajo consiste en rehacer el libro desde el principio, ya que apenas hay material que conservar o desarrollar. En estos casos, la existencia del infraesbozo ni si quiera facilita la creación del libro. Sin embargo, en Wikilibros, nuestra plantilla de «''Infraesbozo''» dice «''Este libro es demasiado reducido y carece de información básica que permita saber de qué se trata.''» Pero esto habla de contexto, y para contexto ya existe la plantilla «''Contextualizar''». Voy a poner algún ejemplo sobre por qué considero esto problemático: * Existe el libro de [[Vim]] que tiene una portada y '''absolutamenete nada''' de contenido. Está clarísimo que el libro pretende tratar sobre [[w:Vim|el editor de texto Vim]], su problema no es que «''carece de información básica que permita saber de qué se trata.''», sé perfectamente de qué quiere tratar. Pero sencillamente no contiene información útil. No hay ningún texto útil que desarrollar, ampliar o contextualizar, ni puede aportar absolutamente nada a ningún lector. Además, lleva once años sin recibir ediciones, por lo que es muy poco probable que su autor original vaya a volver en ningún momento a completarlo. Este tipo de «libros» me parecen problemáticos por lo que comenté anteriormente. * Hay muchos casos similares en Wikilibros. Por ejemplo, existe un libro de [[Vida saludable]] que contiene una portada y una breve frase introductoria, pero nada más. De nuevo, el problema no es que «''carece de información básica que permita saber de qué se trata.''», cualquiera entiende que el libro pretende tratar sobre la vida saludable. Lo que ocurre es que ese contenido no constituye ninguna base útil para un libro. No desarrolla el tema, no aporta información aprovechable al lector y, en la práctica, cualquier editor que quisiera escribir un libro sobre ese tema tendría que empezar de cero. Además hace 16 años que no se edita, no parece que su autor original vaya a volver para completarlo. Por ello, sugiero adaptar estas plantillas para que sus propósitos queden claramente diferenciados, siguiendo el criterio de esWikipedia. En concreto, que «''Infraesbozo''» se reserve para señalar libros cuyo contenido es insuficiente para constituir un esbozo válido, independientemente de que el tema esté claramente identificado, y que «''Contextualizar''» se utilice únicamente cuando el problema sea la falta de contexto o de información introductoria que dificulte la comprensión del contenido existente. De este modo, ambas plantillas dejarían de solapar sus funciones y su uso resultaría mucho más claro y coherente. Además, creo que el origen del problema probablemente sea bastante trivial y ni si quiera responde a ninguna decisión deliberada: simplemente se trata de un pequeño cambio de redacción que se introdujo al adaptar las plantillas desde esWikipedia hace once años, sin que hubiera una intención concreta detrás. Con el tiempo, esa pequeña diferencia ha acabado generando este solapamiento entre ambas plantillas. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:30 30 jun 2026 (UTC) :Han pasado ocho días desde que planteé esto y, dado que no ha habido ninguna objeción y tampoco considero que se trate de un cambio especialmente controvertido, voy a hacer el ajuste que propuse para clarificar la redacción de las plantillas, de forma similar a como ya está escrito en esWikipedia, tal y como expliqué anteriormente. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 16:16 8 jul 2026 (UTC) == Un pequeño hito que quería compartir == ¡Buenas! quería compartir con orgullo un pequeño hito conseguido en Wikilibros, solo por informar de las tareas que ando haciendo. 😊 Últimamente he estado arreglando literalmente '''miles''' de errores de sintaxis que reporta el [[:mw:Extension:Linter|linter]] de Wikilibros. Si entráis en la [[Especial:Errores_de_sintaxis|lista de errores de sintaxis]] podréis ver que la mayoría de categorías de errores graves están a 0, o se han reducido también drásticamente. Arreglar estos errores puede parecer poco llamativo porque no cambia en nada el contenido de las páginas, pero corregirlos hace que Wikilibros sea más fácil de mantener, más compatible con futuras actualizaciones de MediaWiki, cumpla los estándares modernos de accesibilidad y reduce la posibilidad de que las páginas no se rendericen correctamente. No puedo arreglar ''todos'' los errores porque muchos están en páginas protegidas que no puedo editar al no ser bibliotecario, además son muy numerosos (muchos miles) y algunos son complejos de arreglar. Pero ando trabajando en ello en mis ratos libres. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:14 8 jul 2026 (UTC) == Estandarización de las categorías de libros == En esWikilibros tenemos un problema grave con la catalogación de los libros, que en enWikibooks no existe gracias a una simple convención a la hora de nombrar las categorías. Ya expuse este asunto en [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|un escrito en mi página de usuario]]. ''(Nótese que voy a usar enWikibooks de ejemplo, pero que esa misma solución se usa en otras ediciones de Wikilibros como en alemán o portugués).'' Tanto en esWikilibros como en enWikibooks, los libros tienen dos clases de categorías: # '''Categoría para ''agrupar'' el libro''': Todas las páginas de un mismo libro se agrupan bajo una categoría con el mismo nombre del libro. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Book:C programming]]. # '''Categoría para ''catalogar'' el libro''': El libro en sí mismo se cataloga bajo una o varias categorías. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Shelf:C programming language]] que agrupa todos los libros sobre programación en C, como [[:en:Linear Algebra and the C Language]] o [[:en:A Little C Primer]]. Habréis notado que en enWikibooks usan los prefijos: # '''''Book''''': Para ''agrupar'' las páginas del libro. # '''''Shelf''''': Para ''catalogar'' libros. En esWikilibros, hacemos exactamente lo mismo, con la diferencia de que no usamos estos prefijos. Lo cual es un problema porque esto genera innumerables errores como los siguientes: * El libro [[Programación en C++]] se agrupa bajo la categoría [[:Categoría:Programación en C++]]. * Pero a su vez, la [[:Categoría:Programación en C++]] también se usa para catalogar libros relacionados con programación en C++, por lo que esta categoría incluye también el libro [[Desarrollo de videojuegos para PSP con C++ y SDL]] y [[Programación con Qt4]]. Es decir, la [[:Categoría:Programación en C++]] solapa dos propósitos distintos, y este problema ocurre con una gran cantidad de libros en esWikilibros, y hace que sea muy confuso navegar por las categorías de esWikilibros. ;La solución Usar el mismo sistema que usan en otras ediciones de Wikilibros, donde los libros se agrupan bajo una categoría llamada ''Libro:'' (de forma que quedaría ''Categoría:Libro:Programación en C++''), y los libros a su vez se catalogan mediante ''Shelf:'' o en español ''Estante:'' (de forma que quedaría ''Categoría:Estante:Programación en C++''). Curiosamente, ya ha existido algún tímido intento de usar este sistema en esWikilibros, por eso, por ejemplo, tenemos la categoría de catalogación [[:Categoría:Estante:Lenguajes de programación]] y el libro de [[Haskell]] está agrupado bajo la categoría [[:Categoría:Libro:Haskell]]. Pero esto no lo tenemos estandarizado, porque directamente no seguimos ningún sistema en particular [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|como ya expliqué en mi reciente escrito]]. ; Conclusión En consecuencia, propongo adoptar esta convención como estándar en esWikilibros: * Las categorías destinadas a agrupar las páginas de un libro pasarán a usar el prefijo «Libro:». * Las categorías destinadas a catalogar libros por temática pasarán a usar el prefijo «Estante:». Las categorías existentes se irán trasladando progresivamente a esta estructura, corrigiendo los casos en los que actualmente ambos usos se solapan. Se trata de un pequeño cambio principalmente organizativo, que no modifica el contenido de los libros, pero sí hace que la estructura de categorías sea mucho más clara, coherente y fácil de mantener, y que además ya se usa en otras ediciones de Wikilibros. Voy a esperar unos días por si alguien quiere dejar algún comentario sobre este asunto, tras los cuales mi intención es comenzar a usar esta convención y dejarla documentada para que pueda aplicarse de forma consistente en el futuro. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:18 15 jul 2026 (UTC) :Mientras trabajaba en este asunto, me he fijado también en que en Wikilibros tenemos dos «categorías raíz»: :# [[:Categoría:Categorías]] :# [[:Categoría:Principal]] :Ambas dicen ser «la categoría raíz de nuestro sistemas de categorías». Esta duplicidad es un error por motivos obvios. :Mi sugerencia es que nos quedemos sólo con [[:Categoría:Categorías]]. Por los siguientes motivos: :# «Categorías» es mucho mas claro que «Principal». ¿Qué significa principal? ¿Principal qué? «Categorías» deja bastante claro, que esa categoría alberga categorías. :# Por coherencia con otras wikis, ya que en esWikipedia la categoría raíz de otras categorías también se llama «Categorías». Y en enWikibooks se llama «Categories». :[[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:04 15 jul 2026 (UTC) qz5guqs97v5qnn9qxio5l01fczp2jr0 427891 427889 2026-07-16T01:47:42Z Mazbel 57931 /* RFC about AI-generated content in Wikimedia Commons */ archive to [[Wikilibros:Café/Archivo/2026#RFC about AI-generated content in Wikimedia Commons]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]]) 427891 wikitext text/x-wiki {{Wikilibros:Café/Cabecera}} {{Usuario:MABot/config |archive = Wikilibros:Café/Archivo/%(year)s |algo = old(45d) |counter = 1 |archiveheader = {{Archivo}} |minthreadsleft = 0 |minthreadstoarchive = 1 }} == Incorporación del enlace «Contactos legales y de seguridad» en el pie de página de vuestra wiki == <section begin="Message"/> '''Contactos legales y de seguridad''' Hola a toda la comunidad: la Fundación Wikimedia ha puesto a vuestra disposición una [[wmf:Special:MyLanguage/Legal:Wikimedia Foundation Legal and Safety Contact Information|página única de contacto sobre cuestiones legales y de seguridad]], que debéis incluir en el pie de página de vuestra wiki para garantizar el acceso a información jurídica precisa. Se trata de un requisito normativo. Ya hemos implementado enlaces a las wikis en inglés, alemán, italiano, español y otros idiomas de Wikipedia, y pronto los implementaremos en vuestra wiki. [[m:Special:MyLanguage/Wikimedia_Foundation_Legal_and_Safety_Contacts_FAQ|Por favor, leed más información en la página del proyecto]] y dejad vuestros comentarios en este hilo o en la [[m:Special:MyLanguage/Talk:Wikimedia Foundation Legal and Safety Contacts FAQ|página de discusión]]. <section end="Message"/> -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 13:30 25 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Sannita (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=30731267 --> == Petición para establecer una política sobre inteligencia artificial == Buenas. En el tiempo que llevo en Wikilibros, he observado varias páginas editadas mediante copias directas de texto generado por chatbots de IA (como ChatGPT, Copilot, Claude, Gemini, o Grok). Esto me preocupa, ya que este tipo de ediciones pueden resultar muy perjudiciales, y mientras que en muchas otras wikis ya se han establecido políticas sobre el uso de IA, en Wikilibros aún no tenemos ninguna política específica al respecto. Wikilibros en inglés cuenta con una política prohibiendo explícitamente esta clase de ediciones, que además explica el daño que pueden llegar a hacer, traduzco: {{Cita|Solicitar a un chatbot que escriba un libro o un ensayo puede dar lugar a la producción de [[W:Alucinación (inteligencia artificial)|invenciones completas]], incluyendo referencias ficticias. El resultado puede ser sesgado, difamar a personas reales, infringir derechos de autor o simplemente ser de mala calidad. <br>...<br> Estos problemas pueden volverse rápidamente problemáticos en comunidades y entornos grandes donde la transferencia de conocimiento, la verificabilidad, la rendición de cuentas y el pensamiento crítico son importantes. En particular, el alto volumen y la velocidad a la que los LLM pueden generar contenido, todo el cual debe ser verificado, implica que su uso supone un riesgo considerable. Por lo tanto, los materiales de aprendizaje de idiomas no deben utilizarse para generar o resumir material e ideas en Wikibooks, y no se debe confiar ciegamente en sus fuentes. |[https://en.wikibooks.org/wiki/Wikibooks:Artificial_intelligence Extraído y traducido de la política de Wikibooks (en inglés) sobre el uso de IA.] }} Wikipedia en Español también [[w:Wikipedia:Redacción de artículos con modelos de lenguaje grandes|cuenta con una política sobre este asunto]] que me parece correcta. Como Wikilibros en Español es una wiki tan pequeña, quizás sea mas adecuado adaptar o traducir la política de Wikibooks en inglés, o simplemente redirigir o adaptar la política de Wikipedia en español. En mi opinión, las políticas de estas wikis son sólidas, y además, han sido redactadas y consensuadas por más usuarios de los que tenemos aquí, por lo que cuentan con un buen consenso, y están más desarrolladas y probadas en comunidades más grandes. Quedo a la escucha de comentarios, y espero que podamos avanzar en este frente. Menciono a @[[Usuario:Mazbel|Mazbel]] que siempre es de gran ayuda. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 17:33 27 jun 2026 (UTC) :Creo que sí sería conveniente que Wikilibros contara con una política específica sobre el uso de la IA, no tanto porque sea una tecnología distinta a otras herramientasd e edición, sino por la escala a la que permite generar contenido. A diferencia de Wikipedia, aquí no construimos artículos independientes, sino libros completos y materiales de aprendizaje, donde la estructura, la coherencia y la progresión de los contenidos son partwe esencial de la calidad de la obra. Un texto generado por IA puede ser correcto en términos generales y, aun así, presentar problemas de organización, inconsistencias entre capítulos, ejemplos poco adecuados o explicaciones que no responden a un criterio didáctico claro. Detectar ese tipo de problemas exige una revisión completa del libro, algo que en una comunidad pequeña como eswikibooks rara vez es posible cuando se incorporan grandes cantidades de contenido. :Por ello, considero que una política debería ser relativamente estricta con la incorporación de texto generado por IA. No porque toda utilización de estas herramientas sea necesariamente perjudicial, sino porque el riesgo de publicar contenido insuficientemente revisado es mayor que la capacidad que tiene la comunidad para detectarlo y corregirlo. En mi opinión, la IA puede tener cabida como herramienta de apoyo durante el proceso de redacción, pero no debería emplearse para generar de forma directa partes sustanciales de un libro destinadas a su publicación. En un proyecto con pocos editores activos, resulta más prudente priorizar la calidad y el mantenimiento de los libros que facilitar un aumento rápido de contenido cuya revisión efectiva no puede garantizarse. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:49 27 jun 2026 (UTC) ::Estoy de acuerdo con todo lo que has dicho, especialmente con tu segundo párrafo, del que suscribo cada palabra al 100%. ::Lo de adaptar una política de otra wiki, lo mencioné en gran medida, no por la dificultad en sí de redactarla, si no porque en estos lugares ya existe consenso, y así puede ser más fácil ponerse de acuerdo. Pero si en Wikilibros en español también estamos todos más o menos de acuerdo, no veo por qué no podríamos redactar la nuestra propia. ::Concuerdo totalmente en que habría que ser relativamente estricto, porque por los chatbots de IA pueden generar enormes cantidades de texto, y al ser una comunidad tan pequeña no tenemos capacidad para pararnos a revisar un libro que se generase con IA. ::En este sentido, la política de enWikibooks me parece suficientemente estricta, además, [https://en.wikibooks.org/wiki/Wikibooks_talk:Artificial_intelligence/Archive_1 se puede leer el debate que tuvieron para alcanzar tal consenso (en inglés)] que es muy interesante. ::Según la política enWikibooks: ::# Se advierte brevemente de que el contenido de IA puede ser inexacto, inventado o de baja calidad. (Personalmente creo que además podría advertirse de los posibles problemas de copyright que puede llegar a causar). ::# No se permite usar IA para generar, resumir o traducir contenido. ::# Está explícitamente prohibido hacer ediciones que consistan en copiar y pegar texto de IA en páginas. ::# Se avisa de que el contenido debe ser siempre verificado y escrito por humanos. ::# No se prohíbe que alguien consulte o haga uso de la IA como apoyo externo, lo que está prohibido es que la IA genere el contenido, pero uno puede usarla para consulta externa si lo desea. ::Considero que podríamos basarnos en la política de enWikibooks y traducirla y adaptarla a nuestra versión. Si estamos más o menos de acuerdo en que es adecuada, sería muy sencillo incorporar esta política. Si os parece bien esto, podría escribirla basándome en enWikibooks y luego mencionaros para que la reviséis. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:47 27 jun 2026 (UTC) : De acuerdo a que en conjunto establezcamos una política en base al uso de IA. Es algo que se debe de tocar acá y me parece buen puerto, el guiarnos de la política establecida desde enWikibooks [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 02:29 28 jun 2026 (UTC) ::Buenas @[[Usuario:Mazbel|Mazbel]] y @[[Usuario:Divinations|Divinations]] he tomado la iniciativa y redactado la página «''[[Wikilibros:Política sobre el uso de inteligencia artificial generativa]]''» (que de momento está marcada como un borrador). Esta página está traducida y adaptada de la versión de enWikibooks, me he inspirado también en la conversación que hemos tenido por aquí, y en la misma política en la Wikipedia en español. ::Os agradecería si pudieseis revisar esta página, sentíos libres de editarla si lo consideráis, y os invito a continuar esta conversación en la discusión de esta página. Gracias por vuestra colaboración en este asunto. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 09:33 28 jun 2026 (UTC) :::<s>Gracias, [[Usuario:Antimundo|Antimundo]]. Añadí un atajo para que pueda ser encontrada más fácilmente. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 17:47 28 jun 2026 (UTC)</s> ::::Parece que se borró. Creo que me adelanté antes de tiempo, mejor esperar a obtener un mejor consenso comunitario más allá de solo tres usuarios. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:44 28 jun 2026 (UTC) : Me temo que antes de formarse como una política dentro de Wikilibros, debe ser llevada a votación, un aviso tanto para @[[Usuario:Antimundo]] como para @[[Usuario:Divinations]]. Estoy adaptando el contenido para que se proceda a votación. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 20:52 28 jun 2026 (UTC) ::Entendido, gracias por iniciar el procedimiento. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:01 28 jun 2026 (UTC) == Votación sobre nueva política sobre el uso de la inteligencia artificial == En relación con el hilo anterior, se abrió una página de votación para establecer como una nueva política dentro de Wikilibros en Español. El enlace de la votación se encuentra acá: [[Wikilibros:Votaciones/Política sobre el uso de inteligencia artificial generativa]]. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 21:24 28 jun 2026 (UTC) == Clarificar el propósito de las plantillas infraesbozo y contextualizar == Buenas, en esWikilibros contamos con las plantillas {{tlx|Infraesbozo}} y {{tlx|Contextualizar}} que se adaptaron desde esWikipedia en 2015. Sin embargo, la forma en la que están redactadas en Wikilibros, sumada a la falta de documentación, hace que resulten demasiado similares entre sí y sus propósitos se solapen. Estas plantillas en esWikipedia tienen [[w:Wikipedia:Infraesbozo|propósitos claramente diferenciados]]: * [[w:Plantilla:Infraesbozo|Infraesbozo]]: Se utiliza para páginas cuyo contenido es insuficiente para constituir un esbozo válido. No depende de la longitud del texto, si no de que el artículo tenga algo de información mínima para desarrollar el tema. Se sugieren las siguientes preguntas para establecer si una página: *# ¿El artículo está contextualizado en tema, lugar y tiempo?, es decir ¿entiendo exactamente de qué habla? *# ¿El artículo aporta alguna, aunque sea mínima, información adicional enciclopédicamente pertinente? (Adicional a la imprescindible para contextualizar y marcar relevancia, se entiende). *# ¿El artículo muestra la relevancia de su tema? * [[w:Plantilla:Contextualizar|Contextualizar]]: Se utiliza para artículos que no proporcionan el contexto suficiente para un lector general. Su objetivo es solicitar que se añada información introductoria, explicaciones o contexto que permitan entender adecuadamente el tema tratado, sin que ello implique que el artículo sea demasiado corto. Quiero empezar señalando la importancia que, en mi opinión, tiene borrar los infraesbozos, especialmente en esWikilibros. En el proyecto existen muchísios libros muy incompletos y abandonados que se escribieron hace 10 o 20 años que a penas contienen una portada y, como mucho, un par de frases. En la mayoría de casos está claro que su autor no va a regresar para terminarlo, por lo que permanecen indefinidamente en ese estado. Mantener todos estos libros dificulta considerablemente el mantenimiento del proyecto. Por un lado, incrementa enormemente el número de páginas que requieren seguimiento sin aportar contenido útil. Por otro, complica la identificación de libros que realmente cuentan con algo de desarrollo o que tienen posibilidades de completarse. Además, transmiten una imagen de falta de mantenimiento y puede dificultar la navegación y el descubrimiento de obras que sí ofrecen un contenido aprovechable. A todo esto se suma, que estos infraesbozos rara vez sirven como punto de partida para futuros colaboradores, cuando alguien decide crear un libro sobre un tema que ya cuenta con un infraesbozo, lo habitual es que el contenido existente sea tan escaso que no resulte útil para construir sobre él. En la práctica, el trabajo consiste en rehacer el libro desde el principio, ya que apenas hay material que conservar o desarrollar. En estos casos, la existencia del infraesbozo ni si quiera facilita la creación del libro. Sin embargo, en Wikilibros, nuestra plantilla de «''Infraesbozo''» dice «''Este libro es demasiado reducido y carece de información básica que permita saber de qué se trata.''» Pero esto habla de contexto, y para contexto ya existe la plantilla «''Contextualizar''». Voy a poner algún ejemplo sobre por qué considero esto problemático: * Existe el libro de [[Vim]] que tiene una portada y '''absolutamenete nada''' de contenido. Está clarísimo que el libro pretende tratar sobre [[w:Vim|el editor de texto Vim]], su problema no es que «''carece de información básica que permita saber de qué se trata.''», sé perfectamente de qué quiere tratar. Pero sencillamente no contiene información útil. No hay ningún texto útil que desarrollar, ampliar o contextualizar, ni puede aportar absolutamente nada a ningún lector. Además, lleva once años sin recibir ediciones, por lo que es muy poco probable que su autor original vaya a volver en ningún momento a completarlo. Este tipo de «libros» me parecen problemáticos por lo que comenté anteriormente. * Hay muchos casos similares en Wikilibros. Por ejemplo, existe un libro de [[Vida saludable]] que contiene una portada y una breve frase introductoria, pero nada más. De nuevo, el problema no es que «''carece de información básica que permita saber de qué se trata.''», cualquiera entiende que el libro pretende tratar sobre la vida saludable. Lo que ocurre es que ese contenido no constituye ninguna base útil para un libro. No desarrolla el tema, no aporta información aprovechable al lector y, en la práctica, cualquier editor que quisiera escribir un libro sobre ese tema tendría que empezar de cero. Además hace 16 años que no se edita, no parece que su autor original vaya a volver para completarlo. Por ello, sugiero adaptar estas plantillas para que sus propósitos queden claramente diferenciados, siguiendo el criterio de esWikipedia. En concreto, que «''Infraesbozo''» se reserve para señalar libros cuyo contenido es insuficiente para constituir un esbozo válido, independientemente de que el tema esté claramente identificado, y que «''Contextualizar''» se utilice únicamente cuando el problema sea la falta de contexto o de información introductoria que dificulte la comprensión del contenido existente. De este modo, ambas plantillas dejarían de solapar sus funciones y su uso resultaría mucho más claro y coherente. Además, creo que el origen del problema probablemente sea bastante trivial y ni si quiera responde a ninguna decisión deliberada: simplemente se trata de un pequeño cambio de redacción que se introdujo al adaptar las plantillas desde esWikipedia hace once años, sin que hubiera una intención concreta detrás. Con el tiempo, esa pequeña diferencia ha acabado generando este solapamiento entre ambas plantillas. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:30 30 jun 2026 (UTC) :Han pasado ocho días desde que planteé esto y, dado que no ha habido ninguna objeción y tampoco considero que se trate de un cambio especialmente controvertido, voy a hacer el ajuste que propuse para clarificar la redacción de las plantillas, de forma similar a como ya está escrito en esWikipedia, tal y como expliqué anteriormente. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 16:16 8 jul 2026 (UTC) == Un pequeño hito que quería compartir == ¡Buenas! quería compartir con orgullo un pequeño hito conseguido en Wikilibros, solo por informar de las tareas que ando haciendo. 😊 Últimamente he estado arreglando literalmente '''miles''' de errores de sintaxis que reporta el [[:mw:Extension:Linter|linter]] de Wikilibros. Si entráis en la [[Especial:Errores_de_sintaxis|lista de errores de sintaxis]] podréis ver que la mayoría de categorías de errores graves están a 0, o se han reducido también drásticamente. Arreglar estos errores puede parecer poco llamativo porque no cambia en nada el contenido de las páginas, pero corregirlos hace que Wikilibros sea más fácil de mantener, más compatible con futuras actualizaciones de MediaWiki, cumpla los estándares modernos de accesibilidad y reduce la posibilidad de que las páginas no se rendericen correctamente. No puedo arreglar ''todos'' los errores porque muchos están en páginas protegidas que no puedo editar al no ser bibliotecario, además son muy numerosos (muchos miles) y algunos son complejos de arreglar. Pero ando trabajando en ello en mis ratos libres. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:14 8 jul 2026 (UTC) == Estandarización de las categorías de libros == En esWikilibros tenemos un problema grave con la catalogación de los libros, que en enWikibooks no existe gracias a una simple convención a la hora de nombrar las categorías. Ya expuse este asunto en [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|un escrito en mi página de usuario]]. ''(Nótese que voy a usar enWikibooks de ejemplo, pero que esa misma solución se usa en otras ediciones de Wikilibros como en alemán o portugués).'' Tanto en esWikilibros como en enWikibooks, los libros tienen dos clases de categorías: # '''Categoría para ''agrupar'' el libro''': Todas las páginas de un mismo libro se agrupan bajo una categoría con el mismo nombre del libro. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Book:C programming]]. # '''Categoría para ''catalogar'' el libro''': El libro en sí mismo se cataloga bajo una o varias categorías. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Shelf:C programming language]] que agrupa todos los libros sobre programación en C, como [[:en:Linear Algebra and the C Language]] o [[:en:A Little C Primer]]. Habréis notado que en enWikibooks usan los prefijos: # '''''Book''''': Para ''agrupar'' las páginas del libro. # '''''Shelf''''': Para ''catalogar'' libros. En esWikilibros, hacemos exactamente lo mismo, con la diferencia de que no usamos estos prefijos. Lo cual es un problema porque esto genera innumerables errores como los siguientes: * El libro [[Programación en C++]] se agrupa bajo la categoría [[:Categoría:Programación en C++]]. * Pero a su vez, la [[:Categoría:Programación en C++]] también se usa para catalogar libros relacionados con programación en C++, por lo que esta categoría incluye también el libro [[Desarrollo de videojuegos para PSP con C++ y SDL]] y [[Programación con Qt4]]. Es decir, la [[:Categoría:Programación en C++]] solapa dos propósitos distintos, y este problema ocurre con una gran cantidad de libros en esWikilibros, y hace que sea muy confuso navegar por las categorías de esWikilibros. ;La solución Usar el mismo sistema que usan en otras ediciones de Wikilibros, donde los libros se agrupan bajo una categoría llamada ''Libro:'' (de forma que quedaría ''Categoría:Libro:Programación en C++''), y los libros a su vez se catalogan mediante ''Shelf:'' o en español ''Estante:'' (de forma que quedaría ''Categoría:Estante:Programación en C++''). Curiosamente, ya ha existido algún tímido intento de usar este sistema en esWikilibros, por eso, por ejemplo, tenemos la categoría de catalogación [[:Categoría:Estante:Lenguajes de programación]] y el libro de [[Haskell]] está agrupado bajo la categoría [[:Categoría:Libro:Haskell]]. Pero esto no lo tenemos estandarizado, porque directamente no seguimos ningún sistema en particular [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|como ya expliqué en mi reciente escrito]]. ; Conclusión En consecuencia, propongo adoptar esta convención como estándar en esWikilibros: * Las categorías destinadas a agrupar las páginas de un libro pasarán a usar el prefijo «Libro:». * Las categorías destinadas a catalogar libros por temática pasarán a usar el prefijo «Estante:». Las categorías existentes se irán trasladando progresivamente a esta estructura, corrigiendo los casos en los que actualmente ambos usos se solapan. Se trata de un pequeño cambio principalmente organizativo, que no modifica el contenido de los libros, pero sí hace que la estructura de categorías sea mucho más clara, coherente y fácil de mantener, y que además ya se usa en otras ediciones de Wikilibros. Voy a esperar unos días por si alguien quiere dejar algún comentario sobre este asunto, tras los cuales mi intención es comenzar a usar esta convención y dejarla documentada para que pueda aplicarse de forma consistente en el futuro. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:18 15 jul 2026 (UTC) :Mientras trabajaba en este asunto, me he fijado también en que en Wikilibros tenemos dos «categorías raíz»: :# [[:Categoría:Categorías]] :# [[:Categoría:Principal]] :Ambas dicen ser «la categoría raíz de nuestro sistemas de categorías». Esta duplicidad es un error por motivos obvios. :Mi sugerencia es que nos quedemos sólo con [[:Categoría:Categorías]]. Por los siguientes motivos: :# «Categorías» es mucho mas claro que «Principal». ¿Qué significa principal? ¿Principal qué? «Categorías» deja bastante claro, que esa categoría alberga categorías. :# Por coherencia con otras wikis, ya que en esWikipedia la categoría raíz de otras categorías también se llama «Categorías». Y en enWikibooks se llama «Categories». :[[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:04 15 jul 2026 (UTC) gvvia87ma1sidum46hawjj0j1tmx2xr 427893 427891 2026-07-16T01:47:53Z Mazbel 57931 /* Incorporación del enlace «Contactos legales y de seguridad» en el pie de página de vuestra wiki */ archive to [[Wikilibros:Café/Archivo/2026#Incorporación del enlace «Contactos legales y de seguridad» en el pie de página de vuestra wiki]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]]) 427893 wikitext text/x-wiki {{Wikilibros:Café/Cabecera}} {{Usuario:MABot/config |archive = Wikilibros:Café/Archivo/%(year)s |algo = old(45d) |counter = 1 |archiveheader = {{Archivo}} |minthreadsleft = 0 |minthreadstoarchive = 1 }} == Petición para establecer una política sobre inteligencia artificial == Buenas. En el tiempo que llevo en Wikilibros, he observado varias páginas editadas mediante copias directas de texto generado por chatbots de IA (como ChatGPT, Copilot, Claude, Gemini, o Grok). Esto me preocupa, ya que este tipo de ediciones pueden resultar muy perjudiciales, y mientras que en muchas otras wikis ya se han establecido políticas sobre el uso de IA, en Wikilibros aún no tenemos ninguna política específica al respecto. Wikilibros en inglés cuenta con una política prohibiendo explícitamente esta clase de ediciones, que además explica el daño que pueden llegar a hacer, traduzco: {{Cita|Solicitar a un chatbot que escriba un libro o un ensayo puede dar lugar a la producción de [[W:Alucinación (inteligencia artificial)|invenciones completas]], incluyendo referencias ficticias. El resultado puede ser sesgado, difamar a personas reales, infringir derechos de autor o simplemente ser de mala calidad. <br>...<br> Estos problemas pueden volverse rápidamente problemáticos en comunidades y entornos grandes donde la transferencia de conocimiento, la verificabilidad, la rendición de cuentas y el pensamiento crítico son importantes. En particular, el alto volumen y la velocidad a la que los LLM pueden generar contenido, todo el cual debe ser verificado, implica que su uso supone un riesgo considerable. Por lo tanto, los materiales de aprendizaje de idiomas no deben utilizarse para generar o resumir material e ideas en Wikibooks, y no se debe confiar ciegamente en sus fuentes. |[https://en.wikibooks.org/wiki/Wikibooks:Artificial_intelligence Extraído y traducido de la política de Wikibooks (en inglés) sobre el uso de IA.] }} Wikipedia en Español también [[w:Wikipedia:Redacción de artículos con modelos de lenguaje grandes|cuenta con una política sobre este asunto]] que me parece correcta. Como Wikilibros en Español es una wiki tan pequeña, quizás sea mas adecuado adaptar o traducir la política de Wikibooks en inglés, o simplemente redirigir o adaptar la política de Wikipedia en español. En mi opinión, las políticas de estas wikis son sólidas, y además, han sido redactadas y consensuadas por más usuarios de los que tenemos aquí, por lo que cuentan con un buen consenso, y están más desarrolladas y probadas en comunidades más grandes. Quedo a la escucha de comentarios, y espero que podamos avanzar en este frente. Menciono a @[[Usuario:Mazbel|Mazbel]] que siempre es de gran ayuda. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 17:33 27 jun 2026 (UTC) :Creo que sí sería conveniente que Wikilibros contara con una política específica sobre el uso de la IA, no tanto porque sea una tecnología distinta a otras herramientasd e edición, sino por la escala a la que permite generar contenido. A diferencia de Wikipedia, aquí no construimos artículos independientes, sino libros completos y materiales de aprendizaje, donde la estructura, la coherencia y la progresión de los contenidos son partwe esencial de la calidad de la obra. Un texto generado por IA puede ser correcto en términos generales y, aun así, presentar problemas de organización, inconsistencias entre capítulos, ejemplos poco adecuados o explicaciones que no responden a un criterio didáctico claro. Detectar ese tipo de problemas exige una revisión completa del libro, algo que en una comunidad pequeña como eswikibooks rara vez es posible cuando se incorporan grandes cantidades de contenido. :Por ello, considero que una política debería ser relativamente estricta con la incorporación de texto generado por IA. No porque toda utilización de estas herramientas sea necesariamente perjudicial, sino porque el riesgo de publicar contenido insuficientemente revisado es mayor que la capacidad que tiene la comunidad para detectarlo y corregirlo. En mi opinión, la IA puede tener cabida como herramienta de apoyo durante el proceso de redacción, pero no debería emplearse para generar de forma directa partes sustanciales de un libro destinadas a su publicación. En un proyecto con pocos editores activos, resulta más prudente priorizar la calidad y el mantenimiento de los libros que facilitar un aumento rápido de contenido cuya revisión efectiva no puede garantizarse. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:49 27 jun 2026 (UTC) ::Estoy de acuerdo con todo lo que has dicho, especialmente con tu segundo párrafo, del que suscribo cada palabra al 100%. ::Lo de adaptar una política de otra wiki, lo mencioné en gran medida, no por la dificultad en sí de redactarla, si no porque en estos lugares ya existe consenso, y así puede ser más fácil ponerse de acuerdo. Pero si en Wikilibros en español también estamos todos más o menos de acuerdo, no veo por qué no podríamos redactar la nuestra propia. ::Concuerdo totalmente en que habría que ser relativamente estricto, porque por los chatbots de IA pueden generar enormes cantidades de texto, y al ser una comunidad tan pequeña no tenemos capacidad para pararnos a revisar un libro que se generase con IA. ::En este sentido, la política de enWikibooks me parece suficientemente estricta, además, [https://en.wikibooks.org/wiki/Wikibooks_talk:Artificial_intelligence/Archive_1 se puede leer el debate que tuvieron para alcanzar tal consenso (en inglés)] que es muy interesante. ::Según la política enWikibooks: ::# Se advierte brevemente de que el contenido de IA puede ser inexacto, inventado o de baja calidad. (Personalmente creo que además podría advertirse de los posibles problemas de copyright que puede llegar a causar). ::# No se permite usar IA para generar, resumir o traducir contenido. ::# Está explícitamente prohibido hacer ediciones que consistan en copiar y pegar texto de IA en páginas. ::# Se avisa de que el contenido debe ser siempre verificado y escrito por humanos. ::# No se prohíbe que alguien consulte o haga uso de la IA como apoyo externo, lo que está prohibido es que la IA genere el contenido, pero uno puede usarla para consulta externa si lo desea. ::Considero que podríamos basarnos en la política de enWikibooks y traducirla y adaptarla a nuestra versión. Si estamos más o menos de acuerdo en que es adecuada, sería muy sencillo incorporar esta política. Si os parece bien esto, podría escribirla basándome en enWikibooks y luego mencionaros para que la reviséis. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:47 27 jun 2026 (UTC) : De acuerdo a que en conjunto establezcamos una política en base al uso de IA. Es algo que se debe de tocar acá y me parece buen puerto, el guiarnos de la política establecida desde enWikibooks [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 02:29 28 jun 2026 (UTC) ::Buenas @[[Usuario:Mazbel|Mazbel]] y @[[Usuario:Divinations|Divinations]] he tomado la iniciativa y redactado la página «''[[Wikilibros:Política sobre el uso de inteligencia artificial generativa]]''» (que de momento está marcada como un borrador). Esta página está traducida y adaptada de la versión de enWikibooks, me he inspirado también en la conversación que hemos tenido por aquí, y en la misma política en la Wikipedia en español. ::Os agradecería si pudieseis revisar esta página, sentíos libres de editarla si lo consideráis, y os invito a continuar esta conversación en la discusión de esta página. Gracias por vuestra colaboración en este asunto. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 09:33 28 jun 2026 (UTC) :::<s>Gracias, [[Usuario:Antimundo|Antimundo]]. Añadí un atajo para que pueda ser encontrada más fácilmente. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 17:47 28 jun 2026 (UTC)</s> ::::Parece que se borró. Creo que me adelanté antes de tiempo, mejor esperar a obtener un mejor consenso comunitario más allá de solo tres usuarios. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:44 28 jun 2026 (UTC) : Me temo que antes de formarse como una política dentro de Wikilibros, debe ser llevada a votación, un aviso tanto para @[[Usuario:Antimundo]] como para @[[Usuario:Divinations]]. Estoy adaptando el contenido para que se proceda a votación. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 20:52 28 jun 2026 (UTC) ::Entendido, gracias por iniciar el procedimiento. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:01 28 jun 2026 (UTC) == Votación sobre nueva política sobre el uso de la inteligencia artificial == En relación con el hilo anterior, se abrió una página de votación para establecer como una nueva política dentro de Wikilibros en Español. El enlace de la votación se encuentra acá: [[Wikilibros:Votaciones/Política sobre el uso de inteligencia artificial generativa]]. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 21:24 28 jun 2026 (UTC) == Clarificar el propósito de las plantillas infraesbozo y contextualizar == Buenas, en esWikilibros contamos con las plantillas {{tlx|Infraesbozo}} y {{tlx|Contextualizar}} que se adaptaron desde esWikipedia en 2015. Sin embargo, la forma en la que están redactadas en Wikilibros, sumada a la falta de documentación, hace que resulten demasiado similares entre sí y sus propósitos se solapen. Estas plantillas en esWikipedia tienen [[w:Wikipedia:Infraesbozo|propósitos claramente diferenciados]]: * [[w:Plantilla:Infraesbozo|Infraesbozo]]: Se utiliza para páginas cuyo contenido es insuficiente para constituir un esbozo válido. No depende de la longitud del texto, si no de que el artículo tenga algo de información mínima para desarrollar el tema. Se sugieren las siguientes preguntas para establecer si una página: *# ¿El artículo está contextualizado en tema, lugar y tiempo?, es decir ¿entiendo exactamente de qué habla? *# ¿El artículo aporta alguna, aunque sea mínima, información adicional enciclopédicamente pertinente? (Adicional a la imprescindible para contextualizar y marcar relevancia, se entiende). *# ¿El artículo muestra la relevancia de su tema? * [[w:Plantilla:Contextualizar|Contextualizar]]: Se utiliza para artículos que no proporcionan el contexto suficiente para un lector general. Su objetivo es solicitar que se añada información introductoria, explicaciones o contexto que permitan entender adecuadamente el tema tratado, sin que ello implique que el artículo sea demasiado corto. Quiero empezar señalando la importancia que, en mi opinión, tiene borrar los infraesbozos, especialmente en esWikilibros. En el proyecto existen muchísios libros muy incompletos y abandonados que se escribieron hace 10 o 20 años que a penas contienen una portada y, como mucho, un par de frases. En la mayoría de casos está claro que su autor no va a regresar para terminarlo, por lo que permanecen indefinidamente en ese estado. Mantener todos estos libros dificulta considerablemente el mantenimiento del proyecto. Por un lado, incrementa enormemente el número de páginas que requieren seguimiento sin aportar contenido útil. Por otro, complica la identificación de libros que realmente cuentan con algo de desarrollo o que tienen posibilidades de completarse. Además, transmiten una imagen de falta de mantenimiento y puede dificultar la navegación y el descubrimiento de obras que sí ofrecen un contenido aprovechable. A todo esto se suma, que estos infraesbozos rara vez sirven como punto de partida para futuros colaboradores, cuando alguien decide crear un libro sobre un tema que ya cuenta con un infraesbozo, lo habitual es que el contenido existente sea tan escaso que no resulte útil para construir sobre él. En la práctica, el trabajo consiste en rehacer el libro desde el principio, ya que apenas hay material que conservar o desarrollar. En estos casos, la existencia del infraesbozo ni si quiera facilita la creación del libro. Sin embargo, en Wikilibros, nuestra plantilla de «''Infraesbozo''» dice «''Este libro es demasiado reducido y carece de información básica que permita saber de qué se trata.''» Pero esto habla de contexto, y para contexto ya existe la plantilla «''Contextualizar''». Voy a poner algún ejemplo sobre por qué considero esto problemático: * Existe el libro de [[Vim]] que tiene una portada y '''absolutamenete nada''' de contenido. Está clarísimo que el libro pretende tratar sobre [[w:Vim|el editor de texto Vim]], su problema no es que «''carece de información básica que permita saber de qué se trata.''», sé perfectamente de qué quiere tratar. Pero sencillamente no contiene información útil. No hay ningún texto útil que desarrollar, ampliar o contextualizar, ni puede aportar absolutamente nada a ningún lector. Además, lleva once años sin recibir ediciones, por lo que es muy poco probable que su autor original vaya a volver en ningún momento a completarlo. Este tipo de «libros» me parecen problemáticos por lo que comenté anteriormente. * Hay muchos casos similares en Wikilibros. Por ejemplo, existe un libro de [[Vida saludable]] que contiene una portada y una breve frase introductoria, pero nada más. De nuevo, el problema no es que «''carece de información básica que permita saber de qué se trata.''», cualquiera entiende que el libro pretende tratar sobre la vida saludable. Lo que ocurre es que ese contenido no constituye ninguna base útil para un libro. No desarrolla el tema, no aporta información aprovechable al lector y, en la práctica, cualquier editor que quisiera escribir un libro sobre ese tema tendría que empezar de cero. Además hace 16 años que no se edita, no parece que su autor original vaya a volver para completarlo. Por ello, sugiero adaptar estas plantillas para que sus propósitos queden claramente diferenciados, siguiendo el criterio de esWikipedia. En concreto, que «''Infraesbozo''» se reserve para señalar libros cuyo contenido es insuficiente para constituir un esbozo válido, independientemente de que el tema esté claramente identificado, y que «''Contextualizar''» se utilice únicamente cuando el problema sea la falta de contexto o de información introductoria que dificulte la comprensión del contenido existente. De este modo, ambas plantillas dejarían de solapar sus funciones y su uso resultaría mucho más claro y coherente. Además, creo que el origen del problema probablemente sea bastante trivial y ni si quiera responde a ninguna decisión deliberada: simplemente se trata de un pequeño cambio de redacción que se introdujo al adaptar las plantillas desde esWikipedia hace once años, sin que hubiera una intención concreta detrás. Con el tiempo, esa pequeña diferencia ha acabado generando este solapamiento entre ambas plantillas. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:30 30 jun 2026 (UTC) :Han pasado ocho días desde que planteé esto y, dado que no ha habido ninguna objeción y tampoco considero que se trate de un cambio especialmente controvertido, voy a hacer el ajuste que propuse para clarificar la redacción de las plantillas, de forma similar a como ya está escrito en esWikipedia, tal y como expliqué anteriormente. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 16:16 8 jul 2026 (UTC) == Un pequeño hito que quería compartir == ¡Buenas! quería compartir con orgullo un pequeño hito conseguido en Wikilibros, solo por informar de las tareas que ando haciendo. 😊 Últimamente he estado arreglando literalmente '''miles''' de errores de sintaxis que reporta el [[:mw:Extension:Linter|linter]] de Wikilibros. Si entráis en la [[Especial:Errores_de_sintaxis|lista de errores de sintaxis]] podréis ver que la mayoría de categorías de errores graves están a 0, o se han reducido también drásticamente. Arreglar estos errores puede parecer poco llamativo porque no cambia en nada el contenido de las páginas, pero corregirlos hace que Wikilibros sea más fácil de mantener, más compatible con futuras actualizaciones de MediaWiki, cumpla los estándares modernos de accesibilidad y reduce la posibilidad de que las páginas no se rendericen correctamente. No puedo arreglar ''todos'' los errores porque muchos están en páginas protegidas que no puedo editar al no ser bibliotecario, además son muy numerosos (muchos miles) y algunos son complejos de arreglar. Pero ando trabajando en ello en mis ratos libres. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:14 8 jul 2026 (UTC) == Estandarización de las categorías de libros == En esWikilibros tenemos un problema grave con la catalogación de los libros, que en enWikibooks no existe gracias a una simple convención a la hora de nombrar las categorías. Ya expuse este asunto en [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|un escrito en mi página de usuario]]. ''(Nótese que voy a usar enWikibooks de ejemplo, pero que esa misma solución se usa en otras ediciones de Wikilibros como en alemán o portugués).'' Tanto en esWikilibros como en enWikibooks, los libros tienen dos clases de categorías: # '''Categoría para ''agrupar'' el libro''': Todas las páginas de un mismo libro se agrupan bajo una categoría con el mismo nombre del libro. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Book:C programming]]. # '''Categoría para ''catalogar'' el libro''': El libro en sí mismo se cataloga bajo una o varias categorías. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Shelf:C programming language]] que agrupa todos los libros sobre programación en C, como [[:en:Linear Algebra and the C Language]] o [[:en:A Little C Primer]]. Habréis notado que en enWikibooks usan los prefijos: # '''''Book''''': Para ''agrupar'' las páginas del libro. # '''''Shelf''''': Para ''catalogar'' libros. En esWikilibros, hacemos exactamente lo mismo, con la diferencia de que no usamos estos prefijos. Lo cual es un problema porque esto genera innumerables errores como los siguientes: * El libro [[Programación en C++]] se agrupa bajo la categoría [[:Categoría:Programación en C++]]. * Pero a su vez, la [[:Categoría:Programación en C++]] también se usa para catalogar libros relacionados con programación en C++, por lo que esta categoría incluye también el libro [[Desarrollo de videojuegos para PSP con C++ y SDL]] y [[Programación con Qt4]]. Es decir, la [[:Categoría:Programación en C++]] solapa dos propósitos distintos, y este problema ocurre con una gran cantidad de libros en esWikilibros, y hace que sea muy confuso navegar por las categorías de esWikilibros. ;La solución Usar el mismo sistema que usan en otras ediciones de Wikilibros, donde los libros se agrupan bajo una categoría llamada ''Libro:'' (de forma que quedaría ''Categoría:Libro:Programación en C++''), y los libros a su vez se catalogan mediante ''Shelf:'' o en español ''Estante:'' (de forma que quedaría ''Categoría:Estante:Programación en C++''). Curiosamente, ya ha existido algún tímido intento de usar este sistema en esWikilibros, por eso, por ejemplo, tenemos la categoría de catalogación [[:Categoría:Estante:Lenguajes de programación]] y el libro de [[Haskell]] está agrupado bajo la categoría [[:Categoría:Libro:Haskell]]. Pero esto no lo tenemos estandarizado, porque directamente no seguimos ningún sistema en particular [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|como ya expliqué en mi reciente escrito]]. ; Conclusión En consecuencia, propongo adoptar esta convención como estándar en esWikilibros: * Las categorías destinadas a agrupar las páginas de un libro pasarán a usar el prefijo «Libro:». * Las categorías destinadas a catalogar libros por temática pasarán a usar el prefijo «Estante:». Las categorías existentes se irán trasladando progresivamente a esta estructura, corrigiendo los casos en los que actualmente ambos usos se solapan. Se trata de un pequeño cambio principalmente organizativo, que no modifica el contenido de los libros, pero sí hace que la estructura de categorías sea mucho más clara, coherente y fácil de mantener, y que además ya se usa en otras ediciones de Wikilibros. Voy a esperar unos días por si alguien quiere dejar algún comentario sobre este asunto, tras los cuales mi intención es comenzar a usar esta convención y dejarla documentada para que pueda aplicarse de forma consistente en el futuro. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:18 15 jul 2026 (UTC) :Mientras trabajaba en este asunto, me he fijado también en que en Wikilibros tenemos dos «categorías raíz»: :# [[:Categoría:Categorías]] :# [[:Categoría:Principal]] :Ambas dicen ser «la categoría raíz de nuestro sistemas de categorías». Esta duplicidad es un error por motivos obvios. :Mi sugerencia es que nos quedemos sólo con [[:Categoría:Categorías]]. Por los siguientes motivos: :# «Categorías» es mucho mas claro que «Principal». ¿Qué significa principal? ¿Principal qué? «Categorías» deja bastante claro, que esa categoría alberga categorías. :# Por coherencia con otras wikis, ya que en esWikipedia la categoría raíz de otras categorías también se llama «Categorías». Y en enWikibooks se llama «Categories». :[[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:04 15 jul 2026 (UTC) cv9klokew2klzek1n3njcp1i6lvdh67 427977 427893 2026-07-16T07:03:20Z Antimundo 74354 /* Estandarización de las categorías de libros */ Respuesta 427977 wikitext text/x-wiki {{Wikilibros:Café/Cabecera}} {{Usuario:MABot/config |archive = Wikilibros:Café/Archivo/%(year)s |algo = old(45d) |counter = 1 |archiveheader = {{Archivo}} |minthreadsleft = 0 |minthreadstoarchive = 1 }} == Petición para establecer una política sobre inteligencia artificial == Buenas. En el tiempo que llevo en Wikilibros, he observado varias páginas editadas mediante copias directas de texto generado por chatbots de IA (como ChatGPT, Copilot, Claude, Gemini, o Grok). Esto me preocupa, ya que este tipo de ediciones pueden resultar muy perjudiciales, y mientras que en muchas otras wikis ya se han establecido políticas sobre el uso de IA, en Wikilibros aún no tenemos ninguna política específica al respecto. Wikilibros en inglés cuenta con una política prohibiendo explícitamente esta clase de ediciones, que además explica el daño que pueden llegar a hacer, traduzco: {{Cita|Solicitar a un chatbot que escriba un libro o un ensayo puede dar lugar a la producción de [[W:Alucinación (inteligencia artificial)|invenciones completas]], incluyendo referencias ficticias. El resultado puede ser sesgado, difamar a personas reales, infringir derechos de autor o simplemente ser de mala calidad. <br>...<br> Estos problemas pueden volverse rápidamente problemáticos en comunidades y entornos grandes donde la transferencia de conocimiento, la verificabilidad, la rendición de cuentas y el pensamiento crítico son importantes. En particular, el alto volumen y la velocidad a la que los LLM pueden generar contenido, todo el cual debe ser verificado, implica que su uso supone un riesgo considerable. Por lo tanto, los materiales de aprendizaje de idiomas no deben utilizarse para generar o resumir material e ideas en Wikibooks, y no se debe confiar ciegamente en sus fuentes. |[https://en.wikibooks.org/wiki/Wikibooks:Artificial_intelligence Extraído y traducido de la política de Wikibooks (en inglés) sobre el uso de IA.] }} Wikipedia en Español también [[w:Wikipedia:Redacción de artículos con modelos de lenguaje grandes|cuenta con una política sobre este asunto]] que me parece correcta. Como Wikilibros en Español es una wiki tan pequeña, quizás sea mas adecuado adaptar o traducir la política de Wikibooks en inglés, o simplemente redirigir o adaptar la política de Wikipedia en español. En mi opinión, las políticas de estas wikis son sólidas, y además, han sido redactadas y consensuadas por más usuarios de los que tenemos aquí, por lo que cuentan con un buen consenso, y están más desarrolladas y probadas en comunidades más grandes. Quedo a la escucha de comentarios, y espero que podamos avanzar en este frente. Menciono a @[[Usuario:Mazbel|Mazbel]] que siempre es de gran ayuda. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 17:33 27 jun 2026 (UTC) :Creo que sí sería conveniente que Wikilibros contara con una política específica sobre el uso de la IA, no tanto porque sea una tecnología distinta a otras herramientasd e edición, sino por la escala a la que permite generar contenido. A diferencia de Wikipedia, aquí no construimos artículos independientes, sino libros completos y materiales de aprendizaje, donde la estructura, la coherencia y la progresión de los contenidos son partwe esencial de la calidad de la obra. Un texto generado por IA puede ser correcto en términos generales y, aun así, presentar problemas de organización, inconsistencias entre capítulos, ejemplos poco adecuados o explicaciones que no responden a un criterio didáctico claro. Detectar ese tipo de problemas exige una revisión completa del libro, algo que en una comunidad pequeña como eswikibooks rara vez es posible cuando se incorporan grandes cantidades de contenido. :Por ello, considero que una política debería ser relativamente estricta con la incorporación de texto generado por IA. No porque toda utilización de estas herramientas sea necesariamente perjudicial, sino porque el riesgo de publicar contenido insuficientemente revisado es mayor que la capacidad que tiene la comunidad para detectarlo y corregirlo. En mi opinión, la IA puede tener cabida como herramienta de apoyo durante el proceso de redacción, pero no debería emplearse para generar de forma directa partes sustanciales de un libro destinadas a su publicación. En un proyecto con pocos editores activos, resulta más prudente priorizar la calidad y el mantenimiento de los libros que facilitar un aumento rápido de contenido cuya revisión efectiva no puede garantizarse. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:49 27 jun 2026 (UTC) ::Estoy de acuerdo con todo lo que has dicho, especialmente con tu segundo párrafo, del que suscribo cada palabra al 100%. ::Lo de adaptar una política de otra wiki, lo mencioné en gran medida, no por la dificultad en sí de redactarla, si no porque en estos lugares ya existe consenso, y así puede ser más fácil ponerse de acuerdo. Pero si en Wikilibros en español también estamos todos más o menos de acuerdo, no veo por qué no podríamos redactar la nuestra propia. ::Concuerdo totalmente en que habría que ser relativamente estricto, porque por los chatbots de IA pueden generar enormes cantidades de texto, y al ser una comunidad tan pequeña no tenemos capacidad para pararnos a revisar un libro que se generase con IA. ::En este sentido, la política de enWikibooks me parece suficientemente estricta, además, [https://en.wikibooks.org/wiki/Wikibooks_talk:Artificial_intelligence/Archive_1 se puede leer el debate que tuvieron para alcanzar tal consenso (en inglés)] que es muy interesante. ::Según la política enWikibooks: ::# Se advierte brevemente de que el contenido de IA puede ser inexacto, inventado o de baja calidad. (Personalmente creo que además podría advertirse de los posibles problemas de copyright que puede llegar a causar). ::# No se permite usar IA para generar, resumir o traducir contenido. ::# Está explícitamente prohibido hacer ediciones que consistan en copiar y pegar texto de IA en páginas. ::# Se avisa de que el contenido debe ser siempre verificado y escrito por humanos. ::# No se prohíbe que alguien consulte o haga uso de la IA como apoyo externo, lo que está prohibido es que la IA genere el contenido, pero uno puede usarla para consulta externa si lo desea. ::Considero que podríamos basarnos en la política de enWikibooks y traducirla y adaptarla a nuestra versión. Si estamos más o menos de acuerdo en que es adecuada, sería muy sencillo incorporar esta política. Si os parece bien esto, podría escribirla basándome en enWikibooks y luego mencionaros para que la reviséis. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:47 27 jun 2026 (UTC) : De acuerdo a que en conjunto establezcamos una política en base al uso de IA. Es algo que se debe de tocar acá y me parece buen puerto, el guiarnos de la política establecida desde enWikibooks [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 02:29 28 jun 2026 (UTC) ::Buenas @[[Usuario:Mazbel|Mazbel]] y @[[Usuario:Divinations|Divinations]] he tomado la iniciativa y redactado la página «''[[Wikilibros:Política sobre el uso de inteligencia artificial generativa]]''» (que de momento está marcada como un borrador). Esta página está traducida y adaptada de la versión de enWikibooks, me he inspirado también en la conversación que hemos tenido por aquí, y en la misma política en la Wikipedia en español. ::Os agradecería si pudieseis revisar esta página, sentíos libres de editarla si lo consideráis, y os invito a continuar esta conversación en la discusión de esta página. Gracias por vuestra colaboración en este asunto. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 09:33 28 jun 2026 (UTC) :::<s>Gracias, [[Usuario:Antimundo|Antimundo]]. Añadí un atajo para que pueda ser encontrada más fácilmente. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 17:47 28 jun 2026 (UTC)</s> ::::Parece que se borró. Creo que me adelanté antes de tiempo, mejor esperar a obtener un mejor consenso comunitario más allá de solo tres usuarios. [[Usuario:Divinations|Divinations]] ([[Usuario discusión:Divinations|discusión]]) 20:44 28 jun 2026 (UTC) : Me temo que antes de formarse como una política dentro de Wikilibros, debe ser llevada a votación, un aviso tanto para @[[Usuario:Antimundo]] como para @[[Usuario:Divinations]]. Estoy adaptando el contenido para que se proceda a votación. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 20:52 28 jun 2026 (UTC) ::Entendido, gracias por iniciar el procedimiento. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 22:01 28 jun 2026 (UTC) == Votación sobre nueva política sobre el uso de la inteligencia artificial == En relación con el hilo anterior, se abrió una página de votación para establecer como una nueva política dentro de Wikilibros en Español. El enlace de la votación se encuentra acá: [[Wikilibros:Votaciones/Política sobre el uso de inteligencia artificial generativa]]. Saludos [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 21:24 28 jun 2026 (UTC) == Clarificar el propósito de las plantillas infraesbozo y contextualizar == Buenas, en esWikilibros contamos con las plantillas {{tlx|Infraesbozo}} y {{tlx|Contextualizar}} que se adaptaron desde esWikipedia en 2015. Sin embargo, la forma en la que están redactadas en Wikilibros, sumada a la falta de documentación, hace que resulten demasiado similares entre sí y sus propósitos se solapen. Estas plantillas en esWikipedia tienen [[w:Wikipedia:Infraesbozo|propósitos claramente diferenciados]]: * [[w:Plantilla:Infraesbozo|Infraesbozo]]: Se utiliza para páginas cuyo contenido es insuficiente para constituir un esbozo válido. No depende de la longitud del texto, si no de que el artículo tenga algo de información mínima para desarrollar el tema. Se sugieren las siguientes preguntas para establecer si una página: *# ¿El artículo está contextualizado en tema, lugar y tiempo?, es decir ¿entiendo exactamente de qué habla? *# ¿El artículo aporta alguna, aunque sea mínima, información adicional enciclopédicamente pertinente? (Adicional a la imprescindible para contextualizar y marcar relevancia, se entiende). *# ¿El artículo muestra la relevancia de su tema? * [[w:Plantilla:Contextualizar|Contextualizar]]: Se utiliza para artículos que no proporcionan el contexto suficiente para un lector general. Su objetivo es solicitar que se añada información introductoria, explicaciones o contexto que permitan entender adecuadamente el tema tratado, sin que ello implique que el artículo sea demasiado corto. Quiero empezar señalando la importancia que, en mi opinión, tiene borrar los infraesbozos, especialmente en esWikilibros. En el proyecto existen muchísios libros muy incompletos y abandonados que se escribieron hace 10 o 20 años que a penas contienen una portada y, como mucho, un par de frases. En la mayoría de casos está claro que su autor no va a regresar para terminarlo, por lo que permanecen indefinidamente en ese estado. Mantener todos estos libros dificulta considerablemente el mantenimiento del proyecto. Por un lado, incrementa enormemente el número de páginas que requieren seguimiento sin aportar contenido útil. Por otro, complica la identificación de libros que realmente cuentan con algo de desarrollo o que tienen posibilidades de completarse. Además, transmiten una imagen de falta de mantenimiento y puede dificultar la navegación y el descubrimiento de obras que sí ofrecen un contenido aprovechable. A todo esto se suma, que estos infraesbozos rara vez sirven como punto de partida para futuros colaboradores, cuando alguien decide crear un libro sobre un tema que ya cuenta con un infraesbozo, lo habitual es que el contenido existente sea tan escaso que no resulte útil para construir sobre él. En la práctica, el trabajo consiste en rehacer el libro desde el principio, ya que apenas hay material que conservar o desarrollar. En estos casos, la existencia del infraesbozo ni si quiera facilita la creación del libro. Sin embargo, en Wikilibros, nuestra plantilla de «''Infraesbozo''» dice «''Este libro es demasiado reducido y carece de información básica que permita saber de qué se trata.''» Pero esto habla de contexto, y para contexto ya existe la plantilla «''Contextualizar''». Voy a poner algún ejemplo sobre por qué considero esto problemático: * Existe el libro de [[Vim]] que tiene una portada y '''absolutamenete nada''' de contenido. Está clarísimo que el libro pretende tratar sobre [[w:Vim|el editor de texto Vim]], su problema no es que «''carece de información básica que permita saber de qué se trata.''», sé perfectamente de qué quiere tratar. Pero sencillamente no contiene información útil. No hay ningún texto útil que desarrollar, ampliar o contextualizar, ni puede aportar absolutamente nada a ningún lector. Además, lleva once años sin recibir ediciones, por lo que es muy poco probable que su autor original vaya a volver en ningún momento a completarlo. Este tipo de «libros» me parecen problemáticos por lo que comenté anteriormente. * Hay muchos casos similares en Wikilibros. Por ejemplo, existe un libro de [[Vida saludable]] que contiene una portada y una breve frase introductoria, pero nada más. De nuevo, el problema no es que «''carece de información básica que permita saber de qué se trata.''», cualquiera entiende que el libro pretende tratar sobre la vida saludable. Lo que ocurre es que ese contenido no constituye ninguna base útil para un libro. No desarrolla el tema, no aporta información aprovechable al lector y, en la práctica, cualquier editor que quisiera escribir un libro sobre ese tema tendría que empezar de cero. Además hace 16 años que no se edita, no parece que su autor original vaya a volver para completarlo. Por ello, sugiero adaptar estas plantillas para que sus propósitos queden claramente diferenciados, siguiendo el criterio de esWikipedia. En concreto, que «''Infraesbozo''» se reserve para señalar libros cuyo contenido es insuficiente para constituir un esbozo válido, independientemente de que el tema esté claramente identificado, y que «''Contextualizar''» se utilice únicamente cuando el problema sea la falta de contexto o de información introductoria que dificulte la comprensión del contenido existente. De este modo, ambas plantillas dejarían de solapar sus funciones y su uso resultaría mucho más claro y coherente. Además, creo que el origen del problema probablemente sea bastante trivial y ni si quiera responde a ninguna decisión deliberada: simplemente se trata de un pequeño cambio de redacción que se introdujo al adaptar las plantillas desde esWikipedia hace once años, sin que hubiera una intención concreta detrás. Con el tiempo, esa pequeña diferencia ha acabado generando este solapamiento entre ambas plantillas. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:30 30 jun 2026 (UTC) :Han pasado ocho días desde que planteé esto y, dado que no ha habido ninguna objeción y tampoco considero que se trate de un cambio especialmente controvertido, voy a hacer el ajuste que propuse para clarificar la redacción de las plantillas, de forma similar a como ya está escrito en esWikipedia, tal y como expliqué anteriormente. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 16:16 8 jul 2026 (UTC) == Un pequeño hito que quería compartir == ¡Buenas! quería compartir con orgullo un pequeño hito conseguido en Wikilibros, solo por informar de las tareas que ando haciendo. 😊 Últimamente he estado arreglando literalmente '''miles''' de errores de sintaxis que reporta el [[:mw:Extension:Linter|linter]] de Wikilibros. Si entráis en la [[Especial:Errores_de_sintaxis|lista de errores de sintaxis]] podréis ver que la mayoría de categorías de errores graves están a 0, o se han reducido también drásticamente. Arreglar estos errores puede parecer poco llamativo porque no cambia en nada el contenido de las páginas, pero corregirlos hace que Wikilibros sea más fácil de mantener, más compatible con futuras actualizaciones de MediaWiki, cumpla los estándares modernos de accesibilidad y reduce la posibilidad de que las páginas no se rendericen correctamente. No puedo arreglar ''todos'' los errores porque muchos están en páginas protegidas que no puedo editar al no ser bibliotecario, además son muy numerosos (muchos miles) y algunos son complejos de arreglar. Pero ando trabajando en ello en mis ratos libres. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:14 8 jul 2026 (UTC) == Estandarización de las categorías de libros == En esWikilibros tenemos un problema grave con la catalogación de los libros, que en enWikibooks no existe gracias a una simple convención a la hora de nombrar las categorías. Ya expuse este asunto en [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|un escrito en mi página de usuario]]. ''(Nótese que voy a usar enWikibooks de ejemplo, pero que esa misma solución se usa en otras ediciones de Wikilibros como en alemán o portugués).'' Tanto en esWikilibros como en enWikibooks, los libros tienen dos clases de categorías: # '''Categoría para ''agrupar'' el libro''': Todas las páginas de un mismo libro se agrupan bajo una categoría con el mismo nombre del libro. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Book:C programming]]. # '''Categoría para ''catalogar'' el libro''': El libro en sí mismo se cataloga bajo una o varias categorías. Por ejemplo, el libro [[:en:C programming]] pertenece a la categoría [[:en:Category:Shelf:C programming language]] que agrupa todos los libros sobre programación en C, como [[:en:Linear Algebra and the C Language]] o [[:en:A Little C Primer]]. Habréis notado que en enWikibooks usan los prefijos: # '''''Book''''': Para ''agrupar'' las páginas del libro. # '''''Shelf''''': Para ''catalogar'' libros. En esWikilibros, hacemos exactamente lo mismo, con la diferencia de que no usamos estos prefijos. Lo cual es un problema porque esto genera innumerables errores como los siguientes: * El libro [[Programación en C++]] se agrupa bajo la categoría [[:Categoría:Programación en C++]]. * Pero a su vez, la [[:Categoría:Programación en C++]] también se usa para catalogar libros relacionados con programación en C++, por lo que esta categoría incluye también el libro [[Desarrollo de videojuegos para PSP con C++ y SDL]] y [[Programación con Qt4]]. Es decir, la [[:Categoría:Programación en C++]] solapa dos propósitos distintos, y este problema ocurre con una gran cantidad de libros en esWikilibros, y hace que sea muy confuso navegar por las categorías de esWikilibros. ;La solución Usar el mismo sistema que usan en otras ediciones de Wikilibros, donde los libros se agrupan bajo una categoría llamada ''Libro:'' (de forma que quedaría ''Categoría:Libro:Programación en C++''), y los libros a su vez se catalogan mediante ''Shelf:'' o en español ''Estante:'' (de forma que quedaría ''Categoría:Estante:Programación en C++''). Curiosamente, ya ha existido algún tímido intento de usar este sistema en esWikilibros, por eso, por ejemplo, tenemos la categoría de catalogación [[:Categoría:Estante:Lenguajes de programación]] y el libro de [[Haskell]] está agrupado bajo la categoría [[:Categoría:Libro:Haskell]]. Pero esto no lo tenemos estandarizado, porque directamente no seguimos ningún sistema en particular [[Usuario:Antimundo/Taller/El estado actual de Wikilibros#Problemas_de_organización|como ya expliqué en mi reciente escrito]]. ; Conclusión En consecuencia, propongo adoptar esta convención como estándar en esWikilibros: * Las categorías destinadas a agrupar las páginas de un libro pasarán a usar el prefijo «Libro:». * Las categorías destinadas a catalogar libros por temática pasarán a usar el prefijo «Estante:». Las categorías existentes se irán trasladando progresivamente a esta estructura, corrigiendo los casos en los que actualmente ambos usos se solapan. Se trata de un pequeño cambio principalmente organizativo, que no modifica el contenido de los libros, pero sí hace que la estructura de categorías sea mucho más clara, coherente y fácil de mantener, y que además ya se usa en otras ediciones de Wikilibros. Voy a esperar unos días por si alguien quiere dejar algún comentario sobre este asunto, tras los cuales mi intención es comenzar a usar esta convención y dejarla documentada para que pueda aplicarse de forma consistente en el futuro. ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 08:18 15 jul 2026 (UTC) :Mientras trabajaba en este asunto, me he fijado también en que en Wikilibros tenemos dos «categorías raíz»: :# [[:Categoría:Categorías]] :# [[:Categoría:Principal]] :Ambas dicen ser «la categoría raíz de nuestro sistemas de categorías». Esta duplicidad es un error por motivos obvios. :Mi sugerencia es que nos quedemos sólo con [[:Categoría:Categorías]]. Por los siguientes motivos: :# «Categorías» es mucho mas claro que «Principal». ¿Qué significa principal? ¿Principal qué? «Categorías» deja bastante claro, que esa categoría alberga categorías. :# Por coherencia con otras wikis, ya que en esWikipedia la categoría raíz de otras categorías también se llama «Categorías». Y en enWikibooks se llama «Categories». :[[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 19:04 15 jul 2026 (UTC) :Buenas @[[Usuario:Mazbel|Mazbel]], me alegra mucho ver los cambios recientes que has realizado en línea con esta propuesta, y que incluso has categorizado algunos libros usando esta estructura de ''libros'' y ''estantes''. Por lo tanto ¿imagino que la propuesta te parece razonable? Me gustaría conocer tu opinión, gracias de antemano. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 07:03 16 jul 2026 (UTC) b9kyprp0pzeejcvyg1x3rhruczv0m2s Programación en PHP 0 583 427924 385159 2026-07-16T04:29:39Z Mazbel 57931 categorización 427924 wikitext text/x-wiki [[Image:PHPWikibookCover.png|right]] {{Versión imprimible|Programación en PHP/Texto Completo}} {{Versión en PDF}} '''PHP''' es un lenguaje de programación de uso general de código del lado del servidor. Originalmente fue diseñado para el desarrollo web de contenido dinámico. Está actualmente entre los proyectos de código abierto más populares (gracias en parte a la similitud de su sintaxis con el lenguaje C). El código es interpretado por un servidor web con un módulo procesador de PHP que genera la página Web resultante. Si alguna vez accediste a un sitio web que te diese la opción de iniciar sesión, probablemente ejecutara un lenguaje de script del lado servidor; seguramente estaría ejecutando PHP, debido a su gran impacto en el mercado, . Este lenguaje fue creado originalmente por Rasmus Lerdorf en 1995 y actualmente sigue siendo desarrollado con nuevas funciones por el grupo PHP. Básicamente, PHP permite a páginas estáticas convertirse en dinámicas (aunque es mucho más que eso). El nombre "PHP" es un acrónimo que significa "PHP: Hypertext Preprocessor", en español "PHP: Preprocesador de hipertexto". La palabra "hipertexto" significa que PHP realiza cambios antes de que el contenido (como la página HTML) sea creado. Esto permite a desarrolladores crear potentes aplicaciones que publiquen blogs, controlen hardware remotamente o ejecuten potentes sitios web como Wikipedia o Wikilibros. Por supuesto, estos sitios utilizan otras tecnologías en conjunto con PHP, por ejemplo un servidor de bases de datos como MySQL. Antes de embarcarte en el maravilloso viaje del procesamiento en el lado Servidor, es recomendable que tengas unas nociones básicas sobre HTML. PHP es usado también para crear aplicaciones gráficas; PHP-GTK se utiliza para crear interfaces gráficas de usuario (GUI). == Instalar PHP == La mayor aplicación de PHP es como lenguaje de script en servidores (implicado en generación de páginas web), aunque se puede utilizar perfectamente como cualquier otro lenguaje de programación para fines más generales. Si quieres utilizar PHP en tus páginas web, es necesario que poseas (o tengas acceso a) un servidor donde alojar esas páginas. Para esto, no es necesario que tengas una página web con su nombre registrado en Internet, porque puedes habilitar un servidor web en tu ordenador y servir ficheros localmente o través de una red. Una forma de hacerlo es con Apache Web Server, el software de servidor web más utilizado hoy en día. Para una explicación sobre cómo obtener, instalar y configurar este software, ver [[/Obtener Apache Web Server y PHP|Obtener Apache Web Server y PHP]]. Si todavía no quieres profundizar sobre qué es un servidor, cómo instalarlo, configurarlo y agregarle el módulo de PHP, puedes utilizar paquetes que sólo deben ser instalados como [http://www.easyphp.org EasyPHP] o el [http://www.wampserver.com/en/ WAMP], ambos, para el Sistema operativo Windows. También existe otro programa similar al EasyPHP se llama [http://www.appservnetwork.com/ Appserv] el cual instala todo a través de una sola instalación y además permite poner PHP-Nuke de serie. O puedes usar un paquete creado por los desarrolladores de Apache, llamado [http://www.apachefriends.org XAMPP] que posee versiones para GNU/Linux, Windows, Mac, Solaris. Recientemente ha aparecido una alternativa al servidor Apache, llamada [http://www.cherokee-project.com/ Cherokee] que también permite programar en PHP y cuya configuración es mucho más simple que la del servidor Apache, lo cual puede ser una gran ayuda para los recién llegados. == Probar PHP == Probar si PHP funciona es muy fácil. Simplemente, copia este texto en algún editor sencillo (nada de Word o editores así, que meten caracteres "ocultos", usa editores de texto puros como Notepad o gedit). Ahora, salva el documento con nombre "index.php" en tu directorio web. Borra el archivo "index.htm" de ese mismo directorio para que no haya confusiones y digita en el navegador <nowiki>http://localhost/</nowiki> o <nowiki>http://localhost/index.php</nowiki> <syntaxhighlight lang="php"><?php echo 'Hola mundo'; ?></syntaxhighlight> Deberías ver el texto "Hola mundo" en el navegador. Asegúrate de que no estás accediendo al fichero localmente (C:/Web/index.php) sino a través del servidor (<nowiki>http://localhost/index.php</nowiki>). Si accedes localmente al fichero, simplemente verás el contenido de ese fichero de texto. PHP tiene, además, la función phpinfo() que puedes utilizar para comprobar tu instalación y aprender algo sobre algunas de las características especiales disponibles. Para utilizarla, simplemente crea una nueva página (podría llamarse "phpinfo.php") y escribe en ella: <syntaxhighlight lang="php"><?php phpinfo(); ?></syntaxhighlight> Ahora, sitúa el fichero en tu directorio web y visualiza la página con el navegador (por ejemplo, <nowiki>http://localhost/phpinfo.php</nowiki>) == Aprender PHP == === PHP básico === # [[/Hola_mundo|Empezando con "Hola mundo"]] # [[/Bases_del_lenguaje|Bases del lenguaje]] # [[/Comentarios|Comentarios y estilo]] # [[/Variables|Variables]] # [[/Cadenas|Cadenas]] # [[/Operadores|Operadores]] # Estructuras de control ## [[/Estructura_if|La estructura if]] ## [[/Estructura_switch|La estructura switch]] ## [[/Bucle_while|El bucle while]] ## [[/Bucle_do_while|El bucle Do while]] ## [[/Bucle_for|El bucle for]] ## [[/Bucle_foreach|El bucle foreach]] ## [[/Include_y_require|Include y require]] ## [[/Otras_estructuras_de_control|Estructura Go To]] # [[/Funciones|Funciones]] # [[/Mail|Envío de correo electrónico]] # [[/Fecha_y_hora|Fecha y hora]] === PHP medio === # [[/Cookies|Cookies]] [[Archivo:00%.png]] # [[/Sesiones|Sesiones]] [[Archivo:00%.png]] # [[/Intermedio/Arrays|Arrays]] [[Archivo:25%.png]] # [[/Intermedio/Regexp|Expresiones regulares]] [[Archivo:00%.svg]] # [[/Intermedio/OOP|Programación orientada a objetos]] [[Archivo:00%.svg]] # [[/Funciones variadas|Funciones variadas MATH, DATE...]] [[Archivo:00%.svg]] # [[/Manejo de ficheros|Manejo de ficheros]] [[Archivo:00%.svg]] # [[/Mysql|Bases de datos MySQL]] [[Archivo:00%.svg]] === PHP avanzado === # [[/Avanzado/Introducción a SQLite|Introducción a SQLite]] [[Archivo:00%.svg]] # [[/Avanzado/Graficos GD|Generación de gráficos con librería GD]] [[Archivo:50%.png]] # [[/Avanzado/Graficos ezComponents|Visualización gráfica de datos (charts) con ezComponents]] [[Archivo:00%.svg]] # [[/Avanzado/Graficos GD|Generación de PDFs con librería UFPDF]] [[Archivo:00%.svg]] # [[/Avanzado/Smarty|Plantillas Smarty]] [[Archivo:00%.svg]] # [[/Avanzado/SimpleXML (PHP 5)|SimpleXML (PHP 5)]] [[Archivo:00%.svg]] # [[/Avanzado/Usando código Perl desde PHP|Usando código Perl desde PHP]] [[Archivo:00%.svg]] # [[/Avanzado/La extensión SOAP|La extensión SOAP]] [[Archivo:00%.svg]] # [[/Avanzado/Manejo de Sockets|Manejo de Sockets]] [[Archivo:00%.svg]] === Ejemplos Practicos PHP === # [[/Ejemplos/Calcular edad|Calcular Edad]] # [[/Traspaso de variable|Traspaso de variables usando GET]] # [[/Utilidades/Intercambio de variables|Intercambiar variables]] # [[/Avanzado/PHP, MySQL y la extension mysqli|PHP, '''MySQL''' y la extension mysqli]] # [[/Avanzado/XML en PHP 5|XML en PHP 5]] # [[/Ejemplos/redondear un número|Redondear un Numero]] == Enlaces externos == * [http://PHP.net/ PHP.net] - La página oficial de PHP. Aquí puedes [http://PHP.net/downloads.php conseguir el PHP] y leer su [http://PHP.net/docs.php documentación] * [http://sourceforge.net/projects/nusoap/ NuSOAP] - La página oficial de NuSOAP. NuSOAP son un conjunto de clases para implementar servicios web con PHP. {{Wikipedia|PHP}} {{Estantes|Lenguajes de programación}} iuv1a401uh3nn8mhkgxik0jpf8zjyg5 Programación en PHP/Hola mundo 0 639 427925 385155 2026-07-16T04:30:05Z Mazbel 57931 actualización 427925 wikitext text/x-wiki [[Programación en PHP | <nowiki> [Volver al índice general] </nowiki>]] <noinclude> {{navegar |libro=Programación en PHP |actual={{SUBPAGENAME}} |siguiente=Bases del lenguaje }} </noinclude> == Código == <syntaxhighlight lang="php"> <?php $cadena = 'Hola mundo'; echo $cadena; ?> </syntaxhighlight> == Análisis == Esto es un código muy sencillo. Simplemente guarda la cadena de caracteres o string <font color="#FF0000">'Hola mundo'</font> en la variable <font color="#0000FF">$cadena</font> y después se imprime por pantalla con el comando echo. == Nuevos conceptos == === Inicio de un script en PHP === El ' <'''?php''' ' inicial indica que lo que sigue debería ser interpretado por PHP (por el intérprete de PHP), lo que significa que es parte del programa y no del HTML. Al final del documento, o cuando pasamos de nuevo a código HTML, se pone un ' '''?'''>' para indicar a PHP que ignore lo que venga a continuación. La etiqueta de cierre del código en PHP lleva implícito un ' ''';''' '. === Variables === Las variables son la base de cualquier lenguaje de programación. Sin ellas, no podríamos guardar información para utilizarla más adelante. PHP no sería capaz de hacer nada dinámico. Vemos que las variables son necesarias y PHP las tiene. Si tienes experiencia con otros lenguajes de programación, sabes que en algunos de ellos es necesario declarar el tipo que va a tener una variable, es decir, el tipo de datos que será capaz de guardar. Son los lenguajes fuertemente tipados y en ellos necesitas saber el tipo de una variable antes de guardar cualquier cosa en ella. Son de este tipo lenguajes tan conocidos como [[Programación:C mas mas|C++]] y [[Programación:Java|Java]]. PHP, por otra parte, es un lenguaje débilmente tipado, porque el tipo de la variable corresponde al tipo del valor que está guardando ''en este momento''. Puedes crear una variable para guardar una cadena de caracteres (string), asignar a esa variable un string, reemplazarlo luego por un número, y no habría problemas. Sin embargo, en C++ habría que haber hecho un ''cast'' (conversión explícita de tipos) o guardar ese número en otra variable distinta (del tipo correcto). Todas las variables en PHP empiezan por '<font color="#0000FF">$</font>' seguido de un identificador. Se diferencia entre mayúsculas y minúsculas, por lo que <font color="#0000FF">$wiki</font> es diferente de <font color="#0000FF">$Wiki</font>. Para saber más sobre las variables, puedes mirar en el [http://www.php.net/manual/es/language.variables.php manual de PHP]. === Print === La función '''print''' es clave para la salida de datos. Manda cualquier cosa que pongamos entre las comillas (o paréntesis) que siguen a '''print''' a la salida (la ventana del navegador). Una función similar podría se como '''echo''', pero '''print''' permite al programador saber si la salida se ha realizado correctamente o no. Un ejemplo de uso del '''print''' con comillas sería: <syntaxhighlight lang="php"> print 'Hola, mundo'; </syntaxhighlight> Al texto entre comillas se le trata como si fuera un string, por lo que podemos hacer uso de la concatenación (unir dos strings en uno). Por ejemplo: <syntaxhighlight lang="php"> print 'Hola, mundo'; </syntaxhighlight> y <syntaxhighlight lang="php"> print 'Hola' . ', ' . 'mundo'; </syntaxhighlight> Los puntos entre medias de las cadenas de caracteres o strings son el operador de concatenación. Los ejemplos anteriores tendrían el mismo efecto pues, en la segunda versión, los 3 strings se unen en uno solo antes de salir por pantalla. La forma del comando '''print''' es una de las menos comunes. '''Print''' no es una función, sino una construcción interna. Las funciones, como veremos, tienen sus argumentos entre paréntesis. <syntaxhighlight lang="php"> miFuncion("Hola, mundo"); </syntaxhighlight> De todos modos, podemos usar '''print''' también con paréntesis, es decir: <syntaxhighlight lang="php"> print('Hola, mundo'); </syntaxhighlight> De cara a la optimización de código, cabe destacar, que se deben utilizar comillas simples (<font color="#FF0000"> ' </font>), siempre que no vayas a devolver variables, pues con el uso de la doble comilla (<font color="#FF0000"> " </font>), el compilador debe analizar todo el contenido en busca de variables. Es interesante hacer notar que '''echo''' se utiliza exactamente igual, por lo que si sustituimos en los ejemplos anteriores '''print''' por '''echo''' tendremos el mismo resultado. Para saber más sobre '''print''' pulsa [http://www.php.net/manual/es/function.print.php aquí]. Para '''echo''', [http://www.php.net/manual/es/function.echo.php aquí]. === El punto y coma y los espacios blancos === Otra parte imprescindible para este lenguaje, no así en otros como {{libro|Programación en JavaScript|JavaScript}} o [[Programación en ActionScript|ActionScript]], es finalizar cada comando con un punto y coma ("''';'''"). Sin él, el intérprete de PHP nos devolverá un error crítico y ni siquiera iniciará la ejecución del script. Sin embargo PHP ignora completamente los espacios en blanco y los saltos de línea (salvo en las definiciones de cadenas). Esto quiere decir que tanto podemos poner todo un script en una línea como sangrar cada línea tanto como queramos o dejar varias líneas en blanco. == Enlaces externos == * [http://www.juarbo.com/hola-mundo-en-php/ Hola Mundo en PHP] {{AutoCat}} 4eaxb0if9stx764k6y9y2482v6z98fh Física 0 2391 427975 423665 2026-07-16T06:17:10Z Mazbel 57931 427975 wikitext text/x-wiki {{+Portada/f |nombre = Física |título = Física |subtítulo = El libro más completo de física en la red |sección1 = Cinemática |sección5 = Astronomía |sección9 = Capítulos a reubicar |sección13 = |sección17 = |sección21 = |sección25 = |sección29 = |sección33 = |sección2 = Preliminares |sección6 = Magnetismo |sección10 = Electromagnetismo |sección14 = Electricidad y electrónica |sección18 = Fenómenos superficiales de los líquidos |sección22 = Mecánica de Fluídos |sección26 = Hidrostática |sección30 = Hidrodinámica |sección34 = |sección3 = Física moderna |sección7 = Física avanzada |sección11 = Calorimetría |sección15 = Estructura de la materia |sección19 = El estado gaseoso |sección23 = Vibraciones mecánicas |sección27 = |sección31 = |sección35 = |sección4 = Óptica |sección8 = Acústica |sección12 = Termodinámica |sección16 = Mecánica Newtoniana |sección20 = Dinámica |sección24 = |sección28 = |sección32 = |sección36 = |rutacarrusel= Física/Carrusel |titcarrusel = Sección del día }} {{Estantes|Física}} flbmt1caidupw9gvrxebccvtt36d9ga Programación en C++ 0 5324 427919 416168 2026-07-16T04:22:01Z Mazbel 57931 actualización 427919 wikitext text/x-wiki <div style="background-color:#BBDDFF; color:#0000FF; border:1px solid #0000FF; padding:8px; text-align:center; font-size: 150%">Bienvenidos al Wikilibro de Programación en C++</div> <div style="background-color:#99CCFF; padding: 15px; text-align:center">[[Archivo:logoc++.png]]</div> <div style="background-color:#eeeee0; border:1px solid #aaaaa0; padding:8px; margin-top:4px"> [[Archivo:System-users.svg|left|thumb‎]] Si tienes algún comentario, crítica, elogio o sugerencia acerca del material incluido en este wikilibro puede usar la página de discusión, para ello puede hacer clic sobre las pestañas de arriba en donde aparece la palabra discusión. Si lo prefieres, puede colaborar en la edición de este documento pues no necesita ningún permiso especial. Así, si encuentras errores ortográficos o te parece que alguna sección está mal redactada, siéntete libre de hacer responsablemente las correcciones necesarias.</div> == :Tabla de contenido: == # [[/Introducción|Introducción]] {{Desarrollo|25%|Diciembre de 2006}} #[[/Lo más básico|Capítulo 1: Lo más básico]] {{Desarrollo|50%|Diciembre de 2006}} #[[/Iteraciones y decisiones|Capítulo 2: Iteraciones y decisiones]] {{Desarrollo|100%|Diciembre de 2006}} #[[/Estructuras|Capítulo 3: Estructuras I]] {{Desarrollo|100%|Diciembre de 2007}} #[[/Funciones|Capítulo 4: Funciones]] {{Desarrollo|100%|Enero de 2007}} #[[/Streams|Capítulo 5: Streams ( entrada y salida de datos )]] {{Desarrollo|100%|Febrero de 2008}} #[[/Arrays y cadenas de texto|Capítulo 6: Arrays y cadenas de texto]] {{Desarrollo|100%|Febrero de 2008}} #[[/Desarrollo Orientado a Objetos|Capítulo 7: Desarrollo Orientado a Objetos]] {{Desarrollo|25%|Diciembre de 2006}} #[[/Objetos y Clases|Capítulo 8: Objetos y Clases]] {{Desarrollo|100%|Marzo de 2007}} #[[/Sobrecarga de Operadores|Capítulo 9: Sobrecargado de operadores]] {{Desarrollo|00%|Diciembre de 2006}} #[[/Herencia|Capítulo 10: Herencia]] {{Desarrollo|100%|Marzo de 2007}} #[[/Funciones virtuales|Capítulo 11: Funciones virtuales y Polimorfismo]] {{Desarrollo|100%|Marzo de 2007}} #[[/Punteros|Capítulo 12: Punteros]] {{Desarrollo|100%|Diciembre de 2006}} <!-- ##[[/Punteros#Sintaxis|Sintaxis]] ##[[/Punteros#Operadores|Operadores]] ##[[/Punteros#Punteros y matrices|Punteros y matrices]] ##[[/Punteros#Aritmética de Punteros|Aritmética de Punteros]] ##[[/Punteros#Matrices de punteros|Matrices de punteros]] ##[[/Punteros#Formas de pasar un valor por referencia|Formas de pasar un valor por referencia]] ##[[/Punteros#Punteros a funciones|Punteros a funciones]] ##[[/Punteros#Ordenamiento burbuja|Ordenamiento burbuja]] #[[/Programas de varios archivos|Capítulo 13: Programas de varios archivos]] {{Desarrollo|00%|Diciembre de 2006}} --> # [[/Estructuras II|Capítulo 13: Estructuras II]] {{Desarrollo|00%|Abril de 2008}} # [[/Plantillas|Capítulo 14: Plantillas]] {{Desarrollo|00%|Abril de 2008}} # [[/Excepciones|Capítulo 15: Excepciones]] {{Desarrollo|00%|Abril de 2008}} # [[/Biblioteca Estándar de Plantillas|Capítulo 16: Biblioteca Estándar de Plantillas (STL)]] {{Desarrollo|00%|Diciembre de 2006}} # [[/Analisis y Diseño orientado a Objetos|Capítulo 17: Analisis y Diseño orientado a Objetos]] {{Desarrollo|00%|Diciembre de 2006}} ## [[/Analisis y Diseño orientado a Objetos|Introducción al desarrollo de Software]] ## [[/Analisis y Diseño orientado a Objetos|Analisis del Problema]] ## [[/Analisis y Diseño orientado a Objetos|Diseño de la solución (software)]] ## [[/Analisis y Diseño orientado a Objetos|Representación del problema y la solución (notación)]] # [[/Problemas Resueltos|Capítulo 18: Problemas Resueltos]] == Enlaces externos == * [http://www.zator.com/Cpp/E_Ce.htm Tutorial de C++] * [http://c.conclase.net Tutoriales y descripciones de funciones] * [http://www.cplusplus.com Uno de los mejores sitios sobre C++] (en inglés) * [http://www.possibility.com/Cpp/CppCodingStandard.html Posible estándar de creación de código] (en inglés) == Bibliografía == * Cómo programar en C/C++, H.M. Deitel, P.J. Deitel, Ed. Prentice Hall * Aprenda C++, Jeese Liberty, David Howard, Ed. Anaya * Programming, Principles and Practice using C++, Bjarne Stroustrup, Ed. Addison Wesley, 2009, ISBN 0321543726 {{estantes|Programación}} jcdyyg8pqb4z0z0ev6hy7y25d4efdmd 427921 427919 2026-07-16T04:23:58Z Mazbel 57931 427921 wikitext text/x-wiki <div style="background-color:#BBDDFF; color:#0000FF; border:1px solid #0000FF; padding:8px; text-align:center; font-size: 150%">Bienvenidos al Wikilibro de Programación en C++</div> <div style="background-color:#99CCFF; padding: 15px; text-align:center">[[Archivo:logoc++.png]]</div> <div style="background-color:#eeeee0; border:1px solid #aaaaa0; padding:8px; margin-top:4px"> [[Archivo:System-users.svg|left|thumb‎]] Si tienes algún comentario, crítica, elogio o sugerencia acerca del material incluido en este wikilibro puede usar la página de discusión, para ello puede hacer clic sobre las pestañas de arriba en donde aparece la palabra discusión. Si lo prefieres, puede colaborar en la edición de este documento pues no necesita ningún permiso especial. Así, si encuentras errores ortográficos o te parece que alguna sección está mal redactada, siéntete libre de hacer responsablemente las correcciones necesarias.</div> == :Tabla de contenido: == # [[/Introducción|Introducción]] {{Desarrollo|25%|Diciembre de 2006}} #[[/Lo más básico|Capítulo 1: Lo más básico]] {{Desarrollo|50%|Diciembre de 2006}} #[[/Iteraciones y decisiones|Capítulo 2: Iteraciones y decisiones]] {{Desarrollo|100%|Diciembre de 2006}} #[[/Estructuras|Capítulo 3: Estructuras I]] {{Desarrollo|100%|Diciembre de 2007}} #[[/Funciones|Capítulo 4: Funciones]] {{Desarrollo|100%|Enero de 2007}} #[[/Streams|Capítulo 5: Streams ( entrada y salida de datos )]] {{Desarrollo|100%|Febrero de 2008}} #[[/Arrays y cadenas de texto|Capítulo 6: Arrays y cadenas de texto]] {{Desarrollo|100%|Febrero de 2008}} #[[/Desarrollo Orientado a Objetos|Capítulo 7: Desarrollo Orientado a Objetos]] {{Desarrollo|25%|Diciembre de 2006}} #[[/Objetos y Clases|Capítulo 8: Objetos y Clases]] {{Desarrollo|100%|Marzo de 2007}} #[[/Sobrecarga de Operadores|Capítulo 9: Sobrecargado de operadores]] {{Desarrollo|00%|Diciembre de 2006}} #[[/Herencia|Capítulo 10: Herencia]] {{Desarrollo|100%|Marzo de 2007}} #[[/Funciones virtuales|Capítulo 11: Funciones virtuales y Polimorfismo]] {{Desarrollo|100%|Marzo de 2007}} #[[/Punteros|Capítulo 12: Punteros]] {{Desarrollo|100%|Diciembre de 2006}} <!-- ##[[/Punteros#Sintaxis|Sintaxis]] ##[[/Punteros#Operadores|Operadores]] ##[[/Punteros#Punteros y matrices|Punteros y matrices]] ##[[/Punteros#Aritmética de Punteros|Aritmética de Punteros]] ##[[/Punteros#Matrices de punteros|Matrices de punteros]] ##[[/Punteros#Formas de pasar un valor por referencia|Formas de pasar un valor por referencia]] ##[[/Punteros#Punteros a funciones|Punteros a funciones]] ##[[/Punteros#Ordenamiento burbuja|Ordenamiento burbuja]] #[[/Programas de varios archivos|Capítulo 13: Programas de varios archivos]] {{Desarrollo|00%|Diciembre de 2006}} --> # [[/Estructuras II|Capítulo 13: Estructuras II]] {{Desarrollo|00%|Abril de 2008}} # [[/Plantillas|Capítulo 14: Plantillas]] {{Desarrollo|00%|Abril de 2008}} # [[/Excepciones|Capítulo 15: Excepciones]] {{Desarrollo|00%|Abril de 2008}} # [[/Biblioteca Estándar de Plantillas|Capítulo 16: Biblioteca Estándar de Plantillas (STL)]] {{Desarrollo|00%|Diciembre de 2006}} # [[/Analisis y Diseño orientado a Objetos|Capítulo 17: Analisis y Diseño orientado a Objetos]] {{Desarrollo|00%|Diciembre de 2006}} ## [[/Analisis y Diseño orientado a Objetos|Introducción al desarrollo de Software]] ## [[/Analisis y Diseño orientado a Objetos|Analisis del Problema]] ## [[/Analisis y Diseño orientado a Objetos|Diseño de la solución (software)]] ## [[/Analisis y Diseño orientado a Objetos|Representación del problema y la solución (notación)]] # [[/Problemas Resueltos|Capítulo 18: Problemas Resueltos]] == Enlaces externos == * [http://www.zator.com/Cpp/E_Ce.htm Tutorial de C++] * [http://c.conclase.net Tutoriales y descripciones de funciones] * [http://www.cplusplus.com Uno de los mejores sitios sobre C++] (en inglés) * [http://www.possibility.com/Cpp/CppCodingStandard.html Posible estándar de creación de código] (en inglés) == Bibliografía == * Cómo programar en C/C++, H.M. Deitel, P.J. Deitel, Ed. Prentice Hall * Aprenda C++, Jeese Liberty, David Howard, Ed. Anaya * Programming, Principles and Practice using C++, Bjarne Stroustrup, Ed. Addison Wesley, 2009, ISBN 0321543726 {{Estantes|Lenguajes de programación}} ixtc8ld10w4gw5ksfttwxcgm6fvkbnj Física/Unidades y medidas 0 5417 427957 415500 2026-07-16T05:56:51Z Mazbel 57931 categorización 427957 wikitext text/x-wiki == Cantidades dimensionales == Corresponden a ciertas '''magnitudes''' que <u>están asociadas a las '''dimensiones'''</u>. Se miden en '''unidades de longitud, área, tiempo, espacio''', etc. == Cantidades adimensionales == Corresponden a '''magnitudes''' que pueden ser expresadas <u>sin necesidad de una unidad de medida</u>, pueden ser cocientes entre cantidades dimensionales. Ejemplo de estas son los '''grados de un ángulo''' o también las '''[[w:Constante_(matemática)|constantes]]''', como la '''relación''' de la masa entre protón y electrón. ==Magnitud== Se llama '''magnitud''' a la propiedad de la física que es medida. Pueden ser clasificadas en dos clases: * '''magnitudes fundamentales''' y * '''magnitudes derivadas''' ===Magnitudes fundamentales=== Son <u>aquellas que se definen en función de otras magnitudes físicas</u> y que sirven de base para obtener las demás magnitudes utilizadas en la física. Son las que no derivan de otras, única es su especie, son el cimiento de la física, y no se pueden ni multiplicar o dividir entre otras. === Magnitudes derivadas=== Son las que <u>resultan de multiplicar o dividir entre si las magnitudes fundamentales</u>. == Medir == Medir es <u>comparar una magnitud con otra que se utiliza como patrón</u>. Este '''patrón''' es una magnitud de valor conocido y perfectamente definido que se usa como '''referencia''' para la medida. Así, cuando medimos una distancia, el <u>patrón sería la cinta métrica</u>, y la <u>medida sería el resultado de comparar la distancia que estamos midiendo, con la cinta métrica</u>. ==Sistemas de medidas== Un <u>sistema de medidas es un conjunto que consiste en unidades de medida</u>. Definen un conjunto básico de unidades de medida a partir del cual se derivan el resto. Existen varios sistemas de unidades: === Sistema Métrico Decimal === El primer sistema de unidades bien definido que hubo en el mundo fue el Sistema Métrico Decimal, implantado en 1795 como resultado de la ''Convención Mundial de Ciencia celebrada en París'', Francia; este sistema tiene una división '''decimal''' y sus unidades fundamentales son: el '''metro''', el '''kilogramo-peso''' y el '''litro'''. === Sistema MKS === Tiene su origen en 1902 de la mano del ingeniero italiano Giovani Giorgi siendo adoptado por la ''Comisión Electrotécnica Internacional en París'' en el año 1935. Este sistema también recibe el nombre de '''MKS''', cuyas iniciales corresponden al '''metro''', al '''kilogramo''' y al '''segundo''' como unidades de '''longitud''', '''masa''' y '''tiempo''' respectivamente. === Sistema Usual en Estados Unidos (EIA) === Se basa en el sistema inglés, y es muy familiar para todos en Estados Unidos. Usa el '''pie''' como unidad de longitud, la '''libra''' como unidad de peso o fuerza, y el '''segundo''' como unidad de tiempo. En la actualidad, el SUEU está siendo sustituido rápidamente por el sistema internacional, en la ciencia, la tecnología, y en algunos deportes. ===[[Física/Sistema Internacional de Unidades (SI)|Sistema Internacional de Unidades]]=== Debido a que en el mundo científico se buscaba un solo sistema de unidades que resultara práctico, claro y de acuerdo con los avances de la ciencia. En 1960 científicos y técnicos de todo el mundo se reunieron en Ginebra, Suiza, y acordaron adoptar el llamado '''Sistema Internacional de Unidades (SI)'''. Este sistema se basa en el llamado MKS. El Sistema Internacional tiene como magnitudes y unidades fundamentales las siguientes: para longitud el metro ('''m'''), para masa el kilogramo ('''kg'''), para tiempo el segundo ('''s'''), para temperatura al Kelvin ('''K'''), para intensidad de corriente eléctrica al ampere ('''A'''), para la intensidad luminosa la candela ('''cd''') y para cantidad de sustancia el '''mol''' ===Unidades=== Las unidades del Sistema Internacional de Unidades fueron fijadas en la XI Conferencia General de Pesas y Medidas de París (1960). {| class="wikitable" |- ! Magnitud !! Unidades !! Dimensión !! Simbolo !! Descripción |- | '''Longitud''' || Metro || L || m || Unidad de longitud, se definió originalmente como la diezmillonésima parte del cuadrante del meridiano terrestre. Más tarde se estableció un metro patrón de platino iridiado que se conserva en París. En la actualidad, el metro se define como la longitud igual a 1.650.763,73 longitudes de onda, en el vacío, de la radiación correspondiente a la transición entre los niveles 2p10 y 5d5, del átomo de criptón 86. Ahora se define al metro como la longitud de la trayectoria recorrida por la luz en el vacío durante un intervalo de tiempo de 1/299,792,458 de segundo. |- | '''Masa''' || Kilogramo || m || Kg || Unidad de masa, es la masa de un cilindro de platino iridiado establecido en la III Conferencia General de Pesas y Medidas de París. También se define al gramo (milésima parte del kilogramo) como la masa de un centímetro cúbico de agua destilada cuando tiene la mayor densidad, esto sucede a cuatro grados centígrados. |- | '''Tiempo''' || Segundo || t || s || Unidad de tiempo, originalmente, el segundo fue definido como 1/86400 del día solar medio. Se llama día solar verdadero el tiempo transcurrido entre dos pasos consecutivos del Sol por el meridiano de un lugar; pero como no todos los días son de igual duración en el transcurso de un año, se toma un día ficticio, llamado día solar medio, cuya duración es tal que, al cabo del año, la suma de todos estos días ficticios es la misma que la de los días reales. Actualmente se define como la duración de 9.192.631.770 períodos de la radiación correspondiente a la transición entre los dos niveles hiperfinos del estado fundamental del átomo de cesio 133. |- | '''Intensidad de corriente eléctrica''' || Amperio || A || A|| Es la intensidad de corriente eléctrica constante que, mantenida en dos conductores paralelos rectilíneos, de longitud infinita, de sección circular despreciable y colocados en el vació a uno contra otro a una distancia de un metro uno de otro, produce entre estos dos conductores una fuerza igual a 2x10<sup>-7</sup> newton por metro de longitud.<ref>[https://books.google.es/books?id=_h4DEAAAQBAJ&pg=PA446&dq=intensidad+de+corriente+el%C3%A9ctrica+constante+que,+mantenida+en+dos+conductores+paralelos&hl=es&newbks=1&newbks_redir=0&sa=X&ved=2ahUKEwiV_di8m9iFAxWrh_0HHUyMBSQQ6AF6BAgJEAI#v=onepage&q=intensidad%20de%20corriente%20el%C3%A9ctrica%20constante%20que%2C%20mantenida%20en%20dos%20conductores%20paralelos&f=false Cuestiones de física - Página 446]</ref> |- |'''Temperatura termodinámica''' || Kelvin || θ || K || Es la unidad de temperatura termodinámica, es la fracción 1/273,16 de la temperatura termodinámica del punto triple del agua. Este mismo nombre y símbolo son utilizados para expresar un intervalo de temperatura. |- || '''Cantidad de sustancia''' || mol || N || mol || Es la cantidad de sustancia de un sistema que contiene tantas entidades elementales como átomos hay en 0,012 kilogramo de carbono 12. |- || '''Intensidad luminosa''' || Candela || J || cd || Es la intensidad luminosa, en la dirección perpendicular de una superficie de 1/600000 metros cuadrados de un cuerpo negro a la temperatura de solidificación del platino, bajo la presión de 101.325 newton por metro cuadrado. |} ===Otras unidades=== ==== Newton (N) ==== Usado para medir la fuerza. Es una unidad derivada equivalente a la fuerza necesaria para acelerar un kilogramo de masa a un metro por segundo cada segundo, 1 kilogramo fuerza equivale a 9 newton ==== Joule ==== Un '''[[w:Joule|joule]]''' equivale a la '''cantidad de trabajo''' efectuado por una '''[[w:Fuerza|fuerza]]''' de '''1 [[w:Newton_(unidad)|Newton]]''' actuando a través de una '''distancia''' de 1 '''[[w:Metro|metro]]'''. En 1948 el joule fue adoptado por la Conferencia Internacional de Pesas y Medidas como '''unidad de energía'''. El '''joule''' también es igual a '''1 [[w:Vatio|vatio]]''' por '''[[w:Segundo|segundo]]''' ('''[[w:vatio|W]]·[[w:Segundo|s]]'''), por lo que eléctricamente es el '''[[w:Trabajo_(física)|trabajo]]''' realizado por una '''[[w:Diferencia_de_potencial|diferencia de potencial]]''' de '''1 [[w:Voltio|voltio]]''' y con una '''[[w:Intensidad_de_corriente|intensidad]]''' de '''1 [[w:Amperio|Amperio]]''' durante un tiempo de '''1 segundo'''. '''Formula despejada''' <math>T = Trabajo\ T = (F)(d) </math> <math>F = Fuerza \ F = T / d</math> <math>d = distancia\ d = T / F</math> {{Ecuación|<math>\mathrm{ 1\,J = 1\,N \cdot m = \left (kg \cdot \frac{m}{s^2} \right ) \cdot m = \frac{kg \cdot m^2}{s^2} }</math>||}}Donde <math>N</math> representa newtons; <math>m</math>, metros; <math>kg</math>: kilogramos; <math>s</math>: segundos. === Equivalencias: === *1 vatio-hora = 3.600 joules. *1 joule = 0,24 calorías (no confundir con kcal). *1 caloría termoquímica (calth) = 4,184 J *1 Tonelada equivalente de petróleo = 41.840.000.000 joules = 11.622 kilovatio hora. *1 Tonelada equivalente de carbón = 29.300.000.000 joules = 8.138,9 kilovatio hora. == Referencias == {{Listaref}} {{AutoCat}} frkhoijl323ajnkqef0e8stbpbipwjf Física/Definición de la Física 0 6285 427953 394809 2026-07-16T05:55:41Z Mazbel 57931 actualización 427953 wikitext text/x-wiki La '''Física''' es la ciencia dedicada al estudio de los fenómenos naturales. Estudia las propiedades del espacio, el tiempo, la materia y la energía, así como sus interacciones. La física es una de las más antiguas disciplinas académicas, tal vez la más antigua a través de la inclusión de la astronomía. En los últimos dos milenios, la física había sido considerada sinónimo de la filosofía, la química, y ciertas ramas de la matemática y la biología, pero durante la '''Revolución Científica''' en el siglo XVII surgió para convertirse en una ciencia moderna, única por derecho propio. Sin embargo, en algunas esferas como la física matemática y la química cuántica, los límites de la física siguen siendo difíciles de distinguir. Algunas ramas de la física son: óptica, acústica, mecánica de fluidos, física nuclear, biofísica, física-química, electromagnetismo, etc. {{AutoCat}} q1l5cthwjqapqbyvf2ztrrzm399r571 Física/División de la Física 0 6286 427955 414680 2026-07-16T05:56:17Z Mazbel 57931 actualización 427955 wikitext text/x-wiki La '''Física''' se divide para su estudio en dos grandes grupos: la '''''Física Clásica ''''' y la '''''Física Moderna'''''. La primera estudia todos aquellos fenómenos en los cuales la velocidad es muy pequeña comparada con la '''velocidad de propagación de la luz'''. La segunda se encarga de todos aquellos fenómenos producidos a la velocidad de la luz o con valores cercanos a ella. Esto es debido a que la ''física clásica'' no describe con precisión los fenómenos que se suceden a la velocidad de la luz. En la ''física moderna'' también se estudian los ''fenómenos subatómicos''. ====Física clásica==== A su vez se divide en 7 ramales ( y otras subdivisiones) que son: #[[Física/Mecánica Newtoniana|Mecánica Clásica (Newtoniana o Vectorial)]] ##[[Física/Estática|Estática]]: Estudia los cuerpos en equilibrio.</noinclude> ###Hidrostática ###Estática de los sólidos ##[[Física/Cinemática|Cinemática]]: Estudia el movimiento de los cuerpos sin considerar las causas que lo producen.</noinclude> ###Rotacional ###Translacional ###Vibracional ##[[Física/Dinámica|Dinámica]]: Estudia las causas que producen el movimiento de los cuerpos.</noinclude> ###[[Física/Hidrodinámica|Hidrodinámica]] ### Aerodinámica ###Dinámica de los sólidos ####[[Física/Vibraciones mecánicas|Vibraciones Mecánicas]] #Mecánica Analítica. ## Mecánica Lagrangiana ## Mecáncia Hamiltoniana # Mecánica de medios continuos ## Mecánica de fluídos ### [[Física/Hidrostática|Hidrostática]] ### Neumática #Termología ##[[Física/Termodinámica|Termodinámica]]: Estudia los fenómenos térmicos, como el calor, la temperatura y la energía. ##Termometría ##[[Física/Calorimetría|Calorimetría]] #[[Física/Electromagnetismo|Electromagnetismo]]<noinclude> ##Electroestática: estudia los fenómenos eléctricos en reposo. ##Electrodinámica: Estudia los fenómenos eléctricos en movimiento. ##[[Física/Magnetismo|Magnetismo]]<noinclude> ##[[Física/Óptica|Óptica]]<noinclude>: Estudia la luz y sus propiedades. ###Óptica geométrica ###Óptica física ###Óptica cuántica ###Espectroscopio #[[Física/Acústica|Acústica]]<noinclude>: Estudia el sonido y sus propiedades. ##Ondas mecánicas ##Sonido #Astronomía/ Astrofísica: Estudia los fenómenos físicos que ocurren en el universo. ====[[Física/Física moderna|Física Moderna]]====<noinclude> Se encuentran los siguientes campos: *Relatividad: Estudia los fenómenos físicos a velocidades cercanas a la velocidad de la luz. *Mecánica Cuántica: Estudia el comportamiento de la materia y la energía a escala atómica y subatómica. **Física Atómica **Física Nuclear: Estudia la estructura del núcleo atómico y las reacciones nucleares. **Física Química **Física del estado sólido *Física de partículas *Gravitación *Física del plasma {{AutoCat}} 0mkxffoff1cpjrtnne81gipy75dqof5 Física/Sistema Cegesimal o CGS 0 6289 427959 375121 2026-07-16T05:57:28Z Mazbel 57931 categorización 427959 wikitext text/x-wiki == Sistema Cegesimal o CGS == Es un sistema de unidades basado en el centímetro, el gramo y el segundo como unidades de longitud, masa y tiempo respectivamente. ===Historia=== En 1832, este sistema es propuesto por el matemático y científico alemán Karl Gauss.(en alemania) En 1873, un comité establecido por la British Association para el Avance de la Ciencia, recomendó el uso del sistema CGS en dinámica y en electricidad. En 1881, se adopto en el Congreso Internacional de los Electricistas realizado en París, Francia. {{AutoCat}} gpju2efhe85fi9qadn5aiw0dov8qmer Física/Sistema MKS 0 6290 427960 402938 2026-07-16T05:58:01Z Mazbel 57931 categorización 427960 wikitext text/x-wiki == Sistema MKS == En el año 1935 en el Congreso Internacional de los Electricistas celebrado en Bruselas, Belgica; el ingeniero italiano Giovanni Giorgi propone y logra que se acepte su sistema. Este sistema tambien recibe el nombre de MKS, cuyas iniciales corresponden al metro, al kilogramo y al segundo como unidades de longitud, masa y tiempo respectivamente. ===SISTEMA MKS (metro, kilogramo, segundo)=== El nombre del sistema está tomado de las iniciales de sus unidades fundamentales. La unidad de longitud del sistema M.K.S. es el metro: *METRO: Es una longitud igual a la del metro patrón que se conserva en la Oficina Internacional de pesas y medidas. La unidad de masa es el kilogramo: *KILOGRAMO: Es una masa igual a la del kilogramo patrón que se conserva en la Oficina Internacional de pesas y medidas. Un kilogramo (abreviado Kg.) es aproximadamente igual a la masa de un decímetro cúbico de agua destilada a 4º C. La unidad de tiempo de todos los sistemas de unidades es el segundo. *SEGUNDO: Se define como la 86,400 ava. Parte del día solar medio. Los días tienen diferente duración según las épocas del año y la distancia de la Tierra al Sol. El día solar medio es el promedio de duración de cada uno de los días del año. Unidad/Sistema http://genesis.uag.mx/edmedia/material/fisica/introduccion8.htm {{AutoCat}} 5mekggscjjlliy9ma1dd3cndoq6qyxk Física/Sistema Internacional de Unidades (SI) 0 6291 427958 415498 2026-07-16T05:57:10Z Mazbel 57931 categorización 427958 wikitext text/x-wiki El [[w:Sistema_Internacional_de_Unidades|'''Sistema Internacional de Unidades''']] (en francés ''Système international d'unités'') o Sistema Internacional (abreviado '''SI''') está constituido por '''siete unidades básicas o fundamentales''': '''metro''', '''kilogramo''', '''segundo''', '''kelvin''', '''ampere''' o '''amperio''', '''mol''' y '''candela''', que definen las magnitudes físicas fundamentales que han sido elegidas por '''convención''' desde la [[w:Convención_del_Metro|Convención del Metro]]. El Sistema Internacional tiene como antecedente el [[w:Sistema_métrico_decimal|'''sistema métrico decimal''']]. === Revisión de 2018 del SI === En la '''revisión de 2018 del SI''', se cambiaron las '''definiciones''' de cuatro de las unidades básicas del SI: el kilogramo, el ampere, el kelvin y el mol. '''''Sus nuevas definiciones''''' se basan '''''en valores numéricos fijos''''' de la '''constante de Planck''' ( ''h'' ), la '''carga elemental''' ( '''''e''''' ), la '''constante de Boltzmann''' ( '''''k''''' ) y la '''constante de Avogadro''' ( '''''N<sub>A</sub>''''' ), respectivamente. Con estas nuevas definiciones en términos de constantes universales se elimina la dependencia material y dado que ahora se definen en términos de '''fenómenos cuánticos''', pueden considerarse invariables. El SI revisado quedó definido como aquel en el que: * la [[w:Frecuencia|frecuencia]] de la [[w:Transición_hiperfina|transición hiperfina]] del [[w:Estado_fundamental|estado fundamental]] no perturbado del [[w:Átomo|átomo]] de [[w:_Anexo:Isótopos_de_cesio#Cesio_133|cesio 133]] (<math>\Delta\nu_{Cs}</math>) es igual a 9 192 631 770 [[w:Hercio|Hz]] * la [[w:Velocidad_de_la_luz|velocidad de la luz]] en el [[w:Vacío|vacío]] (<math>c</math>) es igual a 299 792 458 [[w:Metro|m]]/[[w:Segundo|s]] * la [[w:Constante_de_Planck|constante de Planck]] (<math>h</math>) es igual a 6.626 070 15 × 10<sup>-34</sup> [[w:Julio|J]]·s * la [[w:Carga_elemental|carga elemental]] (<math>e</math>) es igual a 1.602 176 634 × 10<sup>-19</sup> [[w:Culombio|C]] * la [[w:Constante_de_Boltzmann|constante de Boltzmann]] (<math>k</math>) es igual a 1.380 649 × 10<sup>-23</sup> J/[[w:Kelvin|K]] * la [[w:Constante_de_Avogadro|constante de Avogadro]] (<math>N_{\text{A}}</math>) es igual a 6.022 140 76 × 10<sup>23</sup> [[w:Mol|mol]]<sup>-1</sup> * la [[w:Eficacia_luminosa|eficacia luminosa]] de la [[w:Luz_monocromática|radiación monocromática]] de (<math>K_{\text{cd}}</math>) es 683 igual a [[w:Lumen|lm]]/[[w:Vatio|W]] '''El Sistema Internacional de Unidades (SI): Unidades base o fundamentales''' {| class="wikitable" | colspan="2" |'''Magnitud base''' | colspan="2" |'''Unidad''' |- |'''Nombre''' |'''Símbolo típico''' |'''Nombre''' |'''Símbolo''' |- |'''tiempo''' |'''''t''''' |'''''segundo''''' |'''s''' |- |'''longitud''' |'''''l'', ''x'', ''r'',''' etc. |'''''metro''''' |'''m''' |- |'''masa''' |'''''m''''' |'''''kilogramo''''' |'''kg''' |- |'''corriente eléctrica''' |'''''I'', ''i''''' |'''''ampere''''' |'''A''' |- |'''temperatura termodinámica''' |'''''T''''' |'''''kelvin''''' |'''K''' |- |'''Cantidad de sustancia''' |'''''n''''' |'''''mol''''' |'''mol''' |- |'''Intensidad luminosa''' |'''''I''<sub>v</sub>''' |'''''candela''''' |'''cd''' |} Todas las demás unidades del SI se pueden '''derivar''' de éstas, '''realizando operaciones entre ellas''' o por elevarse a algún exponente. '''Por ejemplo:''' la '''unidad de energía''' es el '''joule''', cuyo símbolo es '''J''', que es una unidad derivada de la combinación de '''kg''', '''m''', '''s'''. === Nuevas definiciones === ==== Datos interesantes ==== Las unidades del SI son la referencia internacional de las indicaciones de todos los '''instrumentos de medida''', y a las que están referidas a través de una cadena interrumpida de calibraciones o comparaciones. El Sistema Internacional de Unidades consta de '''siete unidades básica'''s, también denominadas unidades fundamentales, que definen a las correspondientes magnitudes físicas fundamentales, que han sido elegidas por convención, y que permiten expresar cualquier magnitud física en términos o como combinación de ellas. Las magnitudes físicas fundamentales se complementan con dos magnitudes físicas más, '''denominadas suplementarias'''. Este sistema se basa en el llamado '''MKS''' cuyas iniciales corresponden a '''metro''', '''kilogramo''' y '''segundo'''. El Sistema Internacional tiene como magnitudes y unidades fundamentales las siguientes: * para '''longitud''' al '''metro''' ('''m'''), * para '''masa''' al '''kilogramo''' ('''kg'''), * para '''tiempo''' el '''segundo''' ('''s'''), * para '''temperatura''' al '''kelvin''' ('''K'''), * para '''intensidad de corriente eléctrica''' al '''amperio''' ('''A'''), * para la '''intensidad luminosa''' la '''candela''' ('''cd''') y * para '''cantidad de sustancia''' el '''mol''' ('''mol'''). == Unidades fundamentales == === Metro === La '''unidad fundamental de longitud''' ('''m''') del sistema métrico se definió originalmente en términos de la distancia desde el polo Norte hasta el Ecuador. En esa época se creía que esta distancia era de '''10&nbsp;000 kilómetros'''. Se determinó con cuidado la '''diezmillonésima parte de esa distancia''' y se marcó haciendo rayas a una '''barra de aleación de platino-iridio'''. Esta barra se guarda en la Oficina Internacional de Pesas y Medidas, en Francia. Desde entonces, se ha calibrado el metro patrón de Francia en términos de '''longitud de onda de luz'''; '''''es 1&nbsp;650&nbsp;763.73 veces la longitud de onda de la luz anaranjada emitida por los átomos de kriptón 86 gaseoso'''''. Ahora se define al metro como ''la longitud de la trayectoria recorrida por la luz en el vacío durante un intervalo de tiempo de 1/299&nbsp;792&nbsp;458 de segundo''. === Kilogramo === El '''kilogramo''' ('''kg''') es la '''unidad básica de masa''' y su patrón es un '''cilindro de platino''', que también se conserva en la Oficina Internacional de Pesas y Medidas, en Francia. El kilogramo equivale a '''1000 gramos'''. Un gramo es la masa de '''1 centímetro cubico''' ('''cm³''') de agua a una temperatura de '''4° Celsius'''. Desde 2019 se define al fijar '''el valor numérico de la '''constante de Planck''', '''h''', en 6.626 070 15 × 10−34, cuando se expresa en la unidad J·s, igual a kg·m²·s−1, según las definiciones del metro y el segundo''' . [h=6.626 070 15·10-34 kg·m²/s] *La '''libra patrón''' en función del kilogramo patrón: la masa de un objeto que pesa 1 libra equivale a '''0.4536 kilogramos''' (kg) === Segundo === La unidad oficial de '''tiempo''' ('''s'''), para el SI y para el SUEU es el '''segundo'''. Hasta 1956 se definía en términos del día solar medio, dividido en 24 horas. Cada hora se divide en 60 minutos, y cada minuto en 60 '''segundos'''. Así, hay 86&nbsp;400 '''segundos''' por día y el '''segundo''' se definía como la 1/86&nbsp;400 parte del día solar medio. Esto resultó poco satisfactorio, porque la rapidez de rotación de la tierra está disminuyendo de forma gradual. En 1956 se escogió al día solar medio del año 1900 como patrón para basar el segundo. En 1964 se definió al segundo, en forma oficial, como ''la duración de 9&nbsp;192&nbsp;631&nbsp;770 períodos de la radiación correspondiente a la transición entre los dos niveles hiperfinos del ''' estado fundamental del '''átomo''''''''. === Amperio === Un '''amperio''' es la '''unidad de la intensidad de corriente''' ('''I''') . ''Equivale a la '''carga''' en '''coulomb''' por '''segundo'''''. :<math>1 A = \frac {C}{s}</math> === Kelvin === La '''unidad fundamental de temperatura''' ('''T''') lleva su nombre en honor al cientifico '''[[w:William_Thomson|William Thomson]], Lord Kelvin.''' Se define al '''kelvin''' como ''la 1/273 parte de la '''temperatura''' termodinámica del punto triple del agua'' (que es el punto fijo en el que coexisten el hielo, el agua líquida y el vapor de agua en equilibrio). Se adoptó esta definición en 1968, al decidir cambiar el nombre grado '''kelvin''' ('''°K''') por sólo kelvin ('''K'''). === Mol === Es ''la '''cantidad de sustancia''' ('''N''') de un sistema que contiene 6.022 140 76 × 10<sup>23</sup> entidades elementales especificadas''. * 1 mol = 6.022 140 76 × 10<sup>23</sup> unidades elementales === Candela === Es la '''intensidad luminosa''' ('''Iv'''), en una dirección dada, de una fuente que emite '''radiación monocromática''' de frecuencia 540 × 10<sup>12</sup> Hz y tiene una intensidad radiante en esa dirección de 1/683 W/[[w:estereoradián|sr]]. Su unidad es la candela '''cd''' == Unidades suplementarias == Además de las unidades básicas hay dos unidades suplementarias. {|class="wikitable" border= |- !Unidad<br />(símbolo) !Magnitud física !Expresión en unidades SI básicas !Definición |- ![[w:radián|radián]]<br />(rad) |[[w:ángulo plano|ángulo plano]] |m/m=1 |Es el ángulo plano comprendido entre dos [[w:Radio (geometría)|radio]]s de un [[w:círculo|círculo]] que, sobre la [[w:circunferencia|circunferencia]] de dicho círculo, interceptan un [[w:Arco (geometría)|arco]] de longitud igual a la del radio. |- ![[w:estereorradián|erstereorradián]]<br />(sr) |[[w:ángulo sólido|ángulo sólido]] |m²/m²=1 |Es el ángulo sólido que, teniendo su [[w:Vértice (geometría)|vértice]] en el [[w:Centro (geometría)|centro]] de una [[w:esfera|esfer]], intercepta sobre la superficie de dicha esfera un [[w:área|área]] igual a la de un [[w:cuadrado|cuadrado]] que tenga por [[w:Lado (geometría)|lado]] el [[w:Radio (geometría)|radio]] de la esfera. |} == Unidades derivadas == 22 unidades derivadas tienen nombres especiales. Para representarlas se pueden usar estos nombres o una expresión algebraica en términos de otras unidades. {| class="wikitable" style="margin: auto auto;" |+ Lista completa de las unidades derivadas coherentes del SI con nombre especial<ref group="nota">Los prefijos del SI se pueden usar con cualquiera de los nombres y símbolos de las unidades derivadas coherentes con nombre especial, pero cuando se hace esto, la unidad resultante ya no será coherente.</ref> ! rowspan="2" | Cantidad física !! colspan="5" | Unidad derivada coherente |- ! Nombre !! Símbolo !! Expresada en<br />otras unidades !! Expresada en<br />unidades básicas !! Persona a quien<br />hace referencia |- ! colspan="6" | ''Unidades de geometría, mecánica y tiempo'' |- | frecuencia || [[w:Hercio|hercio]] || Hz || — || s<sup>−1</sup> || [[w:Heinrich_Rudolf_Hertz|Heinrich Rudolf Hertz]] |- | fuerza || [[w:Newton_(unidad)|newton]] || N || — || m kg s<sup>−2</sup> || [[w:Isaac_Newton|Isaac Newton]] |- | presión || [[w:Pascal_(unidad)|pascal]] || Pa || N/m² || m<sup>−1</sup> kg s<sup>−2</sup> || [[w:Blaise_Pascal|Blaise Pascal]] |- | energía (incluyendo calor) || [[w:Julio_(unidad)|julio]] || J || N m || m² kg s<sup>−2</sup> || [[w:James_Prescott_Joule|James Prescott Joule]] |- | potencia y flujo radiante || [[w:Vatio|vatio]] || W || J/s || m² kg s<sup>−3</sup> || [[w:James_Watt|James Watt]] |- ! colspan="6" | ''Unidades electromagnéticas'' |- | carga eléctrica || [[w:Culombio|culombio]] || C || — || s<math>\cdot</math>A || [[w:Charles-Augustin_de_Coulomb|Charles-Augustin de Coulomb]] |- | tensión eléctrica y<br />diferencia de potencial || [[w:Voltio|voltio]] || V || W/A || m² kg s<sup>−3</sup> A<sup>−1</sup> || [[w:Alessandro_Volta|Alessandro Volta]] |- | capacitancia || [[w:Faradio|faradio]] || F || C/V || m<sup>−2</sup> kg<sup>−1</sup> s<sup>4</sup> A<sup>2</sup> || [[w:Michael_Faraday|Michael Faraday]] |- | resistencia eléctrica || [[w:Ohmio|ohmio]] || Ω || V/A || m² kg s<sup>−3</sup> A<sup>−2</sup> || [[w:Georg_Simon_Ohm|Georg Simon Ohm]] |- | conductancia eléctrica || [[w:Siemens_(unidad)|siemens]] || S || A/V || m<sup>−2</sup> kg<sup>−1</sup> s³ A<sup>2</sup> || [[w:Werner_von_Siemens|Werner von Siemens]] |- | flujo magnético || [[w:Weber_(unidad)|weber]] || Wb || V s || m² kg s<sup>−2</sup> A<sup>−1</sup> || [[w:Wilhelm_Eduard_Weber|Wilhelm Eduard Weber]] |- | campo magnético/<small>(densidad de flujo magnético)</small> || [[w:Tesla_(unidad)|tesla]] || T || Wb/m² || kg s<sup>−2</sup> A<sup>−1</sup> || [[w:Nikola_Tesla|Nikola Tesla]] |- | inductancia || [[w:Henrio|henrio]] || H || Wb/A || m² kg s<sup>−2</sup> A<sup>−2</sup> || [[w:Joseph_Henry|Joseph Henry]] |- ! colspan="6" | ''Unidades de termodinámica y química'' |- | temperatura Celsius || [[w:Grado_Celsius|grado Celsius]] || °C || — || K<ref group="nota">El grado Celsius es el nombre especial del [[w:kelvin|kelevin]] que se usa para expresar las temperaturas Celsius. El grado Celsius y el Kelvin son iguales en tamaño, por lo que el valor numérico de una diferencia de temperatura o intervalo de temperatura es el mismo cuando se expresa en grados Celsius o en Kelvin.</ref>|| [[w:Anders_Celsius|Anders Celsius]] |- | actividad catalítica || [[w:Katal|katal]] || kat || — || s<sup>−1</sup> mol || — |- ! colspan="6" | ''Unidades radiológicas'' |- | actividad de un [[w:Radionucleido|radionucleido]]<ref group="nota">La actividad referida a un [[w:Radionucleido|radionucleido]] a veces se denomina incorrectamente [[w:radiactividad|radiactividad]].</ref>|| [[w:Bequerelio|bequerelio]] || Bq || — || s<sup>−1</sup> || [[w:Henri_Becquerel|Henri Becquerel]] |- | dosis absorbida || [[w:Gray_(unidad)|gray]] || Gy || J/kg || m² s<sup>−2</sup> || [[w:Louis_Harold_Gray|Louis Harold Gray]] |- | dosis equivalente || [[w:Sievert|sievert]] || Sv || J/kg || m² s<sup>−2</sup> || [[w:Rolf_Sievert|Rolf Sievert]] |- ! colspan="6" | ''Unidades de fotometría'' |- | flujo luminoso || [[w:Lumen|lumen]] || lm || cd sr || cd 4π<ref group="nota">Los estereorradianes existentes en una esfera equivalen a 4π.</ref> || — |- | iluminancia || [[w:Lux|lux]] || lx || lm/m² || m<sup>−2</sup> cd 4π || — |} == Unidades que no pertenecen al SI pero se aceptan para su uso dentro de este == El '''BIPM''' (''Bureau International des Poids et Mesures'') declara que las siguientes unidades, que no pertenecen al SI, se permiten para su uso con el SI. {| class="wikitable" style="margin: auto;" ! rowspan="2" | Magnitud !! colspan="3" | Unidad |- ! Nombre !! Símbolo !! Valor expresado en<br />unidades del SI |- | masa || [[w:Tonelada|tonelada]]|| t || 1 t = 1 Mg = 1000 kg |- | volumen || [[w:Litro|litro]]|| L, l || 1 L = 1 dm³ = 0.001 m³ |- | rowspan="2" | superficie || [[w:Área_(unidad_de_superficie)|área]]|| a || 1 a = 1 dm² = 100 m² |- | [[w:Hectárea|hectárea]]|| ha || 1 ha = 100 a = 10 000 m² |- | rowspan="3" | ángulo plano<ref group="nota">ISO 31 recomienda que el [[w:grado sexagesimal|grado sexagesimal]] se divida en decimales en lugar de usar el minuto y el segundo. Para la navegación y la topografía, sin embargo, el minuto tiene la ventaja de que un minuto de latitud en la superficie de la Tierra corresponde (aproximadamente) a una [[w:milla náutica|milla náutica]].</ref>|| [[w:Grado_sexagesimal|grado sexagesimal]]|| ° || 1° = (π/180) rad |- | [[w:Minuto_de_arco|minuto de arco]]|| ′ || 1′ = (1/60)° = (π/10800) rad |- | [[w:Segundo_sexagesimal|segundo de arco]]|| ″ || 1′′ = (1/60)′ = (π/648 000) rad |- | rowspan="3" | tiempo || [[w:Minuto|minuto]]|| min || 1 min = 60 s |- | [[w:Hora|hora]]|| h || 1 h = 60 min = 3600 s |- | [[w:Día|día]]|| d || 1 d = 24 h = 86 400 s |} == Prefijos del Sistema Internacional == {| class="wikitable sortable" ! 10<sup>n</sup> ! Prefijo ! Símbolo ! [[w:Escalas_numéricas_larga_y_corta|Escala</br>corta]] <ref group="nota-escala">Escala corta usada especialmente en países anglosajones, Puerto Rico, Brasil, Rusia y países arabes.</ref> ! [[w:Escalas_numéricas_larga_y_corta|Escala</br>larga]] <ref group="nota-escala">Escala larga usada especialmente en Europa continental, excepto Rusia, y en Centro y Sudamérica, excepto Puerto Rico y Brasil.</ref> ! Equivalencia [[w:Sistema_de_numeración_decimal|decimal]] en los [[w:Prefijos_del_Sistema_Internacional|prefijos del Sistema Internacional]] ! Asignación |- | 10<sup>30</sup> | [[w:Quetta_(prefijo)|quetta]]- | Q |align="center"| [[w:Nonillón|Nonillón]] |align="center"| Quintillón | 1 000 000 000 000 000 000 000 000 000 000 | 2022 |- | 10<sup>27</sup> | [[w:Ronna|ronna]]- | R |align="center"| [[w:Octillón|Octillón]] |align="center"| Mil cuatrillones | 1 000 000 000 000 000 000 000 000 000 | 2022 |- | 10<sup>24</sup> | [[w:Yotta|yotta]]- | Y |align="center"| [[w:Septillón|Septillón]] |align="center"| [[w:Cuatrillón|Cuatrillón]] | 1 000 000 000 000 000 000 000 000 | 1991 |- | 10<sup>21</sup> | [[w:Zetta|zetta]]- | Z |align="center"| [[w:Sextillón|Sextillón]] |align="center"| Mil trillones | 1 000 000 000 000 000 000 000 | 1991 |- | 10<sup>18</sup> | [[w:Exa|exa]]- | E |align="center"| [[w:Quintillón|Quintillón]] |align="center"| [[w:Trillón|Trillón]] | 1 000 000 000 000 000 000 | 1975 |- | 10<sup>15</sup> | [[w:Peta_(prefijo)|peta]]- | P |align="center"| [[w:Cuatrillón|Cuatrillón]] |align="center"| Mil billones | 1 000 000 000 000 000 | 1975 |- | 10<sup>12</sup> | [[w:Tera_(prefijo)|tera]]- | T |align="center"| [[w:Trillón|Trillón]] |align="center"| [[w:Billón|Billón]] | 1 000 000 000 000 | 1960 |- | 10<sup>9</sup> | [[w:Giga|giga]]- | G | align="center"|[[w:Billón|Billón]] | align="center"|[[w:Millardo|Mil millones / Millardo]] | 1 000 000 000 | 1960 |- | 10<sup>6</sup> | [[w:Mega_(prefijo)|mega]]- | M |colspan="2" align="center"| [[w:Millón|Millón]] | 1 000 000 | 1960 |- | 10<sup>3</sup> | [[w:Kilo_(prefijo)|kilo-]] <ref group="nota-escala"> Aunque también se admite el prefijo quilo-, esta forma está en desuso y se prefiere el prefijo kilo-. En cualquier caso, el símbolo del prefijo es siempre k y no q.</ref> | k |colspan="2" align="center"| [[w:Mil|Mil / millar]] | 1 000 | 1795 |- | 10<sup>2</sup> | [[w:Hecto|hecto]]- | h |colspan="2" align="center"| [[w:Cien|Cien / centena]] | 100 | 1795 |- | 10<sup>1</sup> | [[w:Deca|deca]]- | da |colspan="2" align="center"| [[w:Diez|Diez / decena]] | 10 | 1795 |- | 10<sup>0</sup> |colspan="2" align="center"| ''<span style="color:gray;">Sin prefijo</span>'' |colspan="2" align="center"| [[w:Uno|Uno / unidad]] | 1 | |- | 10<sup>−1</sup> | [[w:Deci|deci]]- | d |colspan="2" align="center"| [[w:Décimo_(matemática)|Décimo]] | 0.1 | 1795 |- | 10<sup>−2</sup> | [[w:Centi|centi]]- | c |colspan="2" align="center"| [[w:Centésimo|Centésimo]] | 0.01 | 1795 |- | 10<sup>−3</sup> | [[w:Mili|mili]]- | m |colspan="2" align="center"| [[w:Milésimo|Milésimo]] | 0.001 | 1795 |- | 10<sup>−6</sup> | [[w:Micro_(prefijo)|micro]]- | µ |colspan="2" align="center"| [[w:Millonésimo|Millonésimo]] | 0.000 001 | 1960 |- | 10<sup>−9</sup> | [[w:Nano_(prefijo)|nano]]- | n |align="center"| Billonésimo |align="center"| Milmillonésimo | 0.000 000 001 | 1960 |- | 10<sup>−12</sup> | [[w:Pico_(prefijo)|pico]]- | p |align="center"| Trillonésimo |align="center"| Billonésimo | 0.000 000 000 001 | 1960 |- | 10<sup>−15</sup> | [[w:Femto|femto]]- | f |align="center"| Cuatrillonésimo |align="center"| Milbillonésimo | 0.000 000 000 000 001 | 1964 |- | 10<sup>−18</sup> | [[w:Atto|atto]]- | a |align="center"| Quintillonésimo |align="center"| Trillonésimo | 0.000 000 000 000 000 001 | 1964 |- | 10<sup>−21</sup> | [[w:Zepto|zepto]]- | z |align="center"| Sextillonésimo |align="center"| Miltrillonésimo | 0.000 000 000 000 000 000 001 | 1991 |- | 10<sup>−24</sup> | [[w:Yocto|yocto]]- | y |align="center"| Septillonésimo |align="center"| Cuatrillonésimo | 0.000 000 000 000 000 000 000 001 | 1991 |- | 10<sup>−27</sup> | [[w:Ronto_(prefijo)|ronto]]- | r |align="center"| Octillonésimo |align="center"| Milcuatrillonésimo | 0.000 000 000 000 000 000 000 000 001 | 2022 |- | 10<sup>−30</sup> | [[w:Quecto|quecto]]- | q |align="center"| Nonillonésimo |align="center"| Quintillonésimo | 0.000 000 000 000 000 000 000 000 000 001 | 2022 |} === Notas de la escala === <small><references group="nota-escala" /></small> ==Notas generales== <small><references group="nota"/></small> {{AutoCat}} 9qvyhnr1mua3m0hso4l9mqikngmqmyk Física/Sistema Usual en Estados Unidos 0 6331 427962 403012 2026-07-16T05:58:26Z Mazbel 57931 categorización 427962 wikitext text/x-wiki == Sistema Usual en Estados Unidos (SUEU) == Se basa en el sistema inglés, y es muy familiar para todos en Estados Unidos. Usa el pie como unidad de longitud, la libra como unidad de peso o fuerza, y el segundo como unidad de tiempo. En la actualidad, el SUEU está siendo sustituido rápidamente por el sistema internacional, en la ciencia y la tecnología y en algunos deportes. {{AutoCat}} kco4udgfeusj2jg4mv8m16omp86b9mn Crear un MUD 0 6709 427860 355556 2026-07-15T17:58:13Z Antimundo 74354 Categorizar 427860 wikitext text/x-wiki == Introducción == === Palabra de autor === Este proyecto trata sobre la programación de un [[:m:w:es:Mud|MUD]], '''''M'''ulti '''U'''ser '''D'''ungeon'' (Mazmorras Multi Usuario) que, en pocas palabras, es un juego. Pero no es cualquier clase de juego, de esos en los que te mueves con el ratón o el teclado usando las flechas; tampoco es uno donde verás gráficos que te dejen boquiabierto, ni mucho menos verás algún gráfico. Ahí es donde se entiende que es, un juego de solo texto. Así es, aquí no verás monitos por la pantalla ni paisajes, sólo letras. Entonces, ¿cómo funciona?, fácil, mediante descripciones. Es un heredero directo de un antiguo género de videojuegos llamado: ''Juegos Conversacionales'' desde el cual fueron evolucionando juegos más complejos como las ''Aventuras Gráficas''. Su nombre convencional en el norte de España (Galicia, Asturias, etc.) es Mansiones o Mansións. === Más sobre los MUD === "Imagina que viajas a un país lejano y a una bonita ciudad, pero tu amigo o amiga del alma no ha podido ir contigo. Debes escribirle una carta con urgencia para contarle que estás hospedado en un hotel de tres pisos. El hotel está situado en una pequeña plaza rodeada de jardines junto a la biblioteca pública, que resulta ser un edificio antiguo con amplios ventanales. Al final de la calle principal, hacia el norte, hay una zona de bares por donde pasea la gente y donde se oyen continuamente risas y alboroto. A la izquierda del hotel, hacia el oeste, está la calle de las tiendas, aunque no recuerdes muy bien ahora cómo se llama. En esa calle hay una panadería donde hacen un pan delicioso. Un poco al oeste de la panadería está la tienda de artesanías más importante de la ciudad; hay unos recuerdos realmente preciosos y unas camisetas que te encantaría llevarle a tu amigo cuando volvieses. Justo detrás del hotel, hacia el sur, crees haber visto una pequeña caleta con barcas y barquitos de paseo. A la derecha del hotel, hacia el este, se extiende un larga avenida, que te han dicho llega hasta el antiquísimo castillo que da nombre a la ciudad (tienes que ir a visitarlo)." Estas son algunas palabras que utilizó el autor de [http://www.balzhur.org/ Balzhur], uno de los mejores MUDs en español (o castellano). === Empezando === Tal vez todavía no me creas acerca de esto, si es así, abre tu MS-Dos o tu cmd (simbolo de sistema) en los SOs Windows. Ahora escribe esto: telnet balzhur.genesismuds.com 5400 Otro mud famoso (en Inglés) : Telnet sverige.freeshell.org 4000 Con esto te conectarás al [[:m:w:es:servidor|servidor]] de balzhur para que puedas empezar tu aventura, sólo tienes que seguir los pasos. Como te podrás imaginar, un MUD no sólo es un juego normal, es un juego multijugador (como un MMORPG, pero no lo es) con el que podrás jugar junto a otras personas. Una vez que hayas probado el juego, tal vez puede que te quedes con las ganas de agregarle áreas, cuartos, objetos, hechizos, o cientos de cosas más. Éste es el propósito de este manual, para que puedas saciar tu sed de MUDs y te conviertas en el dios de tu propio juego. Si ya no puedes resistir, continúa a la siguiente página. == Contenido == '''''Índice''''' *[[Crear un MUD/Obteniendo lo necesario|Obteniendo lo necesario]][[imagen:100%.svg]] **[[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]][[imagen:100%.svg]] *[[Crear un MUD/Iniciando la creacion|Iniciando la creacion]][[imagen:75%.png]] **[[Crear un MUD/Iniciando tu MUD I|Iniciando tu MUD I]][[imagen:75%.png]] **[[Crear un MUD/Diccionario|Diccionario MUD]][[imagen:00%.svg]] {{Estantes|Desarrollo de videojuegos}} [[Categoría:Creación de videojuegos]] i05uyvxvrvwj9rr0u0lwvudzpu5cs8s Crear un MUD/Obteniendo lo necesario 0 6710 427873 195288 2026-07-15T18:34:31Z Antimundo 74354 Usar autocategoría 427873 wikitext text/x-wiki ''siguiente pagina: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''<br /> '' pagina anterior: [[Crear un MUD]]''</small> == Empezando == Para empezar, dejaré algo en claro. Yo no se ningun tipo de lengiaje, ni C, ni C++, ni nada, pero entonces ¿Como programaremos nuestro MUD sin lengiaje?. Bueno, la verdad es que no necesitas saberlo, ya que es muy facil. Balzhur, el mud antes mencionado, esta realizado bajo un programa muy interesante, llamado SMAUG (Simulated Mediaval Adventure multi-User Game, o juego de simulacion de aventuras multijugador medieval, o algo asi). Este programa es de codigo libre, y lo puedes descarga desde este link [ftp://ftp.game.org/pub/mud/diku/merc/smaug/smaug1_4a_W32bin.zip SMAUG]. Esta version es la 4a, y es la mas reciente actualización. Algunos bugs han sido actializado y han agregado otras cosas, si quieres ver la web del autor(es) clikea [http://www.smaug.org aqui] Esto es todo lo necesario, pero si quieres que sea mucho mas facil puedes bajarte otro programa, pero veremos eso mas tarde. Mientras tanto continua hacia la siguiente pagina. ''siguiente pagina: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''<br /> '' pagina anterior: [[Crear un MUD]]''</small> {{AutoCategoríaLibro}} 15ifjh91mywnrzs25rpsq4mvfd978th 427896 427873 2026-07-16T03:53:04Z Mazbel 57931 Corrigiendo 427896 wikitext text/x-wiki ''siguiente pagina: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''<br /> '' pagina anterior: [[Crear un MUD]]''</small> == Empezando == Para empezar, dejaré algo en claro. Yo no se ningun tipo de lengiaje, ni C, ni C++, ni nada, pero entonces ¿Como programaremos nuestro MUD sin lengiaje?. Bueno, la verdad es que no necesitas saberlo, ya que es muy facil. Balzhur, el mud antes mencionado, esta realizado bajo un programa muy interesante, llamado SMAUG (Simulated Mediaval Adventure multi-User Game, o juego de simulacion de aventuras multijugador medieval, o algo asi). Este programa es de codigo libre, y lo puedes descarga desde este link [ftp://ftp.game.org/pub/mud/diku/merc/smaug/smaug1_4a_W32bin.zip SMAUG]. Esta version es la 4a, y es la mas reciente actualización. Algunos bugs han sido actializado y han agregado otras cosas, si quieres ver la web del autor(es) clikea [http://www.smaug.org aqui] Esto es todo lo necesario, pero si quieres que sea mucho mas facil puedes bajarte otro programa, pero veremos eso mas tarde. Mientras tanto continua hacia la siguiente pagina. ''siguiente pagina: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''<br /> '' pagina anterior: [[Crear un MUD]]''</small> {{AutoCat}} i0qwe97cvo2iuw6nar3srdgbl24xsip Crear un MUD/Comprendiendo lo obtenido 0 6711 427874 168305 2026-07-15T18:34:53Z Antimundo 74354 Usar autocategoría 427874 wikitext text/x-wiki ''Siguinete Pagina: [[Crear un MUD/Iniciando la creacion|Iniciando la creacion]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Obteniendo lo necesario|Obteniendo lo necesario]]''</small> ==Reconociendo todo== Ok, ya obtuviste lo necesario, ahora debes comprender lo obtenido. Para empezar abre la carpeta donde grabaste SMAUG, porque haremos un truquito para que seas el amo y señor de tu juego. Una vez con la carpeta abierta observarás todas las carpetas, y aquí te va una descripción de ellas. ===Carpetas=== *'''area''': Aqui se encuentran las areas que conforman el juego (como ciudades, cuartos, etc.) *'''building''': Esta no se para que es, ya que se encuentra vacia, pero seguro es para construir o cuando construyes los datos se pondran ahí. Quien sabe... *'''corpses''': Esta carpeta es la de cuerpos. Igual que la otra no se para que es. *'''deleted''': Esta carpeta tampoco... pero yo digo que contendrá todos los personajes que borres. *'''log''': Aqui se guardan las bitácoras. *'''races''': Esta contiene las razas del juego, vienen unas predeterminadas. *'''clans''': Esta contendrá todos los clanes que se hagan. *'''council''': Esta es como los clans, todos los que hagas se quedarán aquí. *'''doc''': Esta carpeta contiene los documentos del SMAUG. *'''logs''': Esta también es para registros *'''src''': Esta carpeta es muy importante, contiene los recusros del MUD. Mas tarde dedicaremos un capitulo en explorarla. *'''boards''': La carpeta boards contendra todos los mensajes que hagas, esots mensajes son los que se muestran al inicio, pueden ser desde noticia, información de actualizaciones, o hasta los puedes configurar para que solo se muestren a un grupo determinado de jugadores (ej. inmortales) *'''classes''': Las clases son como las razas, pero difernetes(...). Mas detallado seria así: Las clases son lo mas importamte, ya que deciden que seras al inicio, por ejemplo, un mago o un guerrero. Mientras que las razas solo cambian algunos aspectos. Eemplo, un mago elfo (clase-raza) o un paladin enano (clase-raza). *'''deity''': La carpeta deity contiene las deidades del juego. Las deidades son un punto importante, ya que estas le pueden conceder a los jugadores algunos favores, como regresar los cuerpos a sus dueños (luego hablaremos de esto) o hasta algunos poderes. En la carpeta vienen algunas deidades por defecto. *'''gods''': Esta carpeta es la mejor, ya que aquí se encunetran los dioses del juego (pronto te dire como convertirte en uno). Hablaremos de los dioses mas tardes. *'''playes''': La carpeta mas importante del juego es esta, y no es porque aquí este todo el código almacenado, ni porque los controladores esten, ni algo parecido a eso. No, señor, nada como eso. Aqui encontraras lo mas importante de tu juego, que son los jugadores. Después de esto creeras que soy un cursi y toda la cosa, pero en realidad es importante, porque, ¿que seria de un juego multijugador sin los jugadores?. Solo imagina que por error borras esta carpeta cuando el juego ya esta en un servidor; lo que pasara es que todos los jugadores se enfadaran y se olvidaran de tu juego, correran la voz de que tu juego no sirve y te quedaras solo de nuevo. Asi que cuida bien esa carpeta. Abriendo la carpeta te encontras con otras carpetas que tiene por nombre letras, aquí se guarda la información del jugador. Por ejemplo, si tu personaje se llama beto, este quedara almacenado en la carpeta B, y ahi estara toda su información. *'''system''': La ultima pero no menos importante carpeta es la del sistema, aquí se guardaran los archivos que necesitas, como los skills, los comandos para hablar, el clima, y varios otros archivos mas. Es tiempo de pasar a lo importante, la realizacion del juego, pero antes debes convertirte en dios, así que no esperes y pasa a la siguiente pag. Eso es todo. ''Siguinete Pagina: [[Crear un MUD/Iniciando la creacion|Iniciando la creacion]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Obteniendo lo necesario|Obteniendo lo necesario]]''</small> {{AutoCategoríaLibro}} nk9q0gp6590pdeyhz7x4lytnvhs0uzl 427897 427874 2026-07-16T03:53:15Z Mazbel 57931 427897 wikitext text/x-wiki ''Siguinete Pagina: [[Crear un MUD/Iniciando la creacion|Iniciando la creacion]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Obteniendo lo necesario|Obteniendo lo necesario]]''</small> ==Reconociendo todo== Ok, ya obtuviste lo necesario, ahora debes comprender lo obtenido. Para empezar abre la carpeta donde grabaste SMAUG, porque haremos un truquito para que seas el amo y señor de tu juego. Una vez con la carpeta abierta observarás todas las carpetas, y aquí te va una descripción de ellas. ===Carpetas=== *'''area''': Aqui se encuentran las areas que conforman el juego (como ciudades, cuartos, etc.) *'''building''': Esta no se para que es, ya que se encuentra vacia, pero seguro es para construir o cuando construyes los datos se pondran ahí. Quien sabe... *'''corpses''': Esta carpeta es la de cuerpos. Igual que la otra no se para que es. *'''deleted''': Esta carpeta tampoco... pero yo digo que contendrá todos los personajes que borres. *'''log''': Aqui se guardan las bitácoras. *'''races''': Esta contiene las razas del juego, vienen unas predeterminadas. *'''clans''': Esta contendrá todos los clanes que se hagan. *'''council''': Esta es como los clans, todos los que hagas se quedarán aquí. *'''doc''': Esta carpeta contiene los documentos del SMAUG. *'''logs''': Esta también es para registros *'''src''': Esta carpeta es muy importante, contiene los recusros del MUD. Mas tarde dedicaremos un capitulo en explorarla. *'''boards''': La carpeta boards contendra todos los mensajes que hagas, esots mensajes son los que se muestran al inicio, pueden ser desde noticia, información de actualizaciones, o hasta los puedes configurar para que solo se muestren a un grupo determinado de jugadores (ej. inmortales) *'''classes''': Las clases son como las razas, pero difernetes(...). Mas detallado seria así: Las clases son lo mas importamte, ya que deciden que seras al inicio, por ejemplo, un mago o un guerrero. Mientras que las razas solo cambian algunos aspectos. Eemplo, un mago elfo (clase-raza) o un paladin enano (clase-raza). *'''deity''': La carpeta deity contiene las deidades del juego. Las deidades son un punto importante, ya que estas le pueden conceder a los jugadores algunos favores, como regresar los cuerpos a sus dueños (luego hablaremos de esto) o hasta algunos poderes. En la carpeta vienen algunas deidades por defecto. *'''gods''': Esta carpeta es la mejor, ya que aquí se encunetran los dioses del juego (pronto te dire como convertirte en uno). Hablaremos de los dioses mas tardes. *'''playes''': La carpeta mas importante del juego es esta, y no es porque aquí este todo el código almacenado, ni porque los controladores esten, ni algo parecido a eso. No, señor, nada como eso. Aqui encontraras lo mas importante de tu juego, que son los jugadores. Después de esto creeras que soy un cursi y toda la cosa, pero en realidad es importante, porque, ¿que seria de un juego multijugador sin los jugadores?. Solo imagina que por error borras esta carpeta cuando el juego ya esta en un servidor; lo que pasara es que todos los jugadores se enfadaran y se olvidaran de tu juego, correran la voz de que tu juego no sirve y te quedaras solo de nuevo. Asi que cuida bien esa carpeta. Abriendo la carpeta te encontras con otras carpetas que tiene por nombre letras, aquí se guarda la información del jugador. Por ejemplo, si tu personaje se llama beto, este quedara almacenado en la carpeta B, y ahi estara toda su información. *'''system''': La ultima pero no menos importante carpeta es la del sistema, aquí se guardaran los archivos que necesitas, como los skills, los comandos para hablar, el clima, y varios otros archivos mas. Es tiempo de pasar a lo importante, la realizacion del juego, pero antes debes convertirte en dios, así que no esperes y pasa a la siguiente pag. Eso es todo. ''Siguinete Pagina: [[Crear un MUD/Iniciando la creacion|Iniciando la creacion]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Obteniendo lo necesario|Obteniendo lo necesario]]''</small> {{AutoCat}} hcux5lf5o6mjjbbpcko1546g0t13kao Crear un MUD/Iniciando la creacion 0 6716 427875 247357 2026-07-15T18:35:40Z Antimundo 74354 Usar autocategoría 427875 wikitext text/x-wiki ''Siguinete Pagina: [[Crear un MUD/Iniciando tu MUD I|Iniciando tu MUD I]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''</small> No tengo otra forma de contactar con el autor, al menos no la he encontrado, así que con su permiso editaré este capítulo con un par de cosas que puntualizo pero que no son muy importantes, no me meto en su trabajo, solo recomiendo, espero que no se lo tome a mal. Ahora que ya has checado un poco lo que son las carpetas (recuerda que llevo poco tiempo con el SMAUG, así que no te desesperes, pronto actualizaré), es hora de pasar a lo importante. Para esto necesitaras de abrir tu editor de textos favorito (el Word Pad es el mejor!!! -- ya que mi Word presentaba errores al abrir el tipo de archivos que usaremos) y comenzar a usar la masa gris que algunos le llaman cerebro. No olvides que debes dejar abiertos estos programas. *La carpeta donde guardaste tu SMAUG (Para ver referencias, nombres de archivos y toda la cosa) *Tu simbolo de sistema (MS-Dos o cmd.exe (simbolo de sistema))En los demás OS no se cual sean. (Yo que he tocado y estoy tocando código basado en SMAUG digo que el cmd no es necesario estar abierto, con abrir el smaug.exe ya vale, pero no me meteré en su libro). *El smaug.exe (el Startup es para linux y es el scrip que arranca el servidor, imposible abrir con Windows, le corrijo simplemente eso al editor del libro). *Y este libro para tener referencias. Yo que edito este artículo sin haberle pedido permiso al autor digo que es mejor bajar Kigwin y trabajar desde kygwin instalando los paquetes build essential. Kigwin es para simular un terminal Linux en Windows, aunque si no sabeis mucho ignorar este pequeño párrafo. ''Siguiente Página: [[Crear un MUD/Iniciando tu MUD I|Iniciando tu MUD I]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''</small> {{AutoCategoríaLibro}} l7g3jzoo7oar97os5kuksbmwt1sjv7g 427898 427875 2026-07-16T03:53:28Z Mazbel 57931 427898 wikitext text/x-wiki ''Siguinete Pagina: [[Crear un MUD/Iniciando tu MUD I|Iniciando tu MUD I]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''</small> No tengo otra forma de contactar con el autor, al menos no la he encontrado, así que con su permiso editaré este capítulo con un par de cosas que puntualizo pero que no son muy importantes, no me meto en su trabajo, solo recomiendo, espero que no se lo tome a mal. Ahora que ya has checado un poco lo que son las carpetas (recuerda que llevo poco tiempo con el SMAUG, así que no te desesperes, pronto actualizaré), es hora de pasar a lo importante. Para esto necesitaras de abrir tu editor de textos favorito (el Word Pad es el mejor!!! -- ya que mi Word presentaba errores al abrir el tipo de archivos que usaremos) y comenzar a usar la masa gris que algunos le llaman cerebro. No olvides que debes dejar abiertos estos programas. *La carpeta donde guardaste tu SMAUG (Para ver referencias, nombres de archivos y toda la cosa) *Tu simbolo de sistema (MS-Dos o cmd.exe (simbolo de sistema))En los demás OS no se cual sean. (Yo que he tocado y estoy tocando código basado en SMAUG digo que el cmd no es necesario estar abierto, con abrir el smaug.exe ya vale, pero no me meteré en su libro). *El smaug.exe (el Startup es para linux y es el scrip que arranca el servidor, imposible abrir con Windows, le corrijo simplemente eso al editor del libro). *Y este libro para tener referencias. Yo que edito este artículo sin haberle pedido permiso al autor digo que es mejor bajar Kigwin y trabajar desde kygwin instalando los paquetes build essential. Kigwin es para simular un terminal Linux en Windows, aunque si no sabeis mucho ignorar este pequeño párrafo. ''Siguiente Página: [[Crear un MUD/Iniciando tu MUD I|Iniciando tu MUD I]]''<br /> <small>''Pagina Anterior: [[Crear un MUD/Comprendiendo lo obtenido|Comprendiendo lo obtenido]]''</small> {{AutoCat}} 7hyeqr426i2tbfe2xkcxdi9m9tv1l66 Creación de videojuegos 0 6717 427876 425914 2026-07-15T18:38:22Z Antimundo 74354 Categorizar con estantes 427876 wikitext text/x-wiki Este libro sólo pretende ser una guía de arranque para desarrollar videojuegos. La creación de videojuegos es en principio un '''arte''' que puede ser expresado de muchas maneras, todo depende de la creatividad del desarrollador para utilizar las herramientas a su alcance, y crear las que necesite. Es seguro que la tecnología final para sumergir a los jugadores en la realidad alterna del juego aún no ha sido inventada, y aunque llegue a ser posible construir un nuevo mundo tan lleno de sensaciones como el nuestro, ese solo será el principio para crear una nueva galería de universos, tan vasta como los límites de la creatividad. ¿Tiene algún límite? {| border="0" cellpadding="2" cellspacing="0" style="width:98%; margin-bottom: 1em; text-align: center; border: 1px solid #aaaaaa;" align="center" | style="background-color:#fffadc; padding-top: 4px;"| Invitamos a todos los interesados y aquellos con experiencia en desarrollo de videojuegos a aportar sus ideas. Por favor, al hacer sus aportes regístrense en Wikilibros, usando el enlace arriba a la derecha, y pongan su firma al final de sus contribuciones. |} ==Contenido== *[[Creación de videojuegos/Filosofía del juego|Filosofía del juego]] *[[Creación de videojuegos/Breve historia de los videojuegos|Breve historia de los videojuegos]] *[[Creación de videojuegos/Fundamentos|Fundamentos]] **[[Creación de videojuegos/Fundamentos/Programación|Fundamentos de Programación]] **Fundamentos de Videojuegos ***Arcadia ***Texto ***[[Creación de videojuegos/Fundamentos/Videojuegos/Aventuras|Aventuras]] ***[[Creacion de videojuegos/Fundamentos/Videojuegos/3D de Disparo|3D de Disparo]] ***Multi-jugadores en redes ***Estrategia ***[[Creación de videojuegos/Fundamentos/Videojuegos/Móviles|Móviles]] *[[Creación de videojuegos/Diseño|Diseño]] *[[Creación de videojuegos/Motores|Motores]] *Producción **[[Creación de videojuegos/Producción/Solo o en equipo|Solo o en equipo]] **[[Creación de videojuegos/Producción/Comercialización|Comercialización]] == Véase también == {{-wikilibros|Godot}} == Enlaces externos == *«[http://asm86.wordpress.com/2011/12/26/la-saga-de-la-programacion-grafica-3d ''La Saga de la Programación Gráfica 3D'']» (del año 2011). *«[https://therealpenaz91.itch.io/2dgd-f0th ''2D Game Development: From Zero To Hero'']» (del año 2025, en inglés): Un libro muy completo sobre desarrollo de videojuegos en 2D, con licencia ''CC BY-NC-SA''. *La [[w:Universidad_de_Castilla-La_Mancha|Universidad de Castilla-La Mancha]] publicó en el año 2013 una colección de cuatro libros en español sobre desarrollo de videojuegos bajo licencia ''CC BY-NC-ND''. *#«[https://elhacker.info/manuales/Juegos/M1_ArquitecturaMotor_2Ed.pdf ''Desarrollo de Videojuegos: Arquitectura del Motor'']» ISBN 978-84-686-4028-0 *#«[https://elhacker.info/manuales/Juegos/M2_ProgramacionGrafica_2Ed.pdf ''Desarrollo de Videojuegos: Programación Gráfica'']» ISBN 978-84-686-4026-6 *#«[https://elhacker.info/manuales/Juegos/M3_TecnicasAvanzadas_2Ed.pdf ''Desarrollo de Videojuegos: Técnicas Avanzadas'']» ISBN 978-84-686-4025-9 *#«[https://elhacker.info/manuales/Juegos/M4_DesarrolloComponentes_2Ed.pdf ''Desarrollo de Videojuegos: Desarrollo de Componentes'']» ISBN 978-84-686-4027-3 {{Estantes|Desarrollo de videojuegos}} [[Categoría:Creación de videojuegos]] g8ui008ghvsffkjys4i82co1dttwe0i Programación en C++/Introducción 0 7873 427927 414304 2026-07-16T04:31:44Z Mazbel 57931 actualización 427927 wikitext text/x-wiki {| align="right" |- | [[Programación en C++/Lo más básico|Capitulo 1: Lo más básico]] → |}<br clear="all"> == Conceptos Básicos == <div style="padding:40px; background:#fffeee; text-align:justify;"> === Qué es un Lenguaje de Programación<ref name="lenguajes">[https://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n Lenguaje de Programacion] Definicion de Wikipedia</ref> === Antes de hablar de C++, es necesario explicar que un lenguaje de programación es una herramienta que nos permite comunicarnos e instruir a la computadora para que realice una tarea específica. Cada lenguaje de programación posee una sintaxis y un léxico particular, es decir, forma de escribirse que es diferente en cada uno por la forma que fue creado y por la forma que trabaja su compilador para revisar, acomodar y reservar el mismo programa en memoria. Existen muchos lenguajes de programación de entre los que se destacan los siguientes: # {{libro|Programación en C|C}} # {{libro|Programación en C++|C++}} # [[Programación en Basic|Basic]] # {{libro|Programación en Ada|Ada}} # {{libro|Programación en Java|Java}} # {{libro|Programación en Pascal|Pascal}} # {{libro|Inmersión en Python|Python}} # [[Programación en Fortran|Fortran]] # [[Programación en Smalltalk|Smalltalk]] == Historia de C++ == C++ es un lenguaje de programación creado por [//es.wikipedia.org/wiki/Bjarne_Stroustrup Bjarne Stroustrup] en los laboratorios de At&T en 1983. Stroustrup tomó como base un lenguaje de programación popular en aquella época el cual era C. El C++ es un derivado del mítico lenguaje C, el cual fue creado en la década de los 70 por la mano del finado [//es.wikipedia.org/wiki/Dennis_Ritchie Dennis Ritchie] para la programación del sistema operativo Unix [//es.wikipedia.org/wiki/Unix|Unix] (un sistema parecido a Unix es [[GNU/Linux]]), el cual surgió como un lenguaje orientado a la programación de sistemas ([//en.wikipedia.org/wiki/System_programming System Programming]) y de herramientas (Utilities) recomendado sobre todo para programadores expertos, y que no llevaba implementadas muchas funciones [¿cómo cuáles?] que hacen a un lenguaje más comprensible. Sin embargo, aunque esto en un inicio se puede convertir en un problema, en la práctica es su mayor virtud, ya que permite al programador un mayor control sobre lo que está haciendo. Años más tarde, un programador llamado Bjarne Stroustrup, creo lo que se conoce como C++. Necesitaba ciertas facilidades de programación, incluidas en otros lenguajes pero que C no soportaba, al menos directamente, como son las llamadas clases y objetos, principios usados en la programación actual. Para ello rediseñó C, ampliando sus posibilidades pero manteniendo su mayor cualidad, la de permitir al programador en todo momento tener controlado lo que está haciendo, consiguiendo así una mayor rapidez que no se conseguiría en otros lenguajes. C++ pretende llevar a C a un nuevo paradigma de clases y objetos con los que se realiza una comprensión más humana basándose en la construcción de objetos, con características propias solo de ellos, agrupados en clases. Es decir, si yo quisiera hacer un programa sobre animales, crearía una clase llamada animales, en la cual cada animal, por ejemplo un pato, sería un objeto, de tal manera que se ve el intento de esta forma de programar por ser un fiel reflejo de cómo los humanos (en teoría) manejamos la realidad[referencia]. Se dice que nuestro cerebro trabaja de forma relacional[referencia] (relacionando hechos), es por ello que cada vez que recuerdas algo, (cuentas un hecho), termina siendo diferente (se agregan u omiten partes). === Qué es C++ === C++ es un lenguaje de programación orientado a objetos que toma la base del lenguaje C y le agrega la capacidad de abstraer tipos como en Smalltalk. La intención de su creación fue el extender al exitoso lenguaje de programación C con mecanismos que permitieran la manipulación de objetos. En ese sentido, desde el punto de vista de los lenguajes orientados a objetos, el C++ es un lenguaje híbrido [¿por? fusionar con el siguiente]. Posteriormente se añadieron facilidades de programación genérica, que se sumó a los otros dos paradigmas que ya estaban admitidos (programación estructurada y la programación orientada a objetos). Por esto se suele decir que el C++ es un lenguaje de programación multiparadigma. == Herramientas Necesarias == Las principales herramientas necesarias para escribir un programa en C++ son las siguientes: # Un equipo ejecutando un sistema operativo. # Un compilador de C++ ## Windows [http://www.mingw.org/download.shtml MingW (GCC para Windows)] o [http://msdn.microsoft.com/es-es/visualc/default.aspx MSVC (compilador de microsoft con versión gratuita)] ## Linux (u otros UNIX): [http://gcc.gnu.org/ gcc] ## Mac (con el compilador Xcode) # Un editor cualquiera de texto, o mejor un entorno de desarrollo (IDE) ## Windows: ### Microsoft Visual C++ (conocido por sus siglas MSVC). Incluye compilador y posee una versión gratuita (versión express) ### Bloc de notas (no recomendado) ### [http://notepad-plus.sourceforge.net/es/site.htm Editor Notepad++] ### [http://www.bloodshed.net/devcpp.html DevCpp (incluye MingW - en desuso, no recomendado, incluye también un compilador)] ### [http://www.codeblocks.org/ Code::Blocks] ## Linux (o re-compilación en UNIX): ### [http://projects.gnome.org/gedit/ Gedit] ### [http://kate-editor.org/ Kate] ### [http://www.kdevelop.org/ KDevelop] ### [http://www.codeblocks.org/ Code::Blocks] ### [http://www.scintilla.org/SciTE.html SciTE] ### [http://www.vim.org/ GVim] ## Mac: ### Xcode (con el compilador trae una IDE para poder programar) # Tiempo para practicar # Paciencia '''Adicional''' # Inglés (Recomendado) # Estar familiarizado con C u otro lenguaje derivado (PHP, Python, etc). Es recomendable tener conocimientos de C, debido a que C++ es una mejora de C, tener los conocimientos sobre este te permitira avanzar mas rapido y comprender aun más. También, hay que recordar que C++, admite C, por lo que se puede programar (reutilizar), funciones de C que se puedan usar en C++. Aunque No es obligacion aprender C, es recomendable tener nociones sobre la programación orientada a objetos en el caso de no tener conocimientos previos de programación estructurada. Asimismo, muchos programadores recomiendan no saber C para saber C++, por ser el primero de ellos un lenguaje imperativo o procedimental y el segundo un lenguaje de programación orientado a objetos. </div> == Consejos iniciales antes de programar == <div style="padding:40px; background:#fffeee; text-align:justify;"> Con la práctica, se puede observar que se puede confundir a otros programadores con el código que se haga. Antes de siquiera hacer una línea de código, si se trabaja con otros programadores, ha de tenerse en cuenta que todos deben escribir de una forma similar el código, para que de forma global puedan corregir el código en el caso de que hubieran errores o rastrearlos en el caso de haberlos. También es muy recomendable hacer uso de comentarios (comenta todo lo que puedas, hay veces que lo que parece obvio para ti, no lo es para los demás) y tratar de hacer un código limpio y comprensible, especificando detalles y haciendo tabulaciones, aunque te tome un poco mas de tiempo, es posible que mas adelante lo agradezcas tu mismo. </div> == Ejemplos == El programa [https://es.wikipedia.org/wiki/Hola_mundo Hola mundo] en C++: <source lang=cpp style="font-size:14px;"> #include <iostream> int main() { std::cout << "Hola mundo!" << std::endl; //Imprime el mensaje "Hola mundo!" en pantalla return 0; } </source> '''''Un programa escrito en C++ que pregunta un número al usuario y después nos dice si es par o impar:''''' <source lang=cpp style="font-size:14px;"> // Programa que nos permite saber si el número introducido es par o impar #include <iostream> using std::cout; using std::cin; using std::endl; int main() { int numero; cout << "Introduce un numero: "; cin >> numero; if (numero % 2 == 0) { cout << numero << " es par." << endl; } else { cout << numero << " es impar." << endl; } return 0; } </source> '''''O este programa simple escrito en C++ Por Adrian Gallardo que convierte temperaturas:''''' <syntaxhighlight lang="c++"> #include<iostream> using namespacestd; void main(){ int escala=1; double k=1, c=1, f=1, temperatura=1; cout<<"Pon tu Escala, 1 para Kelvin 2 Para Celsius o 3 Para Farenheit: "; cin>>escala; if (escala<=3){ if (escala>=1){ cout<<"\nOk porfavor pon la temperatura: "; cin>>temperatura; if (escala==1){ double k=temperatura, c=temperatura-273.15, f=c*1.8+32; } else if (escala==2){ double k=temperatura+273.15, c=temperatura, f=c*1.8+32; } else if (escala==3){ double c=temperatura*0.5555-32, f=temperatura, k=c+273.15; } cout<<"\nLas temperaturas son: "; cout<<k; cout<<"K, "; cout<<c; cout<<"°C, "; cout<<f; cout<<"°F."; } } else { cout<<"\nEl numero introducido no se pudo registrar, reinicie el programa."; } } </syntaxhighlight> == Referencias == <references /> {{AutoCat}} 22ia7kmg4wqmo9i0ir91zmz2vv75qcy Programación en C++/Lo más básico 0 7874 427928 411689 2026-07-16T04:32:07Z Mazbel 57931 actualización 427928 wikitext text/x-wiki {| align="center" cellpadding="12" |- | font color="blue" | &#8592; [[Programación en C++/Introducción|Introduccion]] | font color="blue" | [[Programación en C++/Iteraciones y decisiones|Iteraciones y decisiones]] &#8594; |} == Estructura de un programa == <div style="padding:40px; background:#fffeee; text-align:justify" > En general, los programas escritos en C++ tienen una estructura (básica) compuesta por tres secciones: # Directivas de preprocesador # declaraciones globales # declaración de funciones === Directivas de preprocesador === Los compiladores de C++ proporcionan bibliotecas de funciones, y cada biblioteca de funciones tiene asociada un archivo de definición que se denomina cabecera. Para utilizar algo de una biblioteca en un programa (por ejemplo, una función), hay que colocar al principio del programa una directiva de preprocesamiento seguida de la cabecera de la biblioteca entre signos de "menor que" y "mayor que" (<>). A continuación se muestra un típico ejemplo de una directiva de preprocesador: <source lang=cpp style="font-size:14px;"> #include <iostream> </source> En el ejemplo anterior, la directiva invocada es include y la cabecera iostream, e indican al preprocesador que debe incluir la librería iostream a nuestro programa. Cabe señalar que todas las directivas comienzan con el símbolo numeral #. Dentro de las directivas de preprocesador se encuentran: # Macros de preprocesador (#define y #undef) # Inclusiones condicionales (#ifdef, #ifndef, #if, #endif, #else and #elif) # Control (#line) # Error (#error) # Inclusión de fichero (#include) # Pragma (#pragma) ==== Macros de preprocesador ==== Para definir macros de preprocesador, usamos la directiva #define. La sintaxis es: <source lang=cpp style="font-size:14px;"> #define identificador reemplazo </source> Cuando el procesador encuentra esta directiva, este reemplaza todas las ocurrencias del identificador y son sustituidas por reemplazo. Cuando se requiere desactivar una macro, a partir de cierta parte del código, se utiliza la directiva #undef. La sintaxis es: <source lang=cpp style="font-size:14px;"> #undef nombre_macro </source> ==== Inclusiones condicionales ==== Estas directivas permiten incluir o descartar partes de código, si se cumplen algunas condiciones. * #ifdef: Permite que una sección del programa sea compilada solo si la macro especificada como parámetro ha sido definida, sin importar el valor de esta. Por ejemplo: <source lang=cpp style="font-size:14px;"> #ifdef TABLE_SIZE int table[TABLE_SIZE]; #endif </source> El ejemplo anterior indica que, si la macro TABLE_SIZE se encuentra definida, entonces procede a la creación de una matriz de enteros de tamaño TABLE_SIZE. Cabe señalar que el fin para esta directiva es la directiva #endif * #ifndef: Permite realizar exactamente todo lo contrario a #ifdef. La lineas de código que se encuentren entre #ifndef y #endif, serán ejecutadas siempre y cuando la macro señalada como parámetro de #ifndef no se encuentre definida aun. Por ejemplo: <source lang=cpp style="font-size:14px;"> #ifndef TABLE_SIZE #define TABLE_SIZE 100 #endif int table[TABLE_SIZE]; </source> En el ejemplo anterior, se indica que si la macro TABLE_SIZE no está definida aún, entonces se define. Cabe señalar que el fin para la directiva #ifndef es, al igual que #ifdef, #endif. * #if, #else y #elif (o else if): Estas directivas tienen el mismo significado que los comandos condicionales de cualquier lenguaje de programación. Por ejemplo: <source lang=cpp style="font-size:14px;"> #if TABLE_SIZE>200 #undef TABLE_SIZE #define TABLE_SIZE 200 #elif TABLE_SIZE<50 #undef TABLE_SIZE #define TABLE_SIZE 50 #else #undef TABLE_SIZE #define TABLE_SIZE 100 #endif int table[TABLE_SIZE]; </source> En el ejemplo anterior, se muestra el uso de todas las directivas condicionales del preprocesador. ==== Control ==== Cuando compilamos un programa y un error ocurre durante el proceso de compilación, el compilador muestra un mensaje de error con las referencias al nombre del archivo donde ocurrió el error y un número de línea, por lo que es más fácil encontrar el código que genera el error. La directiva #line nos permite controlar ambas cosas, los números de línea en los archivos de código, así como el nombre del archivo que queremos que aparece cuando un error ocurre. Su formato es: <source lang=cpp style="font-size:14px;"> #line numero "nombre_de_archivo" </source> Donde número es el nuevo número de línea que se asignará a la siguiente línea de código. Los números de línea de las líneas sucesivas se incrementarán uno por uno desde este punto en adelante."nombre_de_archivo" es un parámetro opcional que permite redefinir el nombre del archivo que se mostrará. Por ejemplo: <source lang=cpp style="font-size:14px;"> #line 20 "asignacion de variable" int a?; </source> Este código generará un error que se mostrará como un error en el archivo de "asignación de variable", línea 20. ==== Error ==== Esta directiva cancela la compilación cuando es encontrada, generando un error de compilación que puede ser especificado según un parámetro de un ejercicio. Por ejemplo: <source lang=cpp style="font-size:14px;"> #ifndefcplusplus #error A Se requiere compilador de C++ #endif </source> En el ejemplo anterior, la compilación es cancelada si la macro __cplusplus no está definida (Esta macro es definida por defecto en todos los compiladores de C++). ==== Inclusión de fichero ==== Cuando el preprocesador encuentra la directiva #include, este reemplaza todas las ocurrencias de ella por el archivo o cabecera especificada. Existen dos formas de utilizar #include: * #include <cabecera>: Es usado para incluir las cabeceras proporcionadas por defecto, por ejemplo, la librería estándar (string, iostream, etc.). * #include "archivo" : Es usado para incluir archivos. ==== Pragma ==== La directiva #pragma es utilizada para especificar las distintas opciones del compilador. Estas opciones son especificadas dependiendo del compilador que se utilice. Si el compilador no permite un argumento para #pragma, esto es ignorado y no genera un error de sintaxis. === Declaraciones globales === En esta sección se declaran todas variables y cabeceras de funciones que seran vistas de manera global, es decir, que su alcance es total en el programa. Por ejemplo: <source lang=cpp style="font-size:14px;"> #include <iostream> #define PI 3.1415 std::string autor: "Wikibooks"; int adicion(int, int); </source> En el ejemplo anterior, se definen (ademas de las directivas de preprocesador, vistas en la sección anterior) una variable y una función. La variable autor podrá ser utilizada por todas las funciones del programa. Mientras que la función "adicion" solo fue declarada de la forma "inline". Una función se dice declarada "inline" cuando solo se señala su nombre y sus tipos de entrada y salida. Su definición completa se reserva para mas adelante. === Declaración de funciones === La ultima sección del programa es la declaración de funciones. La primera función que se debe declarar es la función principal o "main". La función main es la mas importante, pues es la que es invocada cuando el programa se ejecuta. Toda instrucción que no sea declarada dentro de esta, simplemente no sera considerada. A continuación de la función "main", se permite la definición completa de las funciones declaradas en la sección de declaraciones globales. En el siguiente ejemplo, mostraremos la estructura definitiva de un programa y la declaración completa de sus funciones: <source lang=cpp style="font-size:14px;"> #include <iostream> #define PI 3.1415 std::string autor= "Wikibooks"; int adicion(int, int); int main(int argc, char **argv) { std::cout<<"El resultado de la suma de 1 y 2 es "<<adicion(1,2)<<std::endl; return 0; } int adicion(int a, int b) { return a+b; } </source> Los parámetros de entrada de la función main es algo que se abordará mas adelante. == Proceso de desarrollo de un programa == Si se desea escribir un programa en C++ se debe ejecutar como mínimo los siguientes pasos: # Escribir con un editor de texto plano un programa sintácticamente válido o usar un entorno de desarrollo (IDE) apropiado para tal fin<br /> # Compilar el programa y asegurarse de que no han habido errores de compilación<br /> # Ejecutar el programa y comprobar que no hay errores de ejecución<br /> Este último paso es el más costoso, por que en programas grandes, averiguar si hay o no un fallo prácticamente puede ser una tarea totémica. Como ejemplo, si se desea escribir un archivo con el nombre hola.cpp y en él escribir un programa con emacs, por ejemplo, que es un programa de edición de textos, se puede, en GNU, ejecutar el siguiente comando: <pre> $emacs hola.cpp & </pre> Para otros sistemas operativos u otros entornos de desarrollo, no necesariamente se sigue este paso. A continuación se escribe el siguiente código en C++: <br />'''Ejemplo'''<br /> <source lang=cpp style="font-size:14px;"> // Aquí generalmente se suele indicar qué se quiere con el programa a hacer // Programa que muestra 'Hola mundo' por pantalla y finaliza // Aquí se sitúan todas las librerias que se vayan a usar con #include, // que se verá posteriormente // Las librerias del sistema son las siguientes #include <iostream> // Función main // Recibe: void // Devuelve: int // Función principal, encargada de mostrar "Hola Mundo",por pantalla int main(void) { // Este tipo de líneas de código que comienzan por '//' son comentarios // El compilador los omite, y sirven para ayudar a otros programadores o // a uno mismo en caso de volver a revisar el código // Es una práctica sana poner comentarios donde se necesiten, std::cout << "Hola Mundo" << std::endl; // Mostrar por std::cout el mensaje Hola Mundo y comienza una nueva línea return 0; // se devuelve un 0. //que en este caso quiere decir que la salida se ha efectuado con éxito. } </source> Mediante simple inspección, el código parece enorme, pero el compilador lo único que leerá para la creación del programa es lo siguiente: <br />'''Ejemplo'''<br /> <source lang=cpp style="font-size:14px;"> #include <iostream> int main(void){ std::cout << "Hola Mundo" << std::endl; return 0; } </source> Como se puede observar, este código y el original no difieren en mucho salvo en los saltos de línea y que los comentarios, de los que se detallan posteriormente, están omitidos y tan sólo ha quedado "el esqueleto" del código legible para el compilador. Para el compilador, todo lo demás, sobra. O este otro, que es, en parte, como el lenguaje C, en su versión C99, es: <br />'''Ejemplo'''<br /> <source lang=cpp style="font-size:14px;"> #include <stdio.h> #include <stdlib.h> int main(void) { printf( "Hola Mundo\n" ); return EXIT_SUCCESS; // 'EXIT_SUCCESS' es una definición que está dentro de 'stdlib.h' // también funciona return 0 } </source> Nota: si se usa Windows, el código es el mismo, pero debemos agregar un método más para que el programa se mantenga abierto y no se cierre la consola, cosa que en GNU, no es necesaria por que la consola ya esta abierta (al mandar a ejecutar). Para esto podemos usar cin.get() que nos permitirá leer del teclado, por lo que el programa no finaliza, hasta que el usuario pulse enter. <br />'''Ejemplo'''<br /> <source lang=cpp style="font-size:14px;"> #include <iostream> int main(void) { std::cout << "Hola Mundo" << std::endl; std::cin.get(); //con 'std::cin.get();' lo que se hace es esperar hasta que el usuario pulse enter. return 0; } </source> Los pasos siguientes son para una compilación en GNU o sistema operativo Unix. En Windows tampoco es aplicable. Con ctrl-x ctrl-s se guarda el archivo. Ahora para generar el ejecutable del programa se compila con g++ de la siguiente forma: <pre> $ g++ hola.cpp -o hola </pre> Para poder ver los resultados del programa en acción, se ejecuta el programa de la siguiente forma: <pre> $./hola </pre> Y a continuación se debe mostrar algo como lo siguiente: <pre> Hola Mundo </pre> === Comentarios === Cuando se escriben programas es muy útil agregar comentarios que ayuden a explicar lo que realiza un programa. En C++ se pueden utilizar tres tipos de comentarios: al estilo C, al estilo C++ y usando preprocesador. Los comentarios al estilo C se caracterizan por lo siguiente: comenzar el "bloque" de comentarios con /* y terminar dicho "bloque" de comentarios con */ Ej: <source lang=cpp style="font-size:14px;"yo> /* Este es un comentario al estilo C. Todo lo escrito dentro de las etiquetas de apertura y cierre es un comentario. A estos comentarios se le llaman multilínea, lógicamente por el hecho de permitir varias líneas de comentarios. */ </source> Si se usan este tipo de etiquetas de comentarios, hay que tener cuidado con el cierre (*/), por que el compilador puede tomar todo el texto como comentario, o cerrar antes de lo deseado. Usando el estilo de código de C++ sólo pueden ocupar una línea como en el siguiente código: <source lang=cpp style="font-size:14px;"> // Este es un comentario al estilo C++ </source> Una buena práctica de programación es pensar que se programa a sabiendas de que otro programador, tal vez el lector mismo en un futuro, tenga que "desencriptar" qué quiso hacer ahí y por qué. Otra posible forma de comentar código es usando el preprocesador. Esto se detalla más adelante en profundidad, por ahora la parte útil del preprocesador que interesa es la siguiente: <source lang=cpp style="font-size:14px;"> #if 0 Comentarios sobre el programa /parte del programa. Pueden ocupar múltiples líneas. Más complicado de visualizar que los comentarios C/C++ #endif </source> Este tipo de comentarios se usan rara vez. Generalmente son difíciles de localizar, incluso para programadores experimentados que trabajan en papel, y son fáciles de distinguir en casi cualquier IDE. Es recomendable indicar que se tratan de comentarios, o directamente no usarlos, salvo si son grandes cantidades de comentarios. Se verá más adelante que también puede tener otros usos. === Utilización de la consola o terminal === En los ejemplos anteriores se utilizaron 'std::cout'. 'std::cout' es un "objeto" que permite escribir en la consola (la terminal en GNU/Unix/MacOSX), solo se puede utilizar gracias a que se ha incluido definiciones de su uso con la línea de código '#include <iostream>'. <source lang=cpp style="font-size:14px;"> std::cout << ALGO; </source> Donde ALGO puede ser lo que sea que 'std::cout' sea capaz de mostrar por consola. Más adelante se trata más sobre ello en detalle y aclarando posibles dudas que ahora puedan surgir. También se utilizó 'std::endl', esto permite que el texto se escriba en una nueva línea. Un ejemplo más completo sobre la escritura en consola es el siguiente. Ha de tenerse en cuenta que se han eliminado algunos comentarios superfluos del primer programa debido a que ahora se está tratando con más detalle acerca del uso de imprimir texto en la consola: <br />'''Ejemplo'''<br /> <source lang=cpp style="font-size:14px;"> // Programa que muestra diversos textos por consola // Las librerías del sistema usadas son las siguientes #include <iostream> // Función: main // Recibe: void // Devuelve: int // Es la función principal encargada de mostrar por consola diferentes textos int main(void) { // Ejemplo con una única línea, se muestra el uso de std::cout y std::endl std::cout << "Bienvenido. Soy un programa. Estoy en una linea de codigo." << std::endl; // Ejemplo con una única línea de código que se puede fraccionar mediante el uso de '<<' std::cout << "Ahora " << "estoy fraccionado en el codigo, pero en la consola me muestro como una unica frase." << std::endl; // Uso de un código largo, que cuesta leer para un programador, y que se ejecutará sin problemas. // *** No se recomienda hacer líneas de esta manera, esta forma de programar no es apropiada *** std::cout << "Un gran texto puede ocupar muchas lineas." << std::endl << "Pero eso no frena al programador a que todo se pueda poner en una unica linea de codigo y que" << std::endl << "el programa, al ejecutarse, lo situe como el programador quiso" << std::endl; return 0; // Y se termina con éxito. } </source> Se reta a compilar este código y a observar sus resultados. En este momento el lector está capacitado para escribir programas que impriman por pantalla el mensaje que se quiera. '''Atención:''' Se hace hincapié en la posibilidad de que las palabras acentuadas no se puedan mostrar en la consola. Depende completamente del compilador que se pueda ver lo siguiente: <source lang=cpp style="font-size:14px;"> std::cout << "programación"; </source> Con algunos compiladores, verá 'programación', pero con otros puede ver incluso 'programaci n'. <div style="border: 1px solid #000000; background-color: #eeeeee; padding:8px;">'''Advertencia:''' ''cout'' puede ser utilizado sin tener ''std::'' de forma previa porque se puede introducir una directiva, denominada 'using', que acomoda todos los ''cout''. De otro modo habría un error de compilador. Este tema se trata en detalle más adelante. <div style="border: 1px solid #008000; padding:8px"> <source lang=cpp style="font-size:14px;"> using namespace std; </source> </div> </div> == Sintaxis == Sintaxis es la forma correcta en que se deben escribir las instrucciones para el computador en un lenguaje de programación específico. C++ hereda la sintaxis de C estándar, es decir, la mayoría de programas escritos para el C estándar pueden ser compilados en C++. === El punto y coma === El punto y coma es uno de los símbolos más usados en C, C++; y se usa con el fin de indicar el final de una línea de instrucción. El punto y coma es de uso obligatorio.<br /><br /> '''ejemplo'''<br />´´´´´´ <source lang="cpp"> clrscr(); //Limpiar pantalla, funciona solo con la librería conio de Borland C++ x = a + b; string IP = "127.0.0.1"; // Variable IP tipo string cout << IP << endl; // Devuelve 127.0.0.1 char Saludo[5] = "Hola"; // Variable Saludo tipo char cout << Saludo[0] << endl; // Igual a H cout << Saludo[1] << endl; // Igual a o cout << Saludo[2] << endl; // Igual a l cout << Saludo[3] << endl; // Igual a a </source><br /> El punto y coma se usa también para separar contadores, condicionales e incrementadores dentro de una sentencia '''for'''<br /><br /> '''ejemplo'''<br /> <source lang="cpp"> for (i=0; i < 10; i++) cout << i; </source><br /> === Espacios y tabuladores === Usar caracteres extras de espaciado o tabuladores ( caracteres '''tab''' ) es un mecanismo que nos permite ordenar de manera más clara el código del programa que estemos escribiendo, sin embargo, el uso de estos es opcional ya que el compilador ignora la presencia de los mismos. Por ejemplo, el segundo de los ejemplos anteriores se podría escribir como: <source lang="cpp"> for (int i=0; i < 10; i++) { cout << i * x; x++; } </source> y el compilador no pondría ningún reparo. == Tipos primitivos == En un lenguaje de programación es indispensable poder almacenar información, para esto en C++ están disponibles los siguientes tipos que permiten almacenar información numérica de tipo entero o real: {| class="wikitable" |- ! Nombre !! Descripción !! Tamaño* !! Rango de valores* |- | char || Carácter o entero pequeño || 1byte || con signo: -128 to 127 sin signo: 0 a 255 |- | short int (short) || Entero corto || 2bytes || con signo: -32768 a 32767 sin signo: 0 a 65535 |- | int || Entero || 4bytes || con signo: -2147483648 a 2147483647 sin signo: 0 a 4294967295 |- | long int (long) || Entero largo || 8bytes || con signo: -2147483648 a 2147483647 sin signo: 0 a 4294967295 |- | bool || Valor booleano. Puede tomar dos valores: verdadero o falso || 1byte || true o false |- | float || Número de punto flotante || 4bytes || 3.4e +/- 38 (7 digitos) |- | double || De punto flotante de doble precisión || 8bytes || 1.7e +/- 308 (15 digitos) |- | long double || Long de punto flotante de doble precisión || 8bytes || 1.7e +/- 308 (15 digitos) |} * Los valores dependen de la arquitectura utilizada. Los mostrados son los que generalmente se encuentran en una máquina típica de arquitectura 32 bits. ==== El modificador long ==== El modificador long le indica al compilador que el tipo debe utilizar más bits que los normalmente utilizados por ejemplo si tenemos en una máquina de 32 bits como un Pentium de Intel, normalmente de un int ocupa 32 bits, pero si al declarar un entero le anteceden long, este entero ocupa 64 bits, el siguiente código muestra como utilizar este modificador: <source lang=cpp> int corto; // Entero de 32 bits long int largo; // Entero de 64 bits </source> ==== El Modificador short ==== Similar al anterior, pero indica que se deben utilizar menos bits. Por ejemplo, en un computador de 32 bits, un short int ocupa 16 bits. ==== El Modificador unsigned ==== El modificador unsigned es utilizado únicamente con los enteros, permite utilizar todo el rango posible de valores en positivo, <source lang=cpp> int a; // Almacena valores entre -32768 y 32767 unsigned int a; // Almacena valores entre 0 y 65535 </source> ==== El Modificador register ==== Este modificador sobre una variable le indica al compilador que la variable debe almacenarse en un registro en el compilador, que para el caso de los IA32, es un registro real de la propia CPU, y por tanto el tiempo de acceso es más rápido respecto a la memoria RAM. Hoy en día apenas se utiliza este modificador, ya que los compiladores son capaces de determinar de manera óptima la asignación de registros a variables del programa. ==== El Modificador volatile ==== Al contrario que el modificador registrer, volatile obliga al compilador a forzar el código resultante de manera que la variable modificada con este modificador, sea almacenada siempre en la memoria. El efecto que tiene es que cuando la variable se modifica con otro valor, dicha variable se almacena directamente en memoria y no queda localizado el valor sólo en el registro de la CPU como pasaba en el caso de register o en condiciones normales. Un uso muy común en el que se suele emplear este modificador, es para acceder a variables que están siendo utilizadas por drivers o por periféricos, ya que si no declarásemos esta propiedad, podría darse el caso que la CPU usase el valor de la variable, por lo que la caché guarda el valor, y poco después la CPU usase de nuevo dicha variable, pero como ésta está en cache, la CPU coge el valor que existe en la caché, que puede ser bien distinta al real puesto que un posible periférico puede haber modificado su valor. ==== El Modificador static ==== Dependiendo del entorno donde se declare la variable que la modifiquemos como static, puede significar dos cosas muy distintas: # Si declaramos una variable static dentro del cuerpo de una función, lo que estamos indicándole al compilador es que dicha variable sea inicializada solo una vez (la primera vez que se llama a la función), y el resto de veces que se llame a la función, la variable contendrá el último valor asignado. Esta variable sólo podrá ser visible desde la función que declara dicha variable. Por ejemplo: <source lang=cpp> void mifuncion(){ static int i=0; cout<<"En la entrada i vale "<<i<<endl; for(int j=0;j<10;j++) i++; cout<<"En la salida i vale "<<i<<endl; } </source> # Si declaramos una variable static fuera del cuerpo de una función, lo que le estamos indicando al compilador, es que dicha variable es privada para el modulo donde se implementa el código del contexto de la variable, es decir, que otro fichero objeto binario, no podrá tener acceso a dicha variable utilizando el modificador extern. Ejemplo: <source lang=cpp> #import "prueba.h" //variable privada para prueba.cpp static int i=0; void mifuncion(){ cout<<"En la entrada i vale "<<i<<endl; for(int j=0;j<10;j++) i++; cout<<"En la salida i vale "<<i<<endl; } </source> Tenga en cuenta que para este último caso, usted podrá acceder a la variable y desde cualquier función que defina dentro de prueba.cpp, pero no tendrá acceso desde cualquier fichero objeto o fuente que no sea prueba.cpp === Espacio que ocupan la variables (en máquinas x86) === El espacio en bits que ocupan en la computadora una variable de este tipo se puede ver en la siguiente tabla: {|border="1" align=center |Tipo || Número de Bits |----------------- |char || 8 |----------------- |short || 16 |----------------- |int || 32 |----------------- |long int || 64 |----------------- |float || 32 |----------------- |double || 64 |} ==== Rango de los Tipos Primitivos ==== El rango que puede almacenar los tipos primitivos en C++ es muy importante, para poder saber cual es el rango de valores que puede almacenar un tipo es necesario conocer el número de bits del tipo. El caso para enteros y para flotantes es distinto. Para enteros se debe saber si el tipo es con signo o sin signo. si es sin signo el rango de valores que puede almacenar es el siguiente: <math> [0 , 2^{Bits} - 1 ] </math> Si el tipo es con signo el rango es el siguiente <math> [-2^{Bits - 1} , 2^{Bits - 1} - 1] </math> Para ilustrar lo anterior supongamos que tenemos un entero de 16 bits sin signo, entonces el rango de valores que puede almacenar es el siguiente: <math> [0 , 2^{16} -1] = [0 , 65535] </math> Para obtener el rango de un entero de 32 bits con signo se puede realizar el siguiente calculo: <math> [-2^{31} , 2^{31}-1] = [-2147483648 , 2147483647] </math> El caso de los números flotantes es distinto y depende en gran manera del compilador y el procesador que este utilizando. Sin embargo hoy en día la mayoría de los compiladores y los procesadores utilizan en estándar de la IEEE para representación en coma flotante. Para saber mas al respecto ver [[Wikipedia:IEEE floating-point standard|IEEE floating-point standard]]. == Tipos enumerados (enum) == Los tipos enumerados son un mecanismo usado en C y C++ con el objetivo de agrupar de alguna manera constantes simbólicas. Para definir tipos enumerados se usa la palabra reservada enum. '''Ejemplo 1''' <source lang="cpp"> enum dias { domingo, lunes, martes, miercoles, jueves, viernes, sabado }; </source> En el ejemplo anterior se define por medio de enum el tipo enumerado dias, en el mismo ejemplo se debe observar que dentro de la construcción se definen las constantes simbólicas: domingo, lunes, ... sabado; y que a las mismas el compilador les asignará respectivamente y por defecto los valores: 0, 1, 2, 3, 4, 5, 6. Es decir, las constantes mencionadas pueden usarse dentro del programa y este sabrá a que valor hace referencia cada una de las mismas. Por ejemplo, la instrucción: cout << domingo; desplegará 0 en la pantalla. El siguiente ejemplo muestra como usar las constantes enumeradas en un ciclo for. <source lang="cpp"> for (int d = domingo; d <= sabado; d++) cout << d; </source> En el siguiente ejemplo se define por medio de enum el tipo enumerado colores, en el mismo se debe de observar la eliminación del comportamiento por defecto ya que a la primera constante (gris) se le asigna en forma específica el valor de 7, de tal manera que la siguiente constante (grisoscuro) tendrá un valor igual a 8 y la constante amarillo será igual a 14. '''Ejemplo 2''' <source lang="cpp"> enum colores { gris = 7, grisoscuro, amarillo = 14 }; </source> == Tipos definidos por el usuario == En muchas ocasiones descubriremos que los tipos primitivos no bastan para llevar a cabo ciertas tareas, debido a esto el lenguaje C, C++ da el soporte necesario para que el programador defina sus propios tipos. Para definir tipos se usa la palabra reservada '''typedef'''. Por ejemplo, si deseamos definir un tipo de dato llamado entero podemos usar la sintaxis: <source lang="cpp"> typedef int entero; </source> Luego, podremos declarar variables, constantes y funciones del tipo '''entero'''. Por ejemplo, entero edad = 33; Un uso más útil y común es el empleo de '''typedef''' para definir datos estructurados. Por ejemplo, supongamos que deseamos definir un tipo estructurado llamado persona y que contenga nombre, edad y sexo. Entonces podemos definir persona como: <source lang="cpp"> typedef struct persona { char nombre[32]; int edad; char sexo; }; </source> Una vez que un tipo ya se ha definido, el mismo puede emplearse para declarar variables y constantes de este. Por ejemplo, con la instrucción: <source lang="cpp"> persona hombre; </source> se está declarando la variable hombre del tipo '''persona'''. Luego, para acceder a cada elemento de la variable hombre usaremos un mecanismo conocido como '''direccionamiento directo''' por medio del carácter de punto ( . ). Por ejemplo, la edad de hombre se debe indicar como: <source lang="cpp"> hombre.edad</source> == Variables y constantes == Una variable, como su nombre lo indica, es un determinado objeto cuyo valor puede cambiar durante el proceso de una tarea específica. Contrario a una variable, una constante es un determinado objeto cuyo valor no puede ser alterado durante el proceso de una tarea específica. En C, C++ para declarar variables no existe una palabra especial, es decir, las variables se declaran escribiendo el tipo seguido de uno o más identificadores o nombres de variables. Por otro lado, para declarar constantes existe la palabra reservada '''const''', así como la directiva '''#define'''. A continuación se muestran ejemplos de declaración de variables y constantes. {| width="50%" border="1" cellpadding="8" cellspacing="1" |- ! Variables ! Constantes ! Constantes |- | int a; || const int a = 100; || #define a 100 |- | float b; || const float b = 100; || #define b 100 |} Notas: <blockquote>A diferencia de las constantes declaradas con la palabra '''const''' los símbolos definidos con '''#define''' no ocupan espacio en la memoria del código ejecutable resultante.</blockquote> <blockquote>El tipo de la variable o constante puede ser cualquiera de los listados en [[#Tipos primitivos|Tipos primitivos]], o bien de un tipo definido por el usuario.</blockquote> Las constantes son usadas a menudo con un doble propósito, el primero es con el fin de hacer más legible el código del programa, es decir, si se tiene (por ejemplo) la constante numérica 3.1416 y esta representa al número pi, entonces podemos hacer declaraciones tales como: #define pi 3.1416<br /><br /> En este caso podremos usar la palabra '''pi''' en cualquier parte del programa y el compilador se encargará de cambiar dicho símbolo por 3.1416. o bien, const double pi = 3.1416;<br /><br /> En este otro caso podremos usar la palabra pi en cualquier parte del programa y el compilador se encargará de cambiar dicho símbolo por una referencia a la constante pi guardada en la memoria. </div> ---- {| align="center" cellpadding="12" |- | font color="blue" | ← [[Programación en C++/Introducción|Introducción]] | font color="blue" | [[#Proceso de desarrollo de un programa|Arriba]] | font color="blue" | [[Programación en C++/Iteraciones y decisiones|Iteraciones y decisiones]] → |} {{AutoCat}} c++ y java bq1zv5txsg4s2zvgyd12t4aam2b5uar Programación en C++/Punteros 0 8027 427938 377638 2026-07-16T04:35:17Z Mazbel 57931 actualización 427938 wikitext text/x-wiki Editores:<br /> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Funciones virtuales|Funciones virtuales]] | ← [[Programación en C++/Estructuras II|Estructuras II]] |} == Punteros == <div style="background:#fffeee; padding:40px; text-align:justify"> Los punteros permiten simular el paso por referencia, crear y manipular estructuras dinamicas de datos, tales como listas enlazadas, pilas, colas y árboles. Generalmente las variables contienen valores especificos. Los punteros son variables pero en vez de contener un valor especifico, contienen las direcciones de las variables a las que apuntan. Para obtener o modificar el valor de la variable a la que apuntan se utiliza el operador de indirección. Los punteros, al ser variables deben ser declaradas como punteros antes de ser utilizadas. === Sintaxis === <source lang="cpp"> int *ptrID, ID; ID = 8; ptrID = &ID; // puntero a ID </source> ptrID es un puntero a int, mientras que la variable ID es solo una variable del tipo int. Todo puntero debe ser precedido por un asterisco '''(*)''' en la declaración. Se puede declarar más de un puntero en la misma sentencia. En el ejemplo que sigue se ve la declaración de dos punteros a int. <source lang="cpp"> int *ptrY, *ptrX; </source> === Operadores === Existen dos operadores a tener en cuenta cuando trabajamos con punteros. El '''operador de dirección (&)''' que devuelve la dirección de memoria de su operando y el '''operador de indirección (*)''' que devuelve un alias para el objeto al cual apunta el operando del puntero. En el siguiente ejemplo vemos como se inicializa una variable X con el valor 15. Luego se crea un puntero a int y por último el puntero pasa a apuntar a la variable X. Esto es, ptrX es un puntero a X. <source lang="cpp"> int X = 15; int *ptrX; ptrX = &X; </source> === Punteros y vectores (arrays) === Los vectores son punteros constantes. Un vector sin subindice es un puntero al primer elemento del vector. Una matriz es un vector de vectores. (Ej: int M[3][3];) de manera que en cada elemento del primer vector "se cuelga" otro vector, pudiendo hacer así referencia a filas y columnas. <source lang="cpp"> int X[15]; int *ptrX; ptrX = X; // ptrX recibe la dirección del primer elemento ( 0 ) de X </source> Así como también podría escribirse <source lang="cpp"> int X[15]; int *ptrX; ptrX = &X[0]; // ptrX es igual a la dirección del primer elemento de X </source> Se pueden utilizar distintos elementos del vector teniendo en cuenta la sintaxis de punteros. <source lang="cpp"> int X[15], Y, *ptrX; ptrX = X; Y = *( ptrX + 7 ); </source> En este caso puede verse que Y toma el valor del elemento 7 del vector X, siendo 7 el desplazamiento dentro del vector. El operador de indirección queda fuera del paréntesis porque tiene una prioridad superior a la del operador +. De no existir los paréntesis, se sumaria 7 al elemento X[0]. Teniendo en cuenta que los vectores son punteros constantes, el nombre del vector puede tratarse como un puntero: <source lang="cpp"> Y = *( X + 7 ); </source> === Aritmética de Punteros === Al usar punteros a matrices, hay que tener en cuenta que la aritmética cambia sensiblemente. <source lang="cpp"> #include <iostream> using std::cout; using std::endl; void main() { int X[6] = { 1, 2, 3, 4, 5, 6 }; int *prtX; prtX = X; // incializo el valor del puntero. cout << endl << *prtX; prtX += 2; cout << endl << *prtX; prtX -= 2; cout << endl << *prtX; prtX++; cout << endl << *prtX; } copiado del Internet para una tarea atte: Oscar Torres & David Paz </source> En el siguiente código, primero se crea un puntero a un arreglo de 6 elementos y si inicializa el puntero ''prtX'' al primer elemento del arreglo ''X[0]''. Si tenemos en cuenta que el siguiente ejemplo se ejecuta en una computadora con enteros de 4 bytes, el segundo elemento de la matriz tendrá en memoria un desplazamiento de 4 bytes, el 2 de ocho y asi sucesivamente. La operación ''prtX += 2;'' produce un desplazamiento llevándolo al 3 elemento dentro del arreglo. Debe entenderse que prtX ahora apunta a una dirección de memoria y la instrucción cambia esta dirección de memoria sumándole 2 multiplicado por el tamaño del tipo de dato del arreglo que en este supuesto sería de 4. ''(dir = ( dir + 2 * 4 ))'', dando por resultado un desplazamiento de 8 bytes. Sería igual que ejecutar la operación ''prtX = &X[2];''. La operación ''prtX -= 2'' obedece a la misma lógica estableciendo el puntero al primer elemento del array ''X[0]'' y el operador ++ modifica el puntero desplazándolo 4 bytes y asignándole el segundo elemento de la matriz. === Matrices de punteros === Para realizar una estructura de datos dinámica, se puede utilizar una matriz donde sus elementos sean punteros. Suponiendo que queramos hacer un calendario y lo dividamos por semanas. Podríamos utilizar una matriz con los días de la semana. <source lang="cpp"> const char *dias[7] = { "Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado" } </source> Cada día de la semana, no es un elemento de la matriz, sino que la expresión dias[7] crea una matriz de siete elementos como punteros a char. === Formas de pasar un valor por referencia === '''Un puntero constante a un dato no constante''' <source lang="cpp"> #include <iostream> void sumoeldoble( int * ); // prototipo void main () { int X = 15; sumoeldoble( &X ); // Pasa la dirección de memoria de X . std::cout << X; } void sumoeldoble( int *ptrX ) { // Toma el valor de X mediante el operador de indirección // La funcion no devuelve nada porque modifica el valor por referencia. *ptrX = *ptrX + ( *ptrX * 2 ); } </source> '''Un puntero no constante a un dato constante''' <source lang="cpp"> #include <iostream> void imprimeChars( const char * ); // prototipo void main () { char cFrase[] = "Hola Mundo"; imprimeChars( cFrase ); } void imprimeChars( const char *ptrStr ) { for ( ; *ptrStr != '\0'; ptrStr++ ) //Sin inicialización std::cout << *ptrStr; } </source> '''Un puntero constante a un dato no constante''' Un puntero es constante cuando apunta siempre a la misma dirección de memoria y si el dato no es constante entonces el valor puede ser modificado. <source lang="cpp"> void main () { int foo, bar; int * const ptrFoo = &foo; // Apuntador constante a un entero en la dirección de memoria de foo *ptrFoo = 53; // Esto devuelve un error porque es un puntero constante. // No se puede alterar la dirección de memoria a la que apunta. ptrFoo = &bar; } </source> '''Un puntero constante a un dato constante''' El puntero constante apunta siempre a la misma dirección de memoria y el valor al que apunta dicho puntero no puede ser modificado mediante el puntero. Este es el metodo en que se debe pasar matrices a funciones que solo leen la matriz y no la modifican. <source lang="cpp"> #include <iostream> using namespace std; int main () { int foo = 3, bar; const int * const ptrFoo = &foo; cout << foo; *ptrFoo = 53; //Error porque no puede alterarse el valor ptrFoo = &bar; // Error foo = 23; cout << foo; } </source> === Punteros a funciones === Teniendo en cuenta que el nombre de una función es en realidad la dirección de memoria donde comienza el código, los punteros a funciones contienen la dirección de memoria de la función a la que apunta, y se pueden pasar y retornar entre funciones. <source lang="cpp"> #include <iostream> using namespace std; bool functionA( int, int, bool (*)( int ) ); //Prototipo bool functionB( int ); //Prototipo void main() { int x = 113, y = 226; if ( functionA( x, y, functionB ) ) cout << "\nEl resultado es verdadero"; else cout << "\nEl resultado es falso"; } bool functionA( int param1, int param2, bool (*verificar)( int ) ) { if ( ( (*verificar)( param1 ) ) && ( (*verificar)( param2 ) ) ) return true; } bool functionB( int param ) { if ( param > 100 ) return true; else return false; } </source> En el ejemplo anterior podrá ver que en la definición de los prototipos, la función functionA recibe tres parámetros, siendo el tercer parámetro un puntero a la funcion functionB, practicamente copiando el prototipo sin el nombre. Cuando se ejecuta functionA, se le pasa como parametro el nombre de la función === Ordenamiento burbuja === '''Ordenamiento burbuja utilizando punteros''' <source lang="cpp"> #include <iostream> #include <iomanip> using namespace std; void orden( int *, const int ); // prototipo void swap( int * const, int * const ); // prototipo int main() { const int nSize = 10; int a[ nSize ] = { 3, 9, 14, 27, 18, 154, 8, 6, 74, 33 }; cout << "\nElementos a ordenar\n"; for ( int j = 0; j < nSize; j++ ) cout << setw( 5 ) << a[ j ]; orden( a, nSize ); // ordena el arreglo cout << "\nElementos ordenados\n"; for ( int j = 0; j < nSize; j++ ) cout << setw( 5 ) << a[ j ]; cout << endl; return 0; // indica terminación exitosa } void orden( int *matriz, const int nSize ) { for ( int pasada = 0; pasada < nSize - 1; pasada++ ) { for ( int k = 0; k < nSize - 1; k++ ) { if ( matriz[ k ] > matriz[ k + 1 ] ) { swap( &matriz[ k ], &matriz[ k + 1 ] ); } } } } void swap( int * const ptrElemento1, int * const ptrElemento2 ) { int mantiene = *ptrElemento1; *ptrElemento1 = *ptrElemento2; *ptrElemento2 = mantiene; } </source> === Proyecto de colas para un banco === '''Por cada 2 clientes normales pasa uno VIP al Cajero''' El codigo es muy simple pero muy trabajado y depurado, esta relizado con if/while.... lo mas complicado son los apuntadores, pero nada del otro mundo, muestra el perfecto uso de funciones, tiene una clave: jahvi, de todas lo puedes leer en el codigo. Compila perfecto en DEV C++. Tiene una interfaces muy creativa, ideal para estudiantes que se están inciando en el desarrollo de software con programación estructurada. recuerda copiarlo en un pagina en blanco en dev c++ desde aqui: (copialo completo y compilalo) <source lang="cpp"> #include <stdio.h> #include <iostream> #include <conio.h> #include <stdlib.h> #include <string.h> using namespace std; typedef struct nodo { int cedula; struct nodo*siguiente; }tiponodo; typedef tiponodo *pnodo; typedef tiponodo *cola; cola cola_n=NULL; cola cola_vip=NULL; int solic; void insertar (cola *cola_n) { cola aux, creado; creado=(pnodo)malloc(sizeof(tiponodo)); cout<<" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"<<endl; cout<<" ||||||||||||||||||||METROPOLI banco universal||||||||||||||||||||"<<endl; cout<<" |||||||||||||||||||||||Le da la bienvenida|||||||||||||||||||||||"<<endl; cout<<" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"<<endl; cout<<" Estimado cliente: Introduzca su numero de cedula"<<endl; cin>> creado->cedula; cout<<" Pronto sera atendido"<<endl; if ((*cola_n)==NULL) { creado->siguiente=*cola_n; *cola_n=creado; } else { aux=*cola_n; while(aux!=NULL) { if(aux->siguiente==NULL) { creado->siguiente=aux->siguiente; aux->siguiente=creado; aux=aux->siguiente; } aux=aux->siguiente; } } } void mostrar_cola (cola cola_n) { cola aux; aux=cola_n; if(aux==NULL) { cout<<"No hay clientes en cola"<<endl; } else { while(aux!=NULL) { cout<<"Cedula: "<<aux->cedula<<endl; cout<<""<<endl; aux=aux->siguiente; cout<<"* Clientes ordenados por orden de llegada((((((SIMCOLAS))))))"<<endl; } } } //modificado hasta acá... falta de orden por parte del creador void insertar_vip (cola *cola_vip){ cola aux_2, creado_vip; creado_vip=(pnodo)malloc(sizeof(tiponodo)); cout<<" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"<<endl;//62 cout<<" ||||||||||||||||||||METROPOLI banco universal||||||||||||||||||||"<<endl; cout<<" |||||||||||||||||||||||Le da la bienvenida|||||||||||||||||||||||"<<endl; cout<<" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"<<endl; cout<<" Estimado cliente: Introduzca su numero de cedula"<<endl; cin>> creado_vip->cedula; cout<<" Pronto sera atendido"<<endl; if ((*cola_vip)==NULL){ creado_vip->siguiente=*cola_vip; *cola_vip=creado_vip; }else{ aux_2=*cola_vip; while(aux_2!=NULL){ if(aux_2->siguiente==NULL){ creado_vip->siguiente=aux_2->siguiente; aux_2->siguiente=creado_vip; aux_2=aux_2->siguiente; } aux_2=aux_2->siguiente; } } } void mostrar_cola_vip (cola cola_vip){ cola aux_2; aux_2=cola_vip; if(aux_2==NULL){ cout<<"No hay clientes V.I.P en cola"<<endl; }else{ while(aux_2!=NULL){ cout<<"Cedula: "<<aux_2->cedula<<endl; cout<<""<<endl; cout<<"* Clientes ordenados por orden de llegada((((((SIMCOLAS))))))"<<endl; aux_2=aux_2->siguiente; } } } void pop (cola *cola_n){ if((*cola_n)==NULL){ cout<<"No hay clientes en cola ((((((SIMCOLAS))))))"<<endl; cout<<""<<endl; } if((*cola_n)!=NULL){ cout<<"Cliente: "<<(*cola_n)->cedula; cout<<" es su turno"<<endl; *cola_n=(*cola_n)->siguiente; free(cola_n); system("PAUSE"); cout<<""<<endl; } if((*cola_n)==NULL){ cout<<"No hay clientes en cola ((((((SIMCOLAS))))))"<<endl; cout<<""<<endl; }else{ cout<<"Cliente: "<<(*cola_n)->cedula; cout<<" es su turno"<<endl; *cola_n=(*cola_n)->siguiente; free(cola_n); system("PAUSE"); cout<<""<<endl; } } void pop_vip(cola *cola_vip){ if(cola_vip!=NULL){ cout<<"Cliente: "<<(*cola_vip)->cedula; cout<<" es su turno"<<endl; *cola_vip=(*cola_vip)->siguiente; free(cola_vip); }else{ cout<<"No hay usuarios V.I.P en cola ((((((SIMCOLAS))))))"<<endl; } } void menu(); void Insertar(); void insertar_vip(); void mostrar_cola(); void mostrar_colavip(); void solicitar_numero(); void salir(); struct perly{ char uxer[]; }data; struct perly *p = &data; int main(int argc, char *argv[]) { system("color 0a"); cout<<" * * * "<<endl; cout<<" * * "<<endl; cout<<" * | * * * * "<<endl; cout<<" * -+- * "<<endl; cout<<" __ | * * * * "<<endl; cout<<" ___| | * _|_ * ____ ____ "<<endl; cout<<" [_]|°°|__ _| |_ * | |....| |....| * * "<<endl; cout<<" | | _|[] []|_ ___ | |....| | ___|__ "<<endl; cout<<" [_]| °° |__|_ ______| | | |_| |....| || -- - | * * "<<endl; cout<<" |________ |__ | |# #| |_| |....| || - -- | _____ "<<endl; cout<<" [_]| _____ | |__[]| | | |_| |....|__|| -- - | |* * *| "<<endl; cout<<" | [___] | |__ |# #| |_| |....|__|| -- -_|_|* * *| "<<endl; cout<<" [_]| | °° | | |__| |__|....| || ___|* *|* * *| "<<endl; cout<<" | _____ | |__ #|_______|....| | |* *|* *|* * *| "<<endl; cout<<" [_]| [___] | °° |__|_______|__ | | |* *|* *|* * *| "<<endl; cout<<" | | __|_____________|__ |* *|* *|* * *| "<<endl; cout<<" [_]| _____ | °° _|___________________|_ |* *|* *|* * *| "<<endl; cout<<" | [___] | |_______________________| ______________ "<<endl; cout<<" __|_______|_________|_______________________| _________________ "<<endl; cout<<" |_______________________________________________________________|"<<endl; cout<<" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"<<endl;//62 cout<<" ||||||||||||||||||||METROPOLI banco universal||||||||||||||||||||"<<endl; cout<<" ||||||||||||Sistema Integral para el Manejo de COLAS|||||||||||||"<<endl; cout<<" |||||||||||||||||||||||||||||SIMCOLAS||||||||||||||||||||||||||||"<<endl; cout<<" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"<<endl; cout<<" |||||||||Creado por: Javier Rodriguez Caracas-Venezuela||||||||||"<<endl; cout<<" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"<<endl; cout<<" Login: "; char usuario[6] = "jahvi"; cin.getline(p->uxer,6); if (strcmp(p->uxer,usuario) == 0) { cout<<"Bienvenid@ al sistema "<<endl; menu(); cout<<""<<endl; }else{ cout<<"Acceso Denegado. Consulte al Admisnistrador "<<endl; } system("PAUSE"); return EXIT_SUCCESS; } void menu() { short a; do { cout<<""<<endl; cout<< "0 - Agregar Cliente"<<endl; cout<< "1 - Agregar Cliente V.I.P"<<endl; cout<< "2 - Solicitar Numero"<<endl; cout<< "3 - Mostrar Cola"<<endl; cout<< "4 - Mostrar Cola V.I.P"<<endl; cout<< "5 - Salir del Sistema"<<endl; cout<<""<<endl; fflush(stdout); cout<<"Opcion #:"; cin>>a; cout<<""<<endl; if (a == 5) exit(1); switch(a){ case 0 : Insertar(); break; case 1 : insertar_vip(); break; case 2 : solicitar_numero(); break; case 3 : mostrar_cola(); break; case 4 : mostrar_colavip(); break; case 5 : salir(); break; default : puts("Usted no ha seleccionado nada, porfavor seleccione algo\n"); break; }; } while (1); } void Insertar(){ insertar(&cola_n); } void insertar_vip(){ insertar(&cola_vip); } void mostrar_cola(){ mostrar_cola(cola_n); } void mostrar_colavip(){ mostrar_cola_vip(cola_vip); } void solicitar_numero(){ pop(&cola_n); if(cola_vip!=NULL){ pop_vip(&cola_vip); }else{ cout<<"No hay cliente V.I.P en cola ((((((SIMCOLAS))))))"<<endl; } } void salir(){ } </source> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Funciones virtuales|Funciones virtuales]] | [[#Punteros|Arriba]] | ← [[Programación en C++/Estructuras II|Estructuras II]] |} [[fr:Programmation C++/Les pointeurs]] [[pl:C++/Referencje]] [[pt:Programar em C++/Ponteiros e matrizes]] {{AutoCat}} 4uc1al9ihyvqp60lu705euuj07arfa1 Plantilla:Versión para imprimir 10 8296 427916 427053 2026-07-16T04:07:38Z Mazbel 57931 actualización 427916 wikitext text/x-wiki __NOEDITSECTION__ <div class="noprint" style="max-width:600px; color:var(--color-base); background-color:var(--background-color-notice-subtle); border: 1px solid var(--border-color-notice); padding:0.5em; font-size:small; margin: 1em auto 1em;"> <div align="center"><big>Esta es la '''versión para imprimir''' de ''[[{{{1|{{BASEPAGENAME}}}}}]]''.</big></div> * Si imprimes esta página, o eliges la opción de <span class="plainlinks">[{{fullurl:{{PAGENAME}}|printable=yes}} Vista preliminar de impresión]</span> de tu navegador, verás que desaparecen este cuadro y los elementos de navegación de arriba y de la izquierda, pues no son útiles en una versión impresa. * Pulsando antes en [{{fullurl:{{FULLPAGENAME}}|action=purge}} Refrescar esta página] te asegurarás de obtener los últimos cambios del libro antes de imprimirlo. * Para más información, puedes ver [[Wikilibros:Versión para imprimir]]. </div> <includeonly> [[Categoría:Libros con versión para imprimir]] [[Categoría:Libro:{{{1|{{BASEPAGENAME}}}}}|*]] </includeonly><noinclude> {{Uso de plantilla}} [[Categoría:Wikilibros:Plantillas de avisos a lectores|{{PAGENAME}}]] </noinclude> t5f8uyd9q0e0lsq2moo9sebcshn3x9l Física/Concepto de Modelo 0 8435 427954 405296 2026-07-16T05:55:57Z Mazbel 57931 actualización 427954 wikitext text/x-wiki La Física utiliza '''modelos matemáticos''' para describir los '''fenómenos naturales'''. Es decir, que las leyes y principios que enuncia son sólo aproximaciones y no algo preciso. Los físicos observan un fenómeno, acumulan datos y luego intentan formular una expresión matemática, generalmente basadas en conocimientos anteriores, que se '''adecue''' a los datos '''experimentales'''. Para hacer un modelo necesitas observar a la naturaleza y así entender más de los fenómenos. Para mayor información ver: *[[w:Modelo científico|Modelo científico]] *[[w:Simulación|Simulación]] *[[w:Modelo matemático|Modelo matemático]] {{AutoCat}} lshagyy17hzsnl7r3qecc5e7o4it91r Programación en C++/Desarrollo Orientado a Objetos 0 9373 427933 304546 2026-07-16T04:33:35Z Mazbel 57931 actualización 427933 wikitext text/x-wiki {| align="center" cellpadding="12" |- | ← [[Programación en C++/Arrays y cadenas de texto|Arrays y cadenas de texto]] | [[Programación en C++/Objetos y Clases|Objetos y Clases]] → |} == Desarrollo Orientado a Objetos == <div style="background:#FFFEEE; text-align:justify; padding:48px"> Antes de empezar a programar con objetos, es necesario entender ciertos conceptos básicos. <u>'''Terminología'''</u> El paradigma de Programación Orientada a Objetos utiliza algunos términos básicos que se explicarán a continuación. * Objeto. Es una entidad que tiene atributos o propiedades y que presenta un comportamiento. Puede ser un objeto del mundo real, o una abstracción al mundo informático. Ejemplo, un automóvil, una persona, un animal, etc.<br /><br /> * Clase. Los humanos percibimos el mundo como un entorno compuesto de cosas, objetos, les llamamos. Interactuamos con tantos, que lo natural es agruparlos de acuerdo a sus características más relevantes o generales. En otras palabras, los clasificamos en clases. Todos los objetos que pertenecen a una clase, contiene todos los elementos comunes a todos los objeto y no particulariza en los elementos que distinguen a los objetos entre sí; ejemplo, la clase automóvil, comprende todos los automóviles que circulan en este momento por las calles. Incluiría elementos que asociamos a los automóviles, como llantas, puertas, asientos, volante, etcétera, pero no particularizaría en cuestiones como color, número de registro o características individuales a cada auto.<br /><br /> * Propiedad. Una característica asociada a una clase. Ejemplo, todos los autos tienen un color, o un registro aunque esta propiedad varíe entre objetos.<br /><br /> * Método. Posible acción que los objetos de una clase pueden realizar. En términos informáticos, un algoritmo que pueden ejecutar. Ejemplo: todos los autos pueden acelerar, frenar, etc. </div> == Características de la programación orientada a objetos == <div style="background:#FFFEEE; text-align:justify; padding:48px"> * '''Encapsulamiento'''. Cuando conducimos un auto, no es necesario que nos enteremos de como hace el motor para girar las ruedas del vehículo. Esos pormenores quedan ocultos al usuario o encapsulados en la estructura del la clase auto. Cada objeto presenta una interfaz al usuario de métodos y propiedades con las cuales se interactúa con él. Así se protege el objeto y todos los miembros de su clase, de alteraciones directas a sus métodos y propiedades.<br /><br /> * '''Polimorfismo'''. Una vez que aprendemos a conducir un auto, podemos manejar prácticamente cualquier auto. Esto se debe a que la interfaz que presentan los objetos auto a los usuarios, es más o menos la misma para cada auto. Todos tiene métodos para acelerar, y si bien, posiblemente los pormenores de como acelera cada auto, sean sustancialmente diferentes; el usuario hace referencia a un mismo método en todos los autos. En términos informáticos, objetos de clases diferentes; incluso en la misma clase; pueden tener métodos homónimos, que hagan cosas equivalentes aunque los detalles del como, sean diferentes.<br /><br /> * '''Herencia'''. La clase auto es una clase muy general; se puede hacer un desglose más pormenorizado, por ejemplo, si hacemos subclases de autos deportivos, utilitarios, compactos, manuales, automáticos, de lujo, etc. Cada subclase toma de su clase base (o superclase, en la jerga informática) las propiedades y métodos más generales y agrega las propias. Así, como todos los autos, tienen color y registro, así que éstas estarían contenidas en la superclase auto. Propiedades como Capacidad en toneladas, sistema estéreo o cantidad de velocidades, estarían delegadas a las subclases más particulares. </div> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Arrays y cadenas de texto|Arrays y cadenas de texto]] | [[#Desarrollo Orientado a Objetos|Arriba]] | [[Programación en C++/Objetos y Clases|Objetos y Clases]] → |} {{AutoCat}} i7jiuyt84jyw12ox139ykahydhg60qo Programación en C++/Analisis y Diseño orientado a Objetos 0 10122 427943 304538 2026-07-16T04:36:29Z Mazbel 57931 actualización 427943 wikitext text/x-wiki *[[/Introducción al desarrollo de Software|Introducción al desarrollo de Software]] *[[/Analisis del Problema|Analisis del Problema]] *[[/Diseño de la solución (software)|Diseño de la solución (software)]] *[[/Representación del problema y la solución (notación)|Representación del problema y la solución (notación)]] {{AutoCat}} d0xuhqj4s7op8bihymajz24atj50x7y Programación en C++/Funciones 0 11166 427930 385014 2026-07-16T04:32:45Z Mazbel 57931 actualización 427930 wikitext text/x-wiki {| align="center" cellpadding="12" |- | ← [[Programación en C++/Estructuras|Estructuras]] | [[Programación en C++/Streams|Streams]] → |} = Funciones = == Definiendo una función == <div style="background:#FFEEFF; text-align:justify; padding:100px; border:1px; border-color:red; border-style:solid"> [[Archivo:Funciones.png|left|Modelo de programación estructurada]] Una función es un conjunto de líneas de código que realizan una tarea específica y puede retornar un valor. Las funciones pueden tomar parámetros que modifiquen su funcionamiento. Las funciones son utilizadas para descomponer grandes problemas en tareas simples y para implementar operaciones que son comúnmente utilizadas durante un programa y de esta manera reducir la cantidad de código. Cuando una función es invocada se le pasa el control a la misma, una vez que esta finalizó con su tarea el control es devuelto al punto desde el cual la función fue llamada. </div><br clear="all" /> <div style="background:#FFFFEE; text-align:justify; padding:40px;margin-top:20px"> <tipo> [clase::] <nombre> ( [Parámetros] ). { cuerpo; } '''Ejemplo de una función''' Para comenzar, vamos a considerar el caso en el cual se desea crear la función '''cuadrado()''', que deberá devolver el cuadrado de un número real (de punto flotante), es decir, cuadrado() aceptará números de punto flotante y regresará una respuesta como número flotante. '''Nota''': aunque para la función que veremos el tipo de retorno coincide con el tipo de parámetro pasado, algunas veces las cosas pueden cambiar, es decir, no es obligatorio que una función reciba un parámetro de un tipo y que tenga que regresar una respuesta de dicho tipo. <source lang="cpp"> // regresar el cuadrado de un número double Cuadrado(double n) { return n*n; }</source> == Parámetros == Normalmente, las funciones operan sobre ciertos valores pasados a las mismas ya sea como constantes literales o como variables, aunque se pueden definir funciones que reciban parámetros. Existen dos formas en C++ de pasar parámetros a una función; por referencia o por valor. El hecho es que si en una declaración de función se declaran parámetros por referencia, a los mismos no se les podrá pasar valores literales ya que las referencias apuntan a objetos (variables o funciones) residentes en la memoria; por otro lado, si un parámetro es declarado para ser pasado por valor, el mismo puede pasarse como una constante literal o como una variable. Los parámetros pasados por referencia pueden ser alterados por la función que los reciba, mientras que los parámetros pasados por valor o copia no pueden ser alterados por la función que los recibe, es decir, la función puede manipular a su antojo al parámetro, pero ningún cambio hecho sobre este se reflejará en el parámetro original. '''Parámetros por valor''' La función '''cuadrado()''' (ver arriba) es un clásico ejemplo que muestra el paso de parámetros por valor, en ese sentido la función cuadrado() recibe una copia del parámetro '''n'''. En la misma función se puede observar que se realiza un cálculo ( '''n*n''' ), sin embargo el parámetro original no sufrirá cambio alguno, esto seguirá siendo cierto aún cuando dentro de la función hubiera una instrucción parecida a '''n = n * n;''' o '''n*=n;'''. '''Parámetros por referencia''' Para mostrar un ejemplo del paso de parámetros por referencia, vamos a retomar el caso de la función cuadrado, salvo que en esta ocasión cambiaremos ligeramente la sintaxis para definir la misma. Veamos: <source lang="cpp"> // regresar el cuadrado de un número double cuadrado2(double &n) { n *= n; return n; }</source> Al poner a prueba las funciones cuadrado() y cuadrado2() se podrá verificar que la primera de estas no cambia el valor del parámetro original, mientras que la segunda sí lo hace. == Llamar a una función == para llamar a la función cuadrado() vista anteriormente, podemos emplear: <source lang="cpp"> cout << cuadrado(25); cout << cuadrado(X); R = cuadrado(X); // guardar en R el cuadrado de X </source> == Funciones void == Bajo ciertas circunstancias se deseará escribir funciones que no regresen valor alguno (esto sería algo parecido a escribir procedures en Pascal) y para ello podemos declarar a la función como '''void'''. La palabra reservada void es utilizada para declarar funciones sin valor de retorno y también para indicar que una función específica no requiere de parámetros. Por ejemplo, la función pausa() que se verá enseguida, no devolverá valor alguno y la misma no requiere de parámetros. <source lang="cpp"> // esta función requiere de la librería iostream void pausa(void) { cout << "Por favor presione <Enter> HOLA..."; cin.get(); cin.ignore(255, '\n'); // rechazar caracteres introducidos antes de <Enter> }</source>; '''Notas:''' se debe de aclarar que el uso de la palabra '''void''' dentro de los paréntesis es opcional al momento de declarar una función. Así, la función '''pausa()''' podría haberse declarado como '''void pausa()''', y la misma puede invocarse como: pausa();. == Funciones anidadas == A diferencia de '''Pascal''', el lenguaje C, C++ no permite anidar funciones, sin embargo, dentro de una función puede existir la llamada a una o más funciones declaradas previamente, que determinara en cierto punto un resultado para que sea ejecutado cuando el programador lo desee. == Funciones de tipo puntero (*) == En muchas ocasiones se desea que ciertas funciones regresen una referencia o puntero hacia un tipo (sea este estructurado o no) específico de dato en lugar de un valor específico. En tales casos, la función se deberá declarar como para que regrese un puntero. Por ejemplo, supongamos que deseamos crear una función para convertir un número entero en notación decimal a una cadena de caracteres en forma de números binarios, luego, la función mencionada podría escribirse para que reciba el número entero como parámetro y regrese un puntero a una cadena de caracteres conteniendo la conversión. Para ser más puntuales, vamos a escribir un programa en donde se verá la función '''binstr()''', y cuyo objetivo será precisamente convertir números decimales en cadenas binarias. <div style="background:#FFFFBB; padding:16px; border-color:#0000FF; border-style:"solid"> Nota: observe que en la sintaxis para declarar funciones tipo puntero se debe de poner el símbolo '''*''' después del tipo y antes del nombre de la función que se está declarando. Esto se puede ver en el programa, ya que la función binstr se declara como: '''char *binstr(unsigned int);'''</div> <source lang="cpp"> #include <iostream> #include <cstring> using namespace std; // declaración de prototipo char *binstr(unsigned int); // punto de prueba int main() { int n = 128; cout << "decimal = " << n << ", binario = " << binstr(n) << endl; cin.get(); } // definición de función binstr() // nota: esta funcion requiere de la librería estándar string char *binstr(unsigned int n) { static char buffer[65]; int i = 0; strcpy(buffer, "0"); if (n > 0) { while (n > 0) { buffer[i] = ( n & 1 ) + '0'; i++; n >>= 1; } buffer[i] = '\0'; strrev(buffer); } // fin (n > 0) return buffer; } </source> == Variables estáticas y automáticas == Dentro de una función, las variables y/o constantes pueden ser declaradas como: '''auto''' (por omisión) o como '''static'''. Si una variable dentro de una función es declarada como estática significa que la misma retendrá su valor entre las llamadas a la función. Por otro lado, la variables automáticas pierden su valor entre las llamadas. En el programa anterior puede verse que el arreglo de caracteres (buffer[65]) se ha declarado como estático para garantizar que dicho buffer retenga los datos aún después de que la función termine. En el mismo ejemplo, si el buffer no se declara como estático, el contenido del mismo podría ser destruido al salir de la función y los resultados obtenidos podrían ser no deseados. == Parámetros constantes == Los parámetros usados por una función pueden declararse como constantes ( '''const''' ) al momento de la declaración de la función. Un parámetro que ha sido declarado como constante significa que la función no podrá cambiar el valor del mismo ( sin importar si dicho parámetro se recibe por valor o por referencia ). Ejemplo: <pre>int funcionX( const int n ); void printstr( const char *str ); </pre> == Parámetros con valor por defecto == Los parámetros usados por una función pueden declararse con un valor por defecto. Un parámetro que ha sido declarado con valor por defecto es opcional a la hora de hacer la llamada a la función. Ejemplo: Dada la función: <pre>void saludo( char* mensaje = "Hola Copa America 2015" );</pre> la misma puede ser invocada como: <pre>saludo(); // sin parámetro saludo("Sea usted bienvenido a C++"); // con parámetro </pre> Para ver un ejemplo más, vamos a considerar el caso de la función '''binstr()''' del programa funciones01. Ahora, vamos modificar dicha función, salvo que esta ocasión nos interesa que la misma sirva para convertir números decimales en cadenas numéricas y cuya base de conversión sea pasada como parámetro. Es decir, la función de la que estamos hablando podrá convertir números decimales a: binario, octal, decimal, hexadecimal, etc.; y la única condición será que la base indicada esté entre el 2 y el 36, inclusive. '''Nota:''' Ya que la función servirá para convertir números a cualquier representación la nombraremos como '''numstr()''' en lugar de binstr(). Si la función es invocada sin el parámetro base regresará una cadena de dígitos decimales. <source lang="cpp"> #include <iostream> #include <cstdlib> using namespace std; // declaración de prototipo char *numstr(unsigned int, const int base = 10); // punto de prueba int main() { int n = 128; cout << "decimal = " << n << ", binario = " << numstr(n, 2) << endl; cout << "decimal = " << n << ", octal.. = " << numstr(n, 8) << endl; cin.get(); } // definición de función numstr() // nota: esta funcion requiere de la librería stdlib.h char *numstr(unsigned int n, const int base) { static char buffer[65]; itoa(n, buffer, base); return buffer; }</source> == Parámetros de tipo puntero == Anteriormente se mencionó que en C++ los parámetros a una función pueden pasarse por valor o por referencia, al respecto, podemos agregar que los parámetros también pueden pasarse como punteros. El paso de parámetros de punteros es bastante parecido al paso de parámetros por referencia, salvo que el proceso de los datos dentro de la función es diferente. Por ejemplo, las funciones: <source lang="cpp">void referencia( int &X ) { X = 100; } void puntero( int *X ) { *X = 100; }</source>ambas reciben un puntero o referencia a un objeto de tipo entero, por lo tanto cualquiera de las funciones del ejemplo puede cambiar el valor de la variable entera apuntada por '''X''', la diferencia radica en la forma en que cada una de las mismas lleva cabo la tarea. Si en la función '''puntero()''' en lugar de usar '''*X = 100;''' se usara '''X = 100;''' se le asignaría 100 al puntero X, más no al objeto apuntado por X, y esto podría ser la causa de que el programa se terminara de manera abrupta. == Parámetros estructurados == Al igual que cualquier otro tipo los parámetros de tipo estructurado pueden pasarse por valor o por referencia, sin embargo, podría ser que si una estructura es pasada por valor el compilador mostrara una advertencia ( warning ) indicando que se pasado por valor una estructura, puesto que el paso de estructuras por valor es permitido usted puede ignorar la advertencia, pero lo mejor es pasar estructuras por referencia. Si una estructura es pasada por valor y si esta es muy grande podría ser que se agotara la memoria en el segmento de pila ( Stack Segment ), aparte de que la llamada a la función sería más lenta. Para ver un ejemplo, consideremos el caso del siguiente tipo estructurado: <source lang="cpp"> struct empleado { char nombre[32]; int edad; char sexo; }; </source> Ahora, pensemos que deseamos escribir una función para imprimir variables del tipo '''empleado'''. Así, la función puede escribirse de las tres maneras siguientes: <source lang="cpp"> void ImprimeEmpleadoV( empleado e) { cout << "Nombre: " << e.nombre << endl; cout << "Edad: " << e.edad << endl; cout << "Sexo: " << e.sexo << endl; } // Parametro empleado pasado por referencia void ImprimeEmpleadoR( empleado &e ) { cout << "Nombre: " << e.nombre << endl; cout << "Edad: " << e.edad << endl; cout << "Sexo: " << e.sexo << endl; } // Parametro empleado pasado como puntero void ImprimeEmpleadoP( empleado *e ) { cout << "Nombre: " << e->nombre << endl; cout << "Edad: " << e->edad << endl; cout << "Sexo: " << e->sexo << endl; }</source> == Funciones sobrecargadas == C++, a diferencia del C estándar, permite declarar funciones con el mismo nombre y a esto se conoce como '''sobrecarga de funciones'''. Las funciones sobrecargadas pueden coincidir en tipo, pero al menos uno de sus parámetros tiene que ser diferente. En todo caso, si usted trata de declarar funciones sobrecargadas que coincidan en tipo y número de parámetros el compilador no se lo permitirá. Para poner un ejemplo vamos a considerar el caso de dos funciones cuyo nombre será '''divide''', ambas regresarán el cociente de dos números, salvo que una de ellas operará sobre números enteros y la otra lo hará sobre números reales ( de punto flotante ). <div style="background:#FFFF88; border-style:solid; border-color:blue; padding:8px"> '''Nota:''' cuando en los programas se hace una llamada a una función sobrecargada, el compilador determina a cual de las funciones invocar en base al tipo y número de parámetros pasados a la función. </div> <source lang="cpp"> #include <iostream> #include <cstdlib> using namespace std; // divide enteros int divide(int a, int b) { cout << "división entera" << endl; return ( (b != 0) ? a/b : 0); } // divide reales double divide(double a, double b) { cout << "división real" << endl; return ( (b != 0) ? a/b : 0); } // punto de prueba int main() { cout << divide(10, 3) << endl; cout << divide(10.0, 3.0) << endl; cin.get(); } </source> == Número variable de parámetros == En C,C++ se pueden crear funciones que operen sobre una lista variable de parámetros, es decir, en donde el número de parámetros es indeterminado. En esta sección se mostrará un ejemplo de la manera en que podemos crear funciones para manejar tales asuntos, y para ello haremos uso de tres macros soportadas por C++: # '''va_list''' puntero de argumentos # '''va_start''' inicializar puntero de argumentos # '''va_end''' liberar puntero de argumentos La sintaxis que usaremos para declarar funciones con lista de parámetros variables es: <pre>1) tipo nombrefuncion(...) 2) tipo nombrefuncion(int num, ...)</pre> donde: # '''tipo''' es el tipo regresado por la función # '''nombrefuncion''' es el nombre de la función # '''int num''' es el número de parámetros que la función procesará # '''...''' esta notación se emplea para indicar que el número de parámetros es variable '''Nota:''' observe que la primera forma de declaración es realmente variable el número de parámetros a procesar y en estos casos se debe establecer el mecanismo para determinar cuando se ha procesado el último de los argumentos, en el segundo tipo de declaración el número total de parámetros a procesar es igual al valor del parámetro '''num'''. En el siguiente programa, por ejemplo, se define una función ( printstr ) que despliega una lista variable de cadenas de caracteres. <source lang="cpp"> #include <iostream> #include <cstdarg> // despliega una lista de cadenas, la ultima debe ser NULL void printstr(...) { va_list ap; char *arg; va_start(ap, 0); while ( (arg = va_arg(ap, char*) ) != NULL) { cout << arg; } va_end(ap); } int main() { printstr("Hola, ", "Esta es\n", "una prueba\n", NULL); cin.get(); return 0; }</source> En el programa que se listará en seguida, se define la función '''suma()''', misma que operará sobre listas de números enteros, la función devolverá la suma de dichos números. <source lang="cpp"> #include <iostream>//entrada y salida #include <cstdarg> using namespace std; // Esta función opera sobre una lista variable de números enteros int suma( int num, ... ) { int total = 0; va_list argptr; va_start( argptr, num ); while( num > 0 ) { total += va_arg( argptr, int ); num--; } va_end( argptr ); return( total ); } int main() { cout << suma(4, 100, 200, 300, 400) << endl; cin.get(); return 0; }</source> </div> {| align="center" cellpadding="16" |- | font color="blue" | ← [[Programación en C++/Estructuras|Estructuras]] | [[Programación en C++/Funciones#Funciones|Arriba]] | font color="blue" | [[Programación en C++/Streams|Streams]] → |} {{AutoCat}} 2oj9yem9hfd9kpvrdu35t3nxms8mwh7 Programación en C++/Estructuras 0 12427 427923 426166 2026-07-16T04:26:12Z Mazbel 57931 actualización 427923 wikitext text/x-wiki {| align="center" cellpadding="16" |- | font color="blue" | ← [[Programación en C++/Iteraciones y decisiones|Iteraciones y decisiones]] | font color="blue" | [[Programación en C++/Funciones|Funciones]] → |} = Estructuras de datos = <div style="text-align:justify; padding:40px; background:#FFFFEE"> Las estructuras de datos se emplean con el objetivo principal de organizar los datos contenidos dentro de la memoria del ordenador. Así, nuestra primera experiencia con estructuras comienza desde el momento mismo en que usamos en nuestros programas variables de tipos primitivos (char, short, int, float, etc). A la memoria del ordenador se le puede considerar como un gran bloque compuesto por una serie de '''BYTES''' dispuestos secuencialmente uno detrás de otro. por ejemplo, si un ordenador posee una memoria de 128MB (128 megas) entonces se le puede leer o escribir desde el BYTE 0 hasta el BYTE 128MB - 1 ( 0000000H .. 7FFFFFFH ) La idea de ver la memoria como un serie de bytes es buena, sin embargo no es suficiente ya que en la misma podemos guardar números, cadenas de caracteres, funciones, objetos, etc. de tal manera que surge la necesidad de establecer los mecanismos adecuados para dar cuenta de la forma, tamaño y objetivo de los datos almacenados. Según el tipo de microprocesador, estos tienen la capacidad para manipular o direccionar estructuras compuestas por uno, dos, cuatro, etc, bytes; de donde se derivan los tipos que comunmente se conocen como: BYTE, WORD, DWORD, QWORD y TWORD. La estructura mínima de información manipulable en un sistema de computación es el '''BIT''' el cual se agrupa normalmente en bloques de 8 para formar un '''BYTE'''. Cabe mencionar que los BITS no son direccionables directamente, sino a través de compuertas AND, OR, NOT, XOR, las cuales en C y C++ se escriben como &, |, ~ y ^, conocidos como "Bitwise operators" u "Operadores de manipulación de bits". En C,C++ existe una serie de estructuras básicas o tipos primitivos, los cuales pueden ser usados por el programador para declarar variables, y también son el fundamento sobre el cual se crean estructuras complejas. El tamaño de los tipos primitivos no es estándar ya que los mismos dependen de factores tales como: * Tipo del microprocesador * El compilador Sin embargo, en la actualidad, la mayoria de compiladores de C y C++ soportan los siguientes tipos con la longitud indicada: == Estructuras básicas en C, C++ == {| width="384" border="1" cellpadding="3" |+ Tipos primitivos |- ! Nombre común ! Nombre C ! Longitud ! Procesador 64 bits |- | BYTE || char || 8 bits || 8 bits |- | WORD || short || 16 bits || 16 bits |- | DWORD || int || 32 bits || 32 bits |- | DWORD || long || 32 bits || 64 bits |- | DWORD || float || 32 bits || 32 bits |- | QWORD || double || 64 bits || 64 bits |- | TWORD || long double || 80 bits || 128 bits |} '''Nota:''' en el lenguaje C,C++ existe el operador '''sizeof()''', con el cual se puede obtener el tamaño (número de bytes) ocupados por un tipo específico. Por ejemplo, '''sizeof(int)''' regresa el número de bytes ocupados por los datos de tipo '''int'''. === Variables === '''En C, C++ la sintaxis para declarar variables es:''' <code>tipo id1 [, id2 ...] ;</code> donde, '''tipo''' se refiere a uno de los tipos mostrados en la tabla anterior; '''id1''' es el nombre con el cual se identificará a la variable. Observe que si se quiere declarar más de una variable en una línea de instrucción, las mismas deben separarse por medio de una coma. Ejemplos: <source lang="cpp"> char c; // La variable c es una variable char int i; // La variable i es una variable int float f; // La variable f es una variable float int x,y,z; // Las variables x,y,z son todas variables int, y declaradas a la vez </source> De acuerdo con la tabla anterior y según las instrucciones anteriores, con la primera, o sea ( char c;), se le está indicando al ordenador que reserve en la memoria un espacio de tipo char (8 bits) y que el mismo será identificado bajo el nombre de '''c'''. La segunda instrucción ( int i;) le indica al ordenador que reserve en la memoria un espacio de tipo int (16 bits) y que el mismo será identificado bajo el nombre de '''i'''. Luego, la instrucción ( float f;) le indica al ordenador que reserve en la memoria un espacio de tipo float (32 bits) y que el mismo será identificado bajo el nombre de '''f'''. Por último, se le indica al compilador que reserve espacio para otras tres variables enteras identificadas como: x, y, z. Así, se puede dar cuenta cómo los tipos primitivos sirven con el propósito de estructurar los datos dentro de la memoria y con la idea de referirnos a los mismos mediante nombres usamos identificadores de variables. . == Matrices o Arreglos == Una Matriz (en inglés, array, también denominado arreglo) es una estructura usada para agrupar bajo un mismo nombre listas de datos de un mismo tipo. El tipo de matriz puede ser cualquiera, sin embargo cada componente tiene que ser del mismo tipo. En C estándar solamente da soporte para matrices estáticas, mientras que con C++ se pueden crear matrices dinámicas pudiendo usar la librería estándar de plantillas (STL). === Matrices estáticas === Una matriz estática es una estructura cuyo tamaño es determinado en tiempo de compilación, es decir, una vez establecido el tamaño de la matriz ésta no podrá cambiarse durante el tiempo de ejecución. En C, C++ para declarar un arreglo estático de datos se emplea la sintaxis: <code>tipo identificador[ [tamaño] ] [ = { lista de inicialización } ] ;</code> donde, * '''tipo''' se refiere al tipo de datos que contendrá la matriz. El tipo puede ser cualquiera de los tipos estándar (char, int, float, etc.) o un tipo definido por el usuario. Es más, el tipo de la matriz puede ser de una estructura creada con: struct, union y class. * <b>identificador se refiere al nombre que se le dará a la matriz.</b> * '''tamaño''' es opcional e indica el número de elementos que contendrá la matriz. Si una matriz se declara sin tamaño, la misma no podrá contener elemento alguno a menos que en la declaración se emplee una lista de inicialización. * '''lista de inicialización''' es opcional y se usa para establecer valores para cada uno de los componentes de la matriz. Si la matriz es declarada con un tamaño especifíco, el número de valores inicializados no podrá ser mayor a dicho tamaño. Ejemplos: <source lang="cpp">int intA[5]; long longA[5] = { 1, 2, 3, 4, 5 }; char charA[] = { 'a', 'b', 'c' };</source> === Acceso a los miembros de una matriz de datos: === En orden de acceder a los miembros de una matriz se debe indicar el nombre de la matriz seguido de dos corchetes, dentro de los cuales se debe especificar el índice del elemento deseado. Se debe aclarar que los índices son números o expresiones enteras y que en C, C++ estos tienen un rango permitido de 0 a T-1 ( T = tamaño de la matriz ). Ejemplos: dadas las matrices intA, charA, longA ( ejemplo anterior ) <source lang="cpp"> intA[0] = 100; // establece el valor del elemento 0 de intA a 100. charA[3] = 'O'; // establece el valor del elemento 3 de charA a 'O'. cout << longA[0]; // muestra por pantalla el elemento 0 de longA, que es longA[0]. </source> === Matrices dinámicas === Una matriz dinámica es una estructura compleja y, ya que C estándar no da el soporte para operar con estos tipos de estructuras, le corresponde al programador crear los algoritmos necesarios para su implementación. Crear lista dinámicas de datos en C estándar no es una tarea para programadores inexpertos, ya que para lograr tal objetivo se necesita tener conocimentos solidos acerca de los punteros y el comportamiento de los mismos. Los usuarios de C++ pueden auxiliarse de la librería estándar de plantillas, conocidas por sus siglas en ingles como STL. == Estructuras compuestas (struct, union, class) == Con base en los tipos básicos mostrados arriba, se pueden crear nuevos tipos con estructuras compuestas por uno o más de uno de los tipos mencionados. En C, C++ en orden de crear nuevas estructuras se emplean la palabras reservadas '''struct''', '''union''' y '''class'''. * '''struct:''' esta orden se emplea para agrupar variables de tipos iguales o diferentes en un solo registro, con la misma se pueden crear estructuras anónimas, estructuras con nombre, y un tipo especial de estructura conocida como bit-fields ( banderas o campos de bits ). * '''union:''' una union es similar a una struct, salvo que en una estructura creada con union los campos o variables comparten una dirección de almacenamiento común. * '''class:''' una clase es una estructura en donde se agrupan variables y funciones, la misma es usada en Programación Orientada al Objeto. Las clases no son soportadas por el C estándar. Nota: tanto las estructuras como las uniones y las clases pueden ser anónimas, pero lo más recomendable es darle a las mismas un nombre. Si una estructura, union o clase posee nombre, esta pueden ser empleadas para declarar variables de la misma y, lo más importante, puede ser usada para el paso de parámetros a funciones. ---- <font color="#FF0000" size="+1">Sintaxis general: struct</font> <source lang="cpp"> struct [ <nombre tipo de estructura > ] { [ <tipo> <nombre-variable[, nombre-variable, ...]> ] ; [ <tipo> <nombre-variable[, nombre-variable, ...]> ] ; ... } [ <variables de estructura> ] ; </source> '''Nota:''' recuerde que lo que se muestra entre corchetes es opcional. <font color="#FF0000" size="+1">struct: Sintaxis</font> ( variación uno, estructura anónima ) De acuerdo con la sintaxis general de la orden struct es posible crear estructuras de datos anónimas. Solamente hay que tener en cuenta que en una declaración anónima se debe definir al menos una variable al final de la declaración. Por ejemplo, con el siguiente fragmento de código: <source lang="cpp">struct { int a, b; } p1;</source> se declara y define la variable estructurada '''p1''', misma que se compone por los miembros ''a'' y ''b''; ambos del tipo '''int'''. Ahora bien, la sintaxis mostrada arriba no es tan común ni conveniente, ya que con la misma solamente se esta creando una variable estructurada pero no un nuevo tipo. Es decir, si desearamos tener otra variable que tuviera las mismas caracteristicas que posee la variable '''p1''', necesitariamos escribir exactamente la misma instrucción, salvo que cambiando el nombre de la variable. Por ejemplo: <source lang="cpp">struct { int a, b; } p2;</source> Por supuesto, en una misma línea de instrucción podemos definir más de una variable. Ejemplo: <source lang="cpp">struct { int a, b; } p1, p2;</source> Entonces, para crear nuevos tipos con '''struct''' deberemos de modificar la sintaxis mostrada en los ejemplos anteriores. <font color="#FF0000" size="+1">Sintaxis: struct</font> ( variación dos, estructura con nombre ) Observe que, la sintaxis para declarar estructuras con nombre es bastante parecida a la sintaxis para declarar estructuras anónimas; salvo que en una declaración de estructura con nombre se debe especificar el nombre deseado para la misma. Además, en una declaración de estructura con nombre la o las variables definidas al final de la misma son opcionales. Ejemplos: <source lang="cpp">struct pareja { int a, b; } p1;</source> En el fragmento de código anterior se declara la estructura identificada como pareja, misma que se compone de los miembros a y b, ambos de tipo int. En el mismo ejemplo, se define la variable p1; la cual es una variable estructurada de tipo pareja. Una vez que una estructura con nombre ha sido creada, la misma puede ser usada para declarar cualquier número de variables. Por ejemplo, en el siguiente fragmento de código se crea la estructura tiempo compuesta por los miembros hora, minuto y segundo; todos del tipo int. En el mismo ejemplo, se declaran las variables t1 y t2. <source lang="cpp"> /* declaración de estructura tiempo */ struct tiempo { int hora, minuto, segundo; }; /* declaración de variables de tipo tiempo */ struct tiempo t1, t2; </source> Nota: en C++ puede obviarse la palabra struct a la hora de declarar variables. Así, en C++ la línea de instrución '''struct tiempo t1, t2;''' ( del ejemplo anterior) puede escibirse como: '''tiempo t1, t2;''' === Acceso a los miembros de una estructura === ---- En orden de poder leer o escribir uno de los miembros de una variable estructurada, se debe usar el operador de acceso ( . ); o sea, el nombre de la variable seguida por un punto seguido por el nombre del miembro o componente deseado de la estructura. Por ejemplo, para acceder a los miembros de la variable t1 (mostrada arriba) podemos hacerlo de la siguiente manera: <source lang="cpp"> t1.hora = 12; t1.minuto = 0; t1.segundo = 0; printf ("%i\n", t1.hora); cout << t1.minuto << endl; </source> === Estructuras anidadas === ---- Los miembros de una estructura pueden ser ellos mismos, otra estructura previamente identificada, o bien una estructura anónima. Por ejemplo, en el siguiente fragmento de código, se crean las estructuras pareja y pareja2. Obsérvese cómo dentro de los miembros de pareja2, se declara el miembro X, que a su vez es una estructura del tipo pareja. Luego, las variables declaradas a raíz de la estructura pareja2 poseerán los miembros variables ''a'' y ''b'' heredados de pareja, y ''c''. <source lang="cpp"> struct pareja { int a, b ; }; struct pareja2 { struct pareja X; int c; } P3;</source> Ahora bien, para acceder a los miembros de una estructura dentro de otra estructura se emplea el mismo mecanismo de acceso (el punto). Por ejemplo, para desplegar el miembro '''a''' de la variable '''P3''' declarada en el ejemplo anterior, lo haremos más o menos así: <source lang="cpp">printf( "%i\n", P3.X.a );</source> === Herencia === ---- El término herencia se usa con gran frecuencia en Programación Orientada a Objetos, y se le relaciona principalmente con las clases. Sin embargo, la herencia está presente siempre y cuando una estructura "struct", "union" o "class" posea a otra estructura. En ese sentido, en C++ se presentan dos tipos de herencia: * herencia por agregación o composición. * herencia por extensión. Por ejemplo, en la definición de las estructuras '''pareja''' y '''pareja2''' del ejemplo anterior, se dice que pareja2 hereda por composición todos los miembros de pareja. Ahora, en el siguiente ejemplo se usa la sintaxis para que la estructura pareja2 herede por extensión los miembros de pareja: <source lang="cpp">// solo C++ struct pareja { int a, b ; }; struct pareja2 : pareja { int c; } P3;</source> Con esta forma de herencia, la estructura '''pareja2''' hereda de '''pareja''' los miembros '''a''' y '''b''', y además agrega un miembro '''c'''. Y a diferencia del ejemplo anterior, para acceder a alguno de sus miembros heredados, basta con utilizar el mecanismo de acceso (el punto). <source lang="cpp">// solo C++ cout << P3.a << P3.b ; </source> === Estructura de campos de bits === ---- :Un campo de bit es un elemento de una estructura definido en terminos de bits. Usando un tipo especial de definición de '''struct''', se pueden declarar elementos de estructura con rangos de 1 a 16 de largo (dependiendo de la arquitectura de la PC y del compilador, el rango para una estructura de campos de bits puede ser de 1 a 16, 1 a 32, 1 a 64). Antes de ver un ejemplo del uso de struct para crear estructuras de campos de bits, consideremos el caso en donde se tiene una variable del tipo short (16 bits) y que para la misma se desea que los bits tengan significados específicos. Digamos que el primer bit servirá para controlar alguna condición; los siguientes cuatro bits, o sea del segundo al quinto bit, controlarán otra condición; el bit 6 tendrá otra función; y el resto, o sea del séptimo al decimosexto bit se emplearán para controlar otra condición. De tal manera que si queremos, por ejemplo, saber si el primer bit de la variable tiene almacenado un 1 o un 0, podemos emplear la siguiente sintaxis: <source lang="cpp"> int X = 123; int r = X & 1; </source> la cosa parece sencilla, pero ahora consideremos el caso en el cual deseamos saber cual es el valor contenido por el grupo de bits ( segundo al quinto ), entonces nos daremos cuenta que no basta con una prueba mediante AND ( X & 1 ), sino que hay que realizar otros pasos. Precisamente, para problemas como el planteado arriba es por los que los lenguajes C y C++ soportan las estructuras de campos de bits. Por ejemplo, la estructura <source lang="cpp"> struct campo_de_bit { int bit_1 : 1; int bits_2_a_5 : 4; int bit_6 : 1; int bits_7_a_16 : 10; } bit_var; </source> :corresponde a la siguiente colección de campos bits: <br /><br /><center>[[Archivo:struct01.gif]]</center><br /><br /> El mecanismo de estructuras de campos de bits soportado por C,C++ es una herramienta útil y poderosa, sobre todo en programación de bajo nivel; ya que mediante el mismo es posible aislar y dar nombres a todos y cada uno de los bits de un dato, y también crear en un mismo campo grupos de bits (como se mostró arriba). Ahora bien, no hay que olvidar que la estructura mínima de información en un sistema de memoria de un PC es el '''bit''', y que para aislar a cada uno de estos se puede emplear el operador AND ( &, en C ), pero mediante el mecanismo mencionado el compilador genera los algoritmos necesarios para llevar a cabo el aislamiento de los bits. Por ejemplo, para escribir y leer bit identificado como '''bit_1''' de la variable '''bit_var''' del ejemplo anterior, podemos emplear las siguientes instrucciones: <source lang="cpp">bit_var.bit_1 = 1; printf("%i\n", bit_var.bit_1 );</source> Nota: acerca de las estructuras de campos de bits hay que aclarar que, aunque cada uno de los campos de la estructura pueden declararse como enteros con signo o enteros sin signo, la misma no tendrá una longitud mayor a un entero largo. ---- == union: Sintaxis general == <source lang="cpp"> union [ <nombre tipo de union > ] { <tipo> <lista de variables>; } [ <variables de union> ] ; </source> * De la misma manera que con la orden struct, con la orden union se pueden crear estructuras con nombre y estructuras sin nombre. * El mecanismo de acceso a los miembros de una union es igual al mecanismo de acceso a los miembros de una struct. * Los miembros de una union comparten un espacio de almacenamiento común. * En una union, el compilador reserva el espacio de almacenamiento para la misma de acuerdo con el tipo de la variable de mayor tamaño. <font color="#FF0000" size="+1">Ejemplo: union anónima</font> <source lang="cpp">union { short a; long b; } u1;</source> En el ejemplo anterior se declara la variable '''u1''', la cual es una estructura tipo union. El espacio de almacenamiento para la variable '''a''' es compartido por la variable '''b''', en consecuencia, al escribir sobre cualquiera de estas dos variables se altera el contenido de ambas. <font color="#FF0000" size="+1">Ejemplo: union con nombre</font> <source lang="cpp">union ux { short a; long b; } u1;</source> En el ejemplo anterior se declara la variable u1, la cual es una estructura tipo union. El espacio de almacenamiento para la variable '''a''' es compartido por la variable '''b'''. Es decir, el compilador reservará espacio en la memoria para la variable de mayor tamaño (que para éste caso es '''b''' ). Ahora bién, suponiendo que en su equipo el tipo '''long''' ocupa 32 bits y que el tipo '''short''' ocupa 16 bits, entonces la variable '''a''' ocupará solamente los 16 bits menos significativos, mientras que la variable '''b''' ocupará todo el espacio, o sea los 32 bits; Observe que en la sintaxis se ha especificado el nombre ux, mismo que puede ser empleado para declarar cualquier número de variables de la union. Por ejemplo, a continuación se declaran las variables u2 y u3 del tipo union ux creado en el ejemplo anterior. <source lang="cpp">union ux u2, u3;</source> ---- == class: sintaxis == <source lang="cpp"> <classkey> <classname> [<:baselist>] { <member list> } [lista de variables] ;</source> * <classkey> es una de las palabras "class", "struct", o "union". * <baselist> lista de clas(es) base de donde se deriva esta clase. <baselist> es opcional. * <member list> declara los datos miembros y funciones miembros de la clase. * [lista de variables] esta entrada es opcional y se usa para instanciar variables u objetos de esta clase. Nota: Dentro de una clase, * los datos son llamados "datos miembros" * las funciones son llamadas "funciones miembros". * El mecanismo para acceder a los miembros de una '''class''' es igual que aquel utilizado para acceder a los miembros de una '''struct''' Las clases son algo así como "super" estructuras capaces de agrupar no solo datos miembros sino también funciones miembros. En el lenguaje común a los datos miembros de una clase se les conoce como '''atributos'''; mientras que a las funciones miembros de una clase se les llama '''métodos'''. Normalmente, los métodos se emplean para leer o escribir los atributos. Es decir, la norma general es no permitir el acceso directo a los atributos de una clase, con la idea de aumentar la seguridad de los datos. En seguida se mostrará el código para crear la clase Pareja, misma que poseerá los atributos a y b, y los métodos setA(), setB(); getA(), getB(), y mostrar(); <source lang="cpp"> class Pareja { int a, b; public: void setA(int n) { a = n; } void setB(int n) { b = n; } int getA() { return a; } int getB() { return b; } void mostrar() { cout << "a = " << a << "; b = " << b << endl; } } p1; </source> '''Nota: '''por omisión, los miembros de una clase son privados, lo cual significa que los objetos instanciados de dicha clase no tendrán acceso a los mismos. Así, en el ejemplo anterior se está creando la clase Pareja, y al mismo tiempo el objeto p1. Luego, para leer o escribir los atributos de p1 se debe hacer a traves de los métodos definidos con tal objetivo. Por ejemplo, con el siguiente fragmento de código se establecen respectivamente a 100 y a 200 los atributos a y b; y posteriormente se despliegan por medio del método mostrar(). <source lang="cpp"> p1.setA(100); p1.setB(200); p1.mostrar();</source> == struct vs. class == Esta sección no pretende enseñar que el uso de la palabra '''struct''' es lo mismo que usar la palabra '''class'''. Sin embargo, como ya se mencionó en una sección anterior a esta, las estructuras ('''struct''') pueden extenderse de otras y heredar todos los miembros de la estructura base. Otro punto que se demostrará aquí es el hecho de que las estructuras en C++ (no en C estándar) pueden contener miembros funciones. Por supuesto, el compilador trata a una '''struct''' de una forma diferente que a una '''class'''. Entre algunas de las diferencias que se pueden mencionar respecto a las estructuras contra las clases son: * Los miembros de una '''struct''' son públicos por defecto, mientras que los miembros de una '''class''' son privados por defecto. * Los parámetros-argumentos '''struct''' se pasan normalmente por copia, los parámetros-argumentos '''class''' se pasan normalmente por referencia. <source lang="cpp"> // Este programa ha sido probado en Dev-C++, Borland C++ y Code::Blocks #include <iostream> using namespace std; // estructura tipo clase base struct Par { int a, b; // constructor base Par() { a = b = 0; } // destructor base ~Par() { cout << "hecho..." << endl; } void setA(int n) { a = n; } void setB(int n) { b = n; } void mostrar() { cout << "a = " << a << ", b = " << b << "; suma = " << a+b << endl; } }; // estructura tipo clase hija // ParHijo es una extensión de Par, y por lo tanto hereda los miembros de Par struct ParHijo : Par { // constructor del hijo ParHijo(int a, int b) { this->a = a; this->b = b; } }; // prueba void test00() { ParHijo p1(100, 200); // p1 es instancia de ParHijo p1.mostrar(); // se envía mensaje al método mostrar() de p1 } // funcion principal int main() { test00(); cin.get(); return 0; }</source> </div> {| align="center" cellpadding="16" |- | font color="blue" | ← [[Programación en C++/Iteraciones y decisiones|Iteraciones y decisiones]] | [[Programación en C++/Estructuras#Estructuras de datos|Arriba]] | font color="blue" | [[Programación en C++/Funciones|Funciones]] → |} {{AutoCat}} 3vrkwmuze3idy7ujbof7l0m4cezidbn Wikilibros:Libros destacados 4 13161 427883 427473 2026-07-15T21:23:00Z Antimundo 74354 Retirar listado por ser completamente erróneo, llevar una década sin actualizarse, y cuyo propósito es una duplicidad de otros listados iguales. Sólo aporta confusión y una complejidad de mantenimiento innecesaria. 427883 wikitext text/x-wiki {{Proyecto|libros destacados}} Con el fin de mostrar en la portada aquellos libros clasificados con [[Archivo:100%.svg]] se ha diseñado esta página para que se coloquen aquí los libros que se consideren destacados, considerándose así aquellos que: #Están correctamente nombrados. <small>Ver [[Wikilibros:Política de nombrado|Política de nombrado]]</small> #No tienen lagunas de contenido y están divididos en subpáginas. #Tienen una presentación agradable al lector. #Tienen (o se está elaborando) su [[Wikilibros:Versión para imprimir|Versión para imprimir]] :''...o cualquiera se anime a hacerlo.'' ==Libros destacados que aparecen en la portada== {{TOC|right}} Estos libros cambiarán cada mes, y se escogerán con una [[Wikilibros Discusión:Libros destacados|votación]] * {{Libro+|Ingeniería del conocimiento}} * {{Libro+|Ingeniería de aguas residuales}} * {{Libro+|Quenya}} * {{Libro+|Esperanto}} * {{Libro+|Billar}} * {{Libro+|Baloncesto}} * {{Libro+|Lanzamiento de martillo}} * {{Libro+|Mantenimiento y Montaje de Equipos Informáticos}} [[Categoría:Wikilibros|Libros destacados]] [[en:Wikibooks:Featured books]] [[fr:Wikilivres:Vitrine]] [[it:Wikibooks:Vetrina]] [[de:Wikibooks:Empfehlenswerte Bücher]] [[pt:Wikilivros:Melhores do Wikilivros]] [[vi:Wikibooks:Các sách chọn lọc]] 9ona36hwvnfz8kjokgrud4p2yczai9m 427884 427883 2026-07-15T21:38:07Z Antimundo 74354 /* Libros destacados que aparecen en la portada */ El listado que aparecía estaba muy desactualizado, actualizo al listado actual. Aunque esto debería transcluirse para no tener que actualizarse a mano... 427884 wikitext text/x-wiki {{Proyecto|libros destacados}} Con el fin de mostrar en la portada aquellos libros clasificados con [[Archivo:100%.svg]] se ha diseñado esta página para que se coloquen aquí los libros que se consideren destacados, considerándose así aquellos que: #Están correctamente nombrados. <small>Ver [[Wikilibros:Política de nombrado|Política de nombrado]]</small> #No tienen lagunas de contenido y están divididos en subpáginas. #Tienen una presentación agradable al lector. #Tienen (o se está elaborando) su [[Wikilibros:Versión para imprimir|Versión para imprimir]] :''...o cualquiera se anime a hacerlo.'' ==Libros destacados que aparecen en la portada== Estos libros cambiarán cada mes, y se escogerán con una [[Wikilibros Discusión:Libros destacados|votación]] # [[Billar]] # [[Ingeniería del conocimiento]] # [[Teoría intuitiva de conjuntos]] # [[Ingeniería de aguas residuales]] # [[Administración de tiempo]] # [[Esperanto]] # [[Quenya]] # [[Manual wiki]] # [[Ingeniería de aguas residuales]] # [[Tutorial de bots]] # [[Programación en Ada]] # [[Catálogo de obras de Erminio Blotta]] [[Categoría:Wikilibros|Libros destacados]] [[en:Wikibooks:Featured books]] [[fr:Wikilivres:Vitrine]] [[it:Wikibooks:Vetrina]] [[de:Wikibooks:Empfehlenswerte Bücher]] [[pt:Wikilivros:Melhores do Wikilivros]] [[vi:Wikibooks:Các sách chọn lọc]] dbilx04mnrwh4yok8iq4gc8mwqq72nd 427885 427884 2026-07-15T21:42:04Z Antimundo 74354 /* Libros destacados que aparecen en la portada */ No tiene sentido poner que se escogerán por una votación, cuando en los casi 20 años que lleva existiendo esta página, esto nunca se ha votado... 427885 wikitext text/x-wiki {{Proyecto|libros destacados}} Con el fin de mostrar en la portada aquellos libros clasificados con [[Archivo:100%.svg]] se ha diseñado esta página para que se coloquen aquí los libros que se consideren destacados, considerándose así aquellos que: #Están correctamente nombrados. <small>Ver [[Wikilibros:Política de nombrado|Política de nombrado]]</small> #No tienen lagunas de contenido y están divididos en subpáginas. #Tienen una presentación agradable al lector. #Tienen (o se está elaborando) su [[Wikilibros:Versión para imprimir|Versión para imprimir]] :''...o cualquiera se anime a hacerlo.'' ==Libros destacados que aparecen en la portada== Estos libros cambiarán cada mes. # [[Billar]] # [[Ingeniería del conocimiento]] # [[Teoría intuitiva de conjuntos]] # [[Ingeniería de aguas residuales]] # [[Administración de tiempo]] # [[Esperanto]] # [[Quenya]] # [[Manual wiki]] # [[Ingeniería de aguas residuales]] # [[Tutorial de bots]] # [[Programación en Ada]] # [[Catálogo de obras de Erminio Blotta]] [[Categoría:Wikilibros|Libros destacados]] [[en:Wikibooks:Featured books]] [[fr:Wikilivres:Vitrine]] [[it:Wikibooks:Vetrina]] [[de:Wikibooks:Empfehlenswerte Bücher]] [[pt:Wikilivros:Melhores do Wikilivros]] [[vi:Wikibooks:Các sách chọn lọc]] 4wd8s4up9s303fu7n77hvkxmdhcm7lm Física/Cinemática 0 14393 427970 418435 2026-07-16T06:09:35Z Mazbel 57931 categorización 427970 wikitext text/x-wiki *[[Física/Cinemática/Introducción|Introducción a Cinemática]] *[[Física/Cinemática/Conceptos|Conceptos de Cinemática]] *[[Física/Cinemática/Velocidad|Concepto de Velocidad]] *[[Física/Cinemática/Aceleración|Concepto de Aceleración]] *[[Física/Cinemática/Movimiento Circular|Movimiento Circular]] *[[Física/Cinemática/Coordenadas polares|Coordenadas Polares]] *[[Física/Cinemática/Cinemática del punto|Cinemática de la partícula]] <noinclude> *[[Cinemática del sólido rígido]] <noinclude>{{Renglóndoble|[[Física/Cinemática/Texto completo|'''Texto completo de este capítulo''']]|Esta página contiene todo el texto del capítulo de '''«Cinemática»'''}} {{AutoCat}} 8vsqbsa3liq8c7qwt2sywj1k0afg2ht Física/Preliminares 0 15794 427951 413308 2026-07-16T05:49:25Z Mazbel 57931 actualización 427951 wikitext text/x-wiki *[[Física/Preliminares/Introducción|Introducción a Física]] *[[Física/Preliminares/Historia|Historia de la Física]] *[[Física/Definición de la Física|Definición de Física]] *[[Física/Concepto de Modelo|Concepto de Modelo]] *[[Física/División de la Física|División de la Física]] *[[Física/Análisis dimensional|Análisis dimensional]] *[[Física/Unidades y medidas|Unidades y medidas]] *[[Física/Sistema Internacional de Unidades (SI)|Sistema Internacional de Unidades (SI)]] *[[Física/Sistema Cegesimal o CGS|Sistema Cegesimal o CGS]] *[[Física/Sistema MKS|Sistema MKS]] *[[Física/Preliminares/Espacios Vectoriales|Espacios Vectoriales]] *[[Física/Sistema Usual en Estados Unidos|Sistema usual en Estados Unidos]] *[[Física/Conversión de unidades|Conversión de unidades en el sistema internacional]] *[[Física/Rotación|Rotación alrededor de un eje fijo]] <noinclude>*[[Física/Introducción a la Física/Ejercicios|Ejercicios]] *[[Física/Apéndices|Apéndices]] <noinclude> {{AutoCat}} auvdpbgisi1mip1jjf887gf8sros86k Programación en C++/Iteraciones y decisiones 0 16471 427929 427338 2026-07-16T04:32:22Z Mazbel 57931 actualización 427929 wikitext text/x-wiki <table align="center" cellpadding="12"> <tr> <td font color="blue">← [[Programación en C++/Lo más básico|Lo más básico]]</td> <td font color="blue">[[Programación en C++/Estructuras|Estructuras]] →</td> </tr></table> == Sentencias de decisión == <div style="padding:40px; background:#fffeee; text-align:justify;"> [[Archivo:desicion.png|left|frame|Estructura de control IF]] '''DEFINICIÓN''' Las sentencias de decisión o también llamadas de CONTROL DE FLUJO son estructuras de control que realizan una pregunta la cual retorna verdadero o falso (evalúa una condicion) y selecciona la siguiente instrucción a ejecutar dependiendo la respuesta o resultado. <br clear="all"> ---- [[Archivo:Crystal_Clear_app_kedit.png|80px|left|thumb|Crystal_Clear_app_kedit.png]] En algún momento dentro de nuestros algoritmos, es preciso cambiar el flujo de ejecución de las instrucciones, es decir, el orden en que las instrucciones son ejecutadas. Muchas de las veces tenemos que tomar una decisión en cuanto a que se debe ejecutar basándonos en una respuesta de verdadero o falso (condicion).<br clear='all'> La ejecución de las instrucciones incluyendo una estructura de control como el condicional funcionan de esta manera: * Las instrucciones comienzan a ejecutarse de forma secuencial (en orden) y cuando se llega a una estructura condicional, la cual esta asociada a una condicion, se decide que camino tomar dependiendo siempre del resultado de la condicion siendo esta falsa o verdadera. * Cuando se termina de ejecutar este bloque de instrucciones se reanuda la ejecución en la instrucción siguiente a la de la condicional. == Sentencia if == ---- La instrucción '''if''' es, por excelencia, la más utilizada para construir estructuras de control de flujo. '''SINTAXIS''' '''Primera Forma''' Ahora bien, la sintaxis utilizada en la programación de C++ es la siguiente: ---- if (condicion) { Set de instrucciones } ---- siendo "condicion" el lugar donde se pondrá la condición que se tiene que cumplir para que sea verdadera la sentencia y así proceder a realizar el "set de instrucciones" o código contenido dentro de la sentencia. '''Segunda Forma ''' Ahora veremos la misma sintaxis pero ahora le añadiremos la parte "Falsa" de la sentencia: ---- if (condicion) { Set de instrucciones //PARTE VERDADERA } else { Set de instrucciones 2 //Parte FALSA } ---- La forma mostrada anteriormente muestra la union de la parte "VERDADERA" con la nueva secuencia la cual es la parte "FALSA" de la sentencia de decision "IF" en la cual esta compuesta por el: else { Set de instrucciones 2 //Parte FALSA } la palabra "else" o "De lo contrario" indica al lenguaje que de lo contrario al no ser verdadera o no se cumpla la parte verdadera entonces realizara el "set de instrucciones 2". '''EJEMPLOS DE SENTENCIAS IF...''' Ejemplo 1: if(numero == 0) //La condicion indica que tiene que ser igual a Cero { cout<<"El Numero Ingresado es Igual a Cero"; } Ejemplo 2: if(numero > 0) // la condicion indica que tiene que ser mayor a Cero { cout<<"El Numero Ingresado es Mayor a Cero"; } Ejemplo 3: if(numero < 0) // la condicion indica que tiene que ser menor a Cero { cout<<"El Numero Ingresado es Menor a Cero"; } Ahora uniremos todos estos ejemplos para formar un solo programa mediante la utilización de la sentencia "Else" e introduciremos el hecho de que se puede escribir en este espacio una sentencia if ya que podemos ingresar cualquier tipo de código dentro de la sentencia escrita después de un Else. Ejemplo 4: if(numero == 0) //La condicion indica que tiene que ser igual a Cero { cout<<"El Numero Ingresado es Igual a Cero"; } else { if(numero > 0) // la condicion indica que tiene que ser mayor a Cero { cout<<"El Numero Ingresado es Mayor a Cero"; } else { if(numero < 0) // la condicion indica que tiene que ser menor a Cero { cout<<"El Numero Ingresado es Menor a Cero"; } } } === Sentencia switch === ---- '''switch''' es otra de las instrucciones que permiten la construcción de estructuras de control. A diferencia de '''if''', para controlar el flujo por medio de una sentencia '''switch''' se debe de combinar con el uso de las sentencias '''case''' y '''break'''. <blockquote>Notas: cualquier número de casos a evaluar por switch así como la sentencia '''default''' son opcionales. La sentencia '''switch''' es muy útil en los casos de presentación de menus.</blockquote> '''Sintaxis:''' <pre> switch (condición) { case primer_caso: bloque de instrucciones 1 break; case segundo_caso: bloque de instrucciones 2 break; case caso_n: bloque de instrucciones n break; default: bloque de instrucciones por defecto } </pre> '''Ejemplo 1''' <source lang="cpp"> switch (numero) { case 0: cout << "numero es cero"; } </source> '''Ejemplo 2''' <source lang="cpp"> switch (opcion) { case 0: cout << "Su opcion es cero"; break; case 1: cout << "Su opcion es uno"; break; case 2: cout << "Su opcion es dos"; } </source> '''Ejemplo 3''' <source lang="cpp"> switch (opcion) { case 1: cout << "Su opcion es 1"; break; case 2: cout << "Su opcion es 2"; break; case 3: cout << "Su opcion es 3"; break; default: cout << "Elija una opcion entre 1 y 3"; } </source> === Operador condicional ternario ?: === En C/C++, existe el operador condicional ( '''?:''' ) el cual es conocido por su estructura como '''ternario'''. El comportamiento de dicho operador es el mismo que una estructura '''if - then - else''' del lenguaje '''BASIC''' (y de la función '''IIf''' de Visual Basic). El operador condicional '''?:''' es útil para evaluar situaciones tales como: <font color="blue">Si se cumple tal condición entonces haz esto, de lo contrario haz esto otro.</font> '''Sintaxis:''' <pre> ( (condicion) ? proceso1 : proceso2 ) </pre> En donde, '''condicion''' es la expresión que se evalua, '''proceso1''' es la tarea a realizar en el caso así también se conoce caridad de que la evaluación resulte verdadera, y '''proceso2''' es la tarea a realizar en el caso de que la evaluación o negativa resulte falsa. '''Ejemplo 1''' <source lang="cpp"> int edad; cout << "Cual es tu edad: "; cin >> edad; cout << ( (edad < 18) ? "Eres joven aun" : "Ya tienes la mayoría de edad" ); </source> El ejemplo anterior podría escribirse de la siguiente manera: <source lang="cpp"> int edad; cout << "Cual es tu edad: "; cin >> edad; if (edad < 18) cout << "Eres joven aun"; else cout << "Ya tienes la mayoría de edad"; </source> '''Ejemplo 2''' Vamos a suponer que deseamos escribir una función que opere sobre dos valores numéricos y que la misma ha de regresar 1 (true) en caso de que el primer valor pasado sea igual al segundo valor; en caso contrario la función debe retornar 0 (false). <source lang="cpp"> int es_igual( int a, int b) { return ( (a == b) ? 1 : 0 ) }</source> == Sentencias de iteración == '''DEFINICIÓN''' Las Sentencias de '''Iteración''' o '''Ciclos''' son estructuras de control que repiten la ejecución de un grupo de instrucciones. Básicamente, una sentencia de iteración es una estructura de control condicional, ya que dentro de la misma se repite la ejecución de una o más instrucciones '''mientras''' que una a condición especifica se cumpla. Muchas veces tenemos que repetir un número definido o indefinido de veces un grupo de instrucciones por lo que en estos casos utilizamos este tipo de sentencias. en C++ los ciclos o bucles se construyen por medio de las sentencias '''for''', '''while''' y '''do - while'''. La sentencia '''for''' es útil para los casos en donde se conoce de antemano el número de veces que una o más sentencias han de repetirse. Por otro lado, la sentencia '''while''' es útil en aquellos casos en donde no se conoce de antemano el número de veces que una o más sentencias se tienen que repetir. === Sentencias For === <source lang="cpp"> for(contador; final; incremento) { Codigo a Repetir; } </source> donde: # contador es una variable numérica # final es la condición que se evalua para finalizar el ciclo (puede ser independiente del contador) # incremento es el valor que se suma o resta al contador Hay que tener en cuenta que el "for" evalua la condición de finalización igual que el while, es decir, mientras esta se cumpla continuaran las repeticiones. Ejemplo 1: <source lang="cpp"> for(int i=1; i<=10; i++) { cout<<"Hola Mundo"; } </source> Esto indica que el contador "i" inicia desde 1 y continuará iterando mientras i sea menor o igual a 10 ( en este caso llegará hasta 10) e "i++" realiza la sumatoria por unidad lo que hace que el '''for ''' y el contador se sumen. repitiendo 10 veces "HOLA MUNDO" en pantalla. Ejemplo 2: <source lang="cpp"> for(int i=10; i>=0; i--) { cout<<"Hola Mundo"; } </source> Este ejemplo hace lo mismo que el primero, salvo que el contador se inicializa a 10 en lugar de 1; y por ello cambia la condición que se evalua así como que el contador se decrementa en lugar de ser incrementado. La condición también puede ser independiente del contador: Ejemplo 3: <source lang="cpp"> int j = 20; for(int i=0; j>0; i++){ cout<<"Hola"<<i<<" - "<<j<<endl; j--; } </source> En este ejemplo las iteraciones continuaran mientras j sea mayor que 0, sin tener en cuenta el valor que pueda tener i. === Sentencia while === <source lang="cpp"> while(condicion) { código a Repetir } </source> donde: # condicion es la expresión a evaluar Ejemplo 1: <source lang="cpp"> int contador = 0; while(contador<=10) { contador=contador+1; cout<<"Hola Mundo"; }</source> El contador Indica que hasta que este llegue a el total de 10 entonces se detendrá y ya no se realizará el código contenido dentro de la sentencia '''while''', de lo contrario mientras el "contador" sea menor o igual a 10 entonces el código contenido se ejecutará desplegando hasta 11 veces "Hola Mundo" en pantalla. === Sentencia do - while === La sentencia '''do''' es usada generalmente en cooperación con '''while''' para garantizar que una o más instrucciones se ejecuten al menos una vez. Por ejemplo, en la siguiente construcción no se ejecuta nada dentro del ciclo '''while''', el hecho es que el ''contador'' inicialmente vale cero y la condición para que se ejecute lo que está dentro del '''while''' es "mientras el contador sea mayor que diez". Es evidente que a la primera evaluación hecha por while la condición deja de cumplirse. <source lang="cpp"> int contador = 0; while(contador > 10) { contador ++; cout<<"Hola Mundo"; }</source> Al modificar el segmento de código anterior usando '''do''' tenemos: <source lang="cpp"> int contador = 0; do { contador ++; cout<<"Hola Mundo"; } while(contador > 10); </source> Observe cómo en el caso de '''do''' la condición es evaluada al final en lugar de al principio del bloque de instrucciones y, por lo tanto, el código que le sigue al '''do''' se ejecuta al menos la primera vez. == Sentencias break y continue == En la sección ('''Sentencia switch''') vimos que la sentencia '''break''' es utilizada con el propósito de forzar un salto dentro del bloque switch hacia el final del mismo. En esta sección volveremos a ver el uso de '''break''', salvo que esta ocasión la usaremos junto con las sentecias '''for''' y la sentencia '''while'''. Además, veremos el uso de la sentencia '''continue'''. === break === La sentencia break se usa para forzar un salto hacia el final de un ciclo controlado por '''for''' o por '''while'''. '''Ejemplo:''' En el siguiente fragmento de código la sentencia break cierra el ciclo for cuando la variable ( i ) es igual a 5. La salida para el mismo será: <center>0 1 2 3 4</center> <source lang="cpp"> for (int i=0; i<10; i++) { if (i == 5) break; cout << i << " "; }</source> === continue === La sentencia continue se usa para ignorar una iteración dentro de un ciclo controlado por '''for''' o por '''while'''. '''Ejemplo:''' En el siguiente fragmento de código la sentencia continue ignora la iteración cuando la variable ( i ) es igual a 5. La salida para el mismo será: <center>0 1 2 3 4 6 7 8 9</center> <source lang="cpp"> for (int i=0; i<10; i++) { if (i == 5) continue; cout << i << " "; }</source> '''Uso de break y continue junto con while''' Los dos ejemplos anteriores se presentan en seguida, salvo que en lugar de for se hace uso de while. <blockquote>Nota: no deje de observar que la construcción del ciclo while para el caso de la sentencia continue es diferente, esto para garantizar que el ciclo no vaya a caer en una iteración infinita.</blockquote> '''break''' <source lang="cpp"> int i = 0; while (i<10) { if (i == 5) break; cout << i << " "; i++; }</source> '''continue''' <source lang="cpp"> int i = -1; while (i<10) { i++; if (i == 5) continue; cout << i << " "; }</source> </div> <table align="center" cellpadding="16"> <tr> <td font color="blue">← [[Programación en C++/Lo más básico|Lo más básico]]</td> <td font color="blue">[[#Sentencias de decisión|Arriba]]</td> <td font color="blue">[[Programación en C++/Estructuras|Estructuras]] →</td> </tr></table> {{AutoCat}} 4t7zvvmpvryaee7awpgczctp6ykr7wj Programación en C++/Funciones virtuales 0 16843 427937 411707 2026-07-16T04:35:01Z Mazbel 57931 actualización 427937 wikitext text/x-wiki Editores:<br /> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Herencia|Herencia]] | [[Programación en C++/Punteros|Punteros]] → |} == Introducción == <div style="background:#FFFFEE; padding:40px; text-align:justify"> Una de las tres mayores facetas de la programación orientada a objetos es el polimorfismo. Aplicado a C++, el término polimorfismo describe el proceso por el cual diferentes implementaciones de una función pueden ser accedidas a través del mismo nombre. Por esta razón, el polimorfismo es en ocasiones caracterizado por la frase "Un interfaz, múltiples métodos". Esto significa que cada miembro de una clase general de operaciones puede ser accedido del mismo modo, incluso cuando las acciones específicas con cada operación puedan diferir. En C++, el polimorfismo es soportado en tiempo de ejecución y en tiempo de compilación. La sobrecarga de operadores y funciones son ejemplos de polimorfismo en tiempo de compilación. Aunque la sobrecarga de operadores y funciones es muy poderosa, éstos no pueden realizar todas las tareas requeridas por un lenguaje realmente orientado a objetos. Además, C++ también permite polimorfismo en tiempo de ejecución a través del uso de clases derivadas y funciones virtuales, que son los principales temas de este capítulo. Este capítulo comienza con una corta discusión de punteros a tipos derivados, ya que éstos dan soporte al polimorfismo en tiempo de ejecución. == PUNTEROS A TIPOS DERIVADOS. == El fundamento del polimorfismo en tiempo de ejecución es el puntero hacia la clase base. Punteros a la clase base y clases derivadas están relacionados en la manera en que otros tipos de puntero no lo están. Como aprendió al principio del libro, un puntero de un tipo generalmente no puede apuntar a un objeto de otro tipo. Sin embargo, los punteros de clase base y objetos derivados son la excepción a esta regla. En C++, un puntero de la clase base podría ser usado para apuntar a un objeto de cualquier clase derivada de esa base. Por ejemplo, asumiendo que usted tiene una clase base llamada 'clase_B' y una clase llamada 'clase_D', la cual es derivada de 'clase_B'. En C++, cualquier puntero declarado como un puntero a 'clase_B' puede también ser un puntero a 'clase_D'. Entonces, dado <source lang="cpp"> clase_B *p; // puntero al objeto del tipo clase_B clase_B objB // objeto del tipo clase_B clase_D objD // objeto del tipo clase_D </source> las siguientes dos declaraciones son perfectamente validas: <source lang="cpp"> p = &objB; // p apunta a un objeto del tipo clase_B p = &objD /* p apunta a un objeto del tipo clase_D el cual es un objeto derivado de clase_B. */ </source> En este ejemplo, 'p' puede ser usado para acceder a todos los elementos de objD heredados de objB. Sin embargo elementos específicos a objD no pueden ser referenciados con 'p'. Para un ejemplo mas concreto, considere el siguiente programa, el cual define una clase llamada clase_B y una clase derivada llamada clase_D. Este programa usa una simple jerarquía para almacenar autores y títulos. <source lang="cpp"> // Usando punteros base en objetos de una clase derivada #include <iostream> #include <cstring> using namespace std; class clase_B { public: void put_autor(char *s) { strcpy(autor, s); } void mostrar_autor() { cout << autor << "\n"; } private: char autor[80]; }; class clase_D : public clase_B { public: void put_titulo(char *num) { strcpy(titulo, num); } void mostrar_titulo() { cout << "Titulo: "; cout << titulo << "\n"; } private: char titulo[80]; }; int main() { clase_B *p; clase_B objB; clase_D *dp; clase_D objD; p = &objB; // direccion la clase base // Accesar clase_B via puntero p->put_autor("Tom Clancy"); // Accesar clase_D via puntero base p = &objD; p->put_autor("William Shakespeare"); // Mostrar cada autor a traves de su propio objeto. objB.mostrar_autor(); objD.mostrar_autor(); cout << "\n"; /* Como put_titulo() y mostrar_titulo() no son parte de la clase base, ellos no son accesibles a traves del puntero base 'p' y deben ser accedidas directamente, o, como se muestra aqui, a traves de un puntero al tipo derivado. */ dp = &objD; dp->put_titulo("La Tempestad"); p->mostrar_autor(); // los dos, 'p' o 'dp' pueden ser usados aqui. dp->mostrar_titulo(); return 0; } </source> Este programa muestra lo siguiente: <pre> Tom Clancy William Shakespeare William Shakespeare Titulo: La Tempestad </pre> En este ejemplo, el puntero 'p' es definido como un puntero a clase_B. Sin embargo, este puede apuntar a un objeto de la clase derivada clase_D y puede ser usado para acceder aquellos elementos de la clase derivada que son heredados de la clase base. Pero recuerde, un puntero base no puede acceder aquellos elementos específicos de la clase derivada. De ahí el porqué de que mostrar_titulo() es accesada con el puntero dp, el cual es un puntero a la clase derivada. Si se quiere acceder a los elementos definidos en una clase derivada usando un puntero de clase base, se debe hacer un casting hacia el puntero del tipo derivado. Por ejemplo, esta linea de codigo llamara apropiadamente a la función mostrar_titulo() en objD: <source lang="cpp"> ((clase_D *)p)->mostrar_titulo(); </source> Los paréntesis externos son necesarios para asociar el cast con 'p y no con el tipo de retorno de mostrar_titulo(). Aunque no hay nada técnicamente erróneo con castear un puntero de esta manera, es probablemente mejor evitarlo, ya que este simplemente agrega confusión a sus código. ( En realidad, la mayoría de los programadores de C++ consideran esto como mala forma.) Otro punto a comprender es que, mientras un puntero base puede ser usado para apuntar a cualquier objeto derivado, no es posible hacerlo de manera inversa. Esto es, no puede acceder a un objeto de tipo base usando un puntero a una clase derivada. Un puntero es incrementado y decrementado relativamente a su tipo base. Por lo tanto, cuando un puntero de la clase base está apuntado a un objeto derivado, incrementarlo o decrementarlo no hará que apunte al siguiente objeto de la clase derivada. En vez de eso, apuntara a ( lo que piense que es ) el próximo objeto de la clase base. Por lo tanto, debería considerar invalido incrementar o decrementar un puntero de clase base cuando esta apuntando a un objeto derivado. El hecho de que un puntero a un tipo base pueda ser usado para apuntar a cualquier objeto derivado de la base es extremadamente importante, y fundamental para C++. Como aprenderá muy pronto, esta flexibilidad es crucial para la manera en que C++ implementa su polimorfismo en tiempo de ejecución. === REFERENCIAS A TIPOS DERIVADOS === Similar a la acción de punteros ya descritas, una referencia a la clase base puede ser usada para referirse a un objeto de un tipo derivado. La más común aplicación de esto es encontrada en los parámetros de la funciones. Un parámetro de referencia de la clase base puede recibir objetos de la clase base así como también otro tipo derivado de esa misma base. === FUNCIONES VIRTUALES === El polimorfismo en tiempo de ejecución es logrado por una combinación de dos características: 'Herencia y funciones virtuales". Aprendió sobre la herencia en el capítulo precedente. Aqui, aprendera sobre función virtual. Una función virtual es una función que es declarada como 'virtual' en una clase base y es redefinida en una o más clases derivadas. Además, cada clase derivada puede tener su propia versión de la función virtual. Lo que hace interesantes a las funciones virtuales es que sucede cuando una es llamada a través de un puntero de clase base ( o referencia ). En esta situación, C++ determina a cual version de la función llamar basándose en el tipo de objeto apuntado por el puntero. Y, esta determinación es hecha en 'tiempo de ejecución'. Además, cuando diferentes objetos son apuntados, diferentes versiones de la función virtual son ejecutadas. En otras palabras es el tipo de objeto al que está siendo apuntado ( no el tipo del puntero ) lo que determina cuál versión de la función virtual será ejecutada. Además, si la clase base contiene una función virtual, y si dos o mas diferentes clases son derivadas de esa clase base, entonces cuando tipos diferentes de objetos están siendo apuntados a través de un puntero de clase base, diferentes versiones de la función virtual son ejecutadas. Lo mismo ocurre cuando se usa una referencia a la clase base. Se declara una función como virtual dentro de la clase base precediendo su declaración con la palabra clave virtual. Cuando una función virtual es redefinida por una clase derivada, la palabra clave 'virtual' no necesita ser repetida ( aunque no es un error hacerlo ). Una clase que incluya una función virtual es llamada una 'clase polimórfica'. Este término también aplica a una clase que hereda una clase base conteniendo una función virtual. Examine este corto programa, el cual demuestra el uso de funciones virtuales: <source lang="cpp"> // Un ejemplo corto que usa funciones virtuales. #include <iostream> using namespace std; class base { public: virtual void quien() {cout << "Base" << endl;} // especificar una clase virtual }; class primera_d : public base { public: // redefinir quien() relativa a primera_d void quien() {cout << "Primera derivacion" << endl;} }; class segunda_d : public base { public: // redefinir quien relativa a segunda_d void quien() {cout << "Segunda derivacion" << endl;} }; int main() { base obj_base; base *p; primera_d obj_primera; segunda_d obj_segundo; p = &obj_base; p->quien(); // acceder a quien() en base p = &obj_primera; p->quien(); // acceder a quien() en primera_d p = &obj_segundo; p->quien(); // acceder a quien() en segunda_d return 0; } </source> Este programa produce la siguiente salida: <pre> Base Primera derivacion Segunda derivacion </pre> Examinemos el programa en detalle para comprender como funciona: En 'base', la función 'quien()' es declarada como 'virtual'. Esto significa que la función puede ser redefinida en una clase derivada. Dentro de ambas 'primera_d' y 'segunda_d', 'quien()' es redefinida relativa a cada clase. Dentro de main(), cuatro variables son declaradas: 'obj_base', el cual es un objeto del tipo 'base'; 'p' el cual un un puntero a objetos del tipo 'base'; 'obj_primera' y 'obj_segunda', que son objetos de dos clases derivadas. A continuación 'p' es asignada con la dirección de 'obj_base', y la función quien() es llamada. Como quien() es declarada como virtual, C++ determina en tiempo de ejecución, cual version de quien() es referenciada por el tipo del objeto apuntado por 'p'. En este caso, 'p' apunta a un objeto del tipo 'base', así que es la versión de 'quien()' declarada en 'base' la que es ejecutada. A continuación, se le asigna a 'p' la dirección de 'obj_primera'. Recuerde que un puntero de la clase base puede referirse a un objeto de cualquier clase derivadas. Ahora, cuando quien() es llamada, C++ nuevamente comprueba para ver que tipo de objeto es apuntado por 'p' y basado en su tipo, determina cual versión de quien() llamar. Como 'p' apunta a un objeto del tipo 'obj_primera', esa versión de quien() es usada. De ese mismo modo, cuando 'p' es asignada con la dirección de 'obj_segunda', la version de quien() declarada en 'segunda_d' es ejecutada. RECUERDE: "Es determinado en tiempo de ejecución cual version de una función virtual en realidad es llamada. Además, esta determinación es basada solamente en el tipo del objeto que está siendo apuntado por un puntero de clase base." Una función virtual puede ser llamada normalmente, con la sintaxis del operador estándar de 'objeto.' Esto quiere decir que en el ejemplo precedente, no sería incorrecto sintácticamente acceder a quien() usando esta declaración: <source lang="cpp"> obj_primera.quien(); </source> Sin embargo, llamar a una función virtual de esta manera ignora sus atributos polimórficos. Es solo cuando una función virtual es accesada por un puntero de clase base que el polimorfismo en tiempo de ejecución es logrado. A primera vista, la redefinición de una función virtual en una clase derivada parece ser una forma especial de sobrecarga de función. Sin embargo, este no es el caso. De hecho, los dos procesos son fundamentalmente diferentes. Primero, una función sobrecargada debe diferir en su tipo y/o número de parámetros, mientras que una función virtual redefinida debe tener exactamente el mismo tipo y número de parámetros. De hecho, los prototipos para una función virtual y sus redefiniciones debe ser exactamente los mismos. Si los prototipos difieren, entonces la función simplemente se considera sobrecargada, y su naturaleza virtual se pierde. Otra restricción es que una función virtual debe ser un miembro, no una función 'friend', de la clase para la cual es definida. Sin embargo, una función virtual puede ser una función 'friend' de otra clase. También, es permisible para funciones destructores ser virtuales, pero esto no es así para los constructores. <pre> "Cuando una funcion virtual es redefinida en una clase derivada, se dice que es una funcion 'overriden' ( redefinida )" </pre> Por las restricciones y diferencias entre sobrecargar funciones normales y redefinir funciones virtuales, el término 'overriding' es usado para describir la redefinición de una función virtual. === LAS FUNCIONES VIRTUALES SON HEREDADAS === Una vez que una función es declarada como virtual, esta se mantiene virtual sin importar cuantas capas de clases derivadas esta debe perdurar. Por ejemplo, si 'segunda_d' es derivada de 'primera_d' en vez de 'base', como se muestra en el próximo ejemplo, entonces quien() es aun virtual y la versión apropiada es aun correctamente seleccionada. <source lang="cpp"> // Derivar de primera_d, no de base. class segunda_d : public primera_d { public: void quien() { // definir 'quien()' relativa a 'segunda_d' cout << "Segunda derivacion\n"; } }; </source> Cuando una clase derivada no redefine una función virtual, entonces la función, como se define en la clase base, es usada. Por ejemplo intente esta versión del programa precedente en el cual 'segunda_d' no redefine 'quien()': <source lang="cpp"> #include <iostream> using namespace std; class base { public: virtual void quien() { cout << "Base\n"; } }; class primera_d : public base { public: void quien() { cout << "Primera derivacion\n"; } }; class segunda_d : public base { public: // quien() no definida }; int main() { base obj_base; base *p; primera_d obj_primera; segunda_d obj_segunda; p = &obj_base; p->quien(); // acceder a quien() en 'base' p = &obj_primera; p->quien(); // acceder a quien() en 'primera_d' p = &obj_segunda; p->quien(); /* acceder a quien() en 'base' porque segunda_d no la redefine */ return 0; } </source> El programa ahora muestra la salida siguiente: <pre> Base Primera derivacion Base </pre> Como confirma la salida, como 'quien()' no ha sido redefinida por 'segunda_d', entonces 'p' apunta a 'obj_segunda', es la versión de 'quien()' en 'base' la que es ejecutada. Mantenga en mente que las características heredadas de 'virtual' son jerárquicas. Por tanto,, si el ejemplo precedente es modificado para que 'segunda_d' sea derivada de 'primera_d' en vez de 'base', entonces cuando quien() es referenciada relativa a un objeto del tipo 'segunda_d', es la versión de 'quien()' declarada dentro de primera_d' la que es llamada ya que es la clase mas cercana a 'segunda_d', no 'quien()' dentro de base. El siguiente programa demuestra esta jerarquía. <source lang="cpp"> #include <iostream> using namespace std; class base { public: virtual void quien() { cout << "Base\n"; } }; class primera_d : public base { public: void quien() { cout << "Primera derivacion\n"; } }; // segunda_d ahora hereda primera_d -- no base. class segunda_d : public primera_d { // quien() no es definida. }; int main() { base obj_base; base *p; primera_d obj_primera; segunda_d obj_segunda; p = &obj_base; p->quien(); // acceder a 'quien()' en 'base'. p = &obj_primera; p->quien(); // acceder a 'quien()' en 'primera'. p = &obj_segunda; p->quien(); /* acceder a 'quien()' en 'primera_d' porque 'segunda_d' no la redefine */ return 0; } </source> Este programa produce la siguiente salida: <pre> Base Primera derivacion Primera derivacion </pre> Como puede ver, 'segunda_d' ahora usa la versión 'quien()' de 'primera_d' porque esa versión es la mas cercana en la cadena de herencia. === POR QUÉ FUNCIONES VIRTUALES === Como se declaraba en el inicio de este capítulo, las funciones virtuales en combinación con tipos derivados le permiten a C++ soportar polimorfismo en tiempo de ejecución. El polimorfismo es esencial para la programación orientada a objetos por una razón: Esta permite a una clase generalizada especificar aquellas funciones que serán comunes a todas las derivadas de esa clase, mientras que permite a una clase derivada definir la implementación específica de algunas o todas de esas funciones. A veces esta idea es expresada como: La clase base dicta la 'interface' general que cualquier objeto derivado de esa clase tendrá, pero permite a la clase derivada definir el método actual usado para implementar esa interfaz. De ahí que la frase "una interface múltiples métodos" sea usada a menudo para describir el polimorfismo. Parte del truco de aplicar el polimorfismo de una manera satisfactoria es comprender que la clase base y derivada forman una jerarquía, la cual se mueve de mayor a menor generalización (base a derivada). Diseñada correctamente, la clase base provee todos los elementos que una clase derivada puede usar directamente. También define cuales funciones la clase derivada debe implementar por su cuenta. Esto permite a la clase derivada la flexibilidad para definir sus propios métodos, y aun mantener un interface consistente. Eso es, como la forma de la interface es definida por la clase base, cualquier clase derivada compartirá esa interface común. Además, el uso de funciones virtuales hace posible para la clase base definir interfaces genéricas que serán usada por todas las clases derivadas. En este punto, usted debe preguntarse a si mismo porque una consistente interface con múltiples implementaciones es importante. La respuesta, nuevamente, no lleva a la fuerza central manejadora detrás de la programación orientada a objetos: Esta ayuda al programador a manejar programas de complejidad creciente. Por ejemplo, si usted desarrolla su programa correctamente, entonces usted sabrá que todos los objetos que usted derive de una clase base son accedidos en la misma manera general, incluso si las acciones específicas varían de una clase derivada a la próxima. Esto significa que usted necesita solo recordar una interface, en vez de varias. También, su clase derivada es libre de usar cualquiera o toda la funcionalidad provista por la clase base. No necesita reinventa esos elementos. Por tanto, la separación de interface e implementación permite la creación de librerías de clases, las cuales pueden ser provistas por un tercero. Si estas librerías son implementadas correctamente, ellas proveerán una interface común que usted puede usar para derivar clases suyas propias que cumplan sus necesidades específicas. Por ejemplo, tanto como las Microsoft Foundation Classes ( MFC ) y la librería de clases .NET Framework Windows Forms soporta programación en Windows. Usando estas clases, su programa puede heredar mucha de la funcionalidad requerida por un programa de Windows. Usted necesita agregar solo las características únicas a su aplicación. Este es un mayor beneficio cuando se programa en sistemas complejos. === UNA SIMPLE APLICACIÓN DE LAS FUNCIONES VIRTUALES === Para tener una idea del poder del concepto "una interface, múltiples métodos", examinemos el siguiente programa. Este crea una clase base llamada 'figura'. Esta clase almacena las dimensiones de varios objetos de 2-dimensiones y calcula sus áreas. La función 'set_dim()' es una función miembro estandar porque esta operacion sera comun a las clases derivadas. Sin embargo, 'mostrar_area()' es declarada como virtual porque el método de computar el área de cada objeto puede variar. El programa usa 'figura' para derivar dos clases específicas llamadas 'rectangulo' y 'triangulo'. <source lang="cpp"> #include <iostream> using namespace std; class figura { protected: double x, y; public: void set_dim(double i, double j) { x = i; y = j; } virtual void mostrar_area() { cout << "No hay calculo de area definido "; cout << " para esta clase.\n"; } }; class triangulo : public figura { public: void mostrar_area() { cout << "Triangulo con alto "; cout << x << " y base " << y; cout << " tiene un area de "; cout << x * 0.5 * y << ".\n"; } }; class rectangulo : public figura { public: void mostrar_area() { cout << "Rectangulo con dimensiones "; cout << x << " x " << y; cout << " tiene un area de "; cout << x * y << ".\n"; } }; int main() { figura *p; // crear un puntero al tipo base. triangulo t; // crear objetos de tipos derivados rectangulo r; p = &t; p->set_dim(10.0, 5.0); p->mostrar_area(); p = &r; p->set_dim(10.0, 5.0); p->mostrar_area(); return 0; } </source> La salida es mostrada aquí: <pre> Triangulo con alto 10 y base 5 tiene un area de 25. Rectangulo con dimensiones 10 x 5 tiene un area de 50. </pre> En el programa, nótese que ambas interfaces, 'rectangulo' y 'triangulo', son la misma, incluso ambas proveen sus propios métodos para computar el área de cada uno de sus objetos. Dada la declaración para 'figura', es posible derivar una clase llamada 'circulo' que computará el área de un círculo, dado en radio? La respuesta es 'Si'. Todo lo que necesita hacer es crear un nuevo tipo derivado que calcule el área de un círculo. El poder de las funciones virtuales está basado en el hecho de que usted puede fácilmente derivar un nuevo tipo que mantendrá un interface común con otros objetos relaciones. Por ejemplo, esta es una manera de hacerlo: <source lang="cpp"> class circulo : public figura { public: void mostrar_area() { cout << "Circulo con radio "; cout << x; cout << " tiene un area de "; cout << 3.14 * x * x; } }; </source> Antes de intentar usar 'circulo', vea de cerca la definición de 'mostrar_area()'. Note que esta usa solo el valor de x, el cual se asume que almacena el radio. ( Recuerde, el área de un círculo es calculada usando la fórmula 'PI*R a la 2'.) Sin embargo, la función 'set_dim()' como se define en 'figura', asume que serán pasados dos valores, no solo uno. Como 'círculo' no requiere este segundo valor, que tipo de acción podemos tomar? Hay dos manera de resolver este problema. La primera y peor, usted simplemente llama a 'set_dim()' usando un valor falso como segundo parámetro cuando use un objeto 'circulo'. Esto tiene la desventaja de ser chapucero, en conjunto requiriendo que recuerde una excepción especial, la cual viola la filosofía "una interface, muchos métodos". Una mejor manera de resolver este problema es pasarle al parámetro 'y' dentro de 'set_dim()' un valor por defecto. Entonces, cuando se llame a 'set_dim()' para un círculo, necesita especificar solo el radio. Cuando llame a 'set_dim()' para un triángulo o un rectángulo, especificará ambos valores. El programa expandido, el cual usa este método, es mostrado aquí: <source lang="cpp"> #include <iostream> using namespace std; class figura { protected: double x, y; public: void set_dim(double i, double j=0) { x = i; y = j; } virtual void mostrar_area() { cout << "No hay calculo de area definido "; cout << " para esta clase.\n"; } }; class triangulo : public figura { public: void mostrar_area() { cout << "Triangulo con alto "; cout << x << " y base " << y; cout << " tiene un area de "; cout << x * 0.5 * y << ".\n"; } }; class rectangulo : public figura { public: void mostrar_area() { cout << "Rectangulo con dimensiones "; cout << x << " x " << y; cout << " tiene un area de "; cout << x * y << ".\n"; }; }; class circulo : public figura { public: void mostrar_area() { cout << "Circulo con radio "; cout << x; cout << " tiene un area de "; cout << 3.14 * x * x; } }; int main() { figura *p; // crear un puntero al tipo base triangulo t; // crear objetos de tipos derivada rectangulo r; circulo c; p = &t; p->set_dim(10.0, 5.0); p->mostrar_area(); p = &r; p->set_dim(10.0, 5.0); p->mostrar_area(); p = &c; p->set_dim(9.0); p->mostrar_area(); return 0; } </source> Este programa produce la siguiente salida: <pre> Triangulo con alto 10 y base 5 tiene un area de 25. Rectangulo con dimensiones 10 x 5 tiene un area de 50. Circulo con radio 9 tiene un area de 254.34 </pre> TIP: Mientras que las funciones virtuales son sintácticamente faciles de comprender, su verdadero poder no puede ser demostrado en ejemplos cortos. En general, el polimorfismo logra su gran fuerza en sistemas largos y complejos. Si continua usando C++, las oportunidades de aplicar funciones virtuales se presentarán por sí mismas. === FUNCIONES VIRTUALES PURAS Y CLASES ABSTRACTAS === Como se ha visto, cuando una función virtual que no es redefinida en una clase derivada es llamada por un objeto de esa clase derivada, la versión de la función como se ha definido en la clase base es utilizada. Sin embargo, en muchas circunstancias, no habrá una declaración con significado en una función virtual dentro de la clase base. Por ejemplo, en la clase base 'figura' usada en el ejemplo anterior, la definición de 'mostrar_area()' es simplemente un sustituto sintético. No computará ni mostrará el area de ningún tipo de objeto. Como verá cuando cree sus propias librerías de clases no es poco común para una función virtual tener una definición sin significado en el contexto de su clase base. Cuando esta situación ocurre, hay dos manera en que puede manejarla. Una manera, como se muestra en el ejemplo, es simplemente hacer que la función reporte un mensaje de advertencia. Aunque esto puede ser útil en ocasiones, no es el apropiado en muchas circunstancias. Por ejemplo, puede haber funciones virtuales que simplemente deben ser definidas por la clase derivada para que la clase derivada tenga algún significado. Considere la clase 'triangulo'. Esta no tendría significado si 'mostrar_area()' no se encuentra definida. En este caso, usted desea algun metodo para asegurarse de que una clase derivada, de hecho, defina todas las funciones necesarias. En C++, la solución a este problema es la 'función virtual pura.' Una 'función virtual pura' es una función declarada en una clase base que no tiene definición relativa a la base. Como resultado, cualquier tipo derivado debe definir su propia versión -- esta simplemente no puede usar la versión definida en la base. Para declarar una función virtual pura use esta forma general: <pre> virtual 'tipo' 'nombre_de_funcion'(lista_de_parametros) = 0; </pre> Aquí, 'tipo' es el tipo de retorno de la función y 'nombre_de_funcion' es el nombre de la función. Es el = 0 que designa la función virtual como pura. Por ejemplo, la siguiente versión de 'figura', 'mostrar_area()' es una función virtual pura. <source lang="cpp"> class figura { double x, y; public: void set_dim(double i, double j=0) { x = i; y = j; } virtual void mostrar_area() = 0; // pura }; </source> Declarando una función virtual como pura, se fuerza a cualquier clase derivada a definir su propia implementación. Si una clase falla en hacerlo, el compilador reporta un error. Por ejemplo, intente compilar esta versión modificando del programa de figuras, en el cual la definición de mostrar_area() ha sido removida de la clase 'círculo': <source lang="cpp"> /* Este programa no compilara porque la clase circulo no redefinio mostrar_area() */ #include <iostream> using namespace std; class figura { protected: double x, y; public: void set_dim(double i, double j=0) { x = i; y = j; } virtual void mostrar_area() = 0; // pura }; class triangulo : public figura { public: void mostrar_area() { cout << "Triangulo con alto "; cout << x << " y base " << y; cout << " tiene un area de "; cout << x * 0.5 * y << ".\n"; } }; class rectangulo : public figura { public: void mostrar_area() { cout << "Rectangulo con dimensiones "; cout << x << " x " << y; cout << " tiene un area de "; cout << x * y << ".\n"; }; }; class circulo : public figura { // la no definicion de mostrar_area() causara un error }; int main() { figura *p; // crear un puntero al tipo base triangulo t; // crear objetos de tipos derivada rectangulo r; circulo c; // ilegal -- no puedo crearla! p = &t; p->set_dim(10.0, 5.0); p->mostrar_area(); p = &r; p->set_dim(10.0, 5.0); p->mostrar_area(); return 0; } </source> Si una clase tiene al menos una función virtual pura, entonces esa clase se dice que es 'abstracta'. Una clase abstracta tiene una característica importante: No puede haber objetos de esa clase. En vez de eso, una clase abstracta debe ser usada solo como una base que otras clases heredarán. La razón por la cual una clase abstracta no puede ser usada para declarar un objeto es, por supuesto, que una o más de sus funciones no tienen definición. Sin embargo, incluso si la clase base es abstracta, la puede usar aún para declarar punteros o referencias, los cuales son necesarios para soportar el polimorfismo en tiempo de ejecución. === ENLACE TEMPRANO VS TARDÍO === Existen dos términos que son comúnmente usado cuando se discute sobre programación orientada a objetos: "Enlace temprano y Enlace Tardío" ( del inglés "early binding and late binding" ). Relativo a C++, estos términos se refieren a eventos que ocurren en tiempo de compilacion y eventos que ocurren en tiempo de ejecucion, respectivamente. Enlace temprano significa que una llamada a una función es resuelta en tiempo de compilación. Esto es, toda la información necesaria para llamar a una función es conocida cuando el programa es compilado. Ejemplos de enlace temprano incluyen llamadas a funciones estándar, llamadas a funciones sobrecargadas y llamadas a funciones de operadores sobrecargados. La principal ventaja del enlace temprano es la eficiencia -- es rápido, y a menudo requiere menos memoria. Su desventaja es falta de flexibilidad. Enlace tardío significa que una llamada a la función es resuelta en tiempo de ejecución. Más precisamente a que la llamada a la función es determinada "al vuelo" mientras el programa se ejecuta. Enlace tardío es logrado en C++ a través del uso de funciones virtuales y tipos derivados. La ventaja del enlace tardío es que permite gran flexibilidad. Puede ser usada para soportar una interface común, mientras que se permite a varios objetos utilizar esa interface para definir sus propias implementaciones. Por tanto, puede ser usada para ayudar a crear librerías de clases, las cuales pueden ser reusadas y extendidas. Su desventaja, sin embargo, es una ligera pérdida de velocidad de ejecución. === POLIMORFISMO Y EL PURISTA === A través de este libro, y en este capítulo específicamente, se ha hecho una distinción entre polimorfismo de tiempo de ejecución y en tiempo de compilación. Características polimórficas en tiempo de compilacion son sobrecarga de operadores y funciones. El polimorfismo en tiempo de ejecución es logrado con funciones virtuales. La definición más común de polimorfismo es, "una interface, múltiples métodos", y todas estas características se ajustan a este significado. Sin embargo, aún existe controversia con el uso del término "polimorfismo". Algunos puristas POO han insistido que el término debe usarse para referirse solo a eventos que ocurren en tiempo de ejecución. También, ellos podrían decir que solo las funciones virtuales soportan el polimorfismo. Parte de este punto de vista está fundado en el hecho de que los primeros lenguajes de computación polimórficos fueran intérpretes (en el que todos los eventos ocurren en tiempo de ejecución). La llegada de lenguajes polimórficos compilador expandió el concepto de polimorfismo. Sin embargo, aún algunos aseguran que el término polimorfismo debería referirse solo a eventos en tiempo de ejecución. La mayoría de los programadores de C++ no están de acuerdo con este punto de vista y establecen que el término aplica en ambos casos a características en tiempo de compilación y en tiempo de ejecución. Sin embargo, no se sorprenda si algun dia, alguien va en contra de usted sobre el uso de este término! Si su programa usa enlace tardío o temprano depende de lo que el programa este diseñado para hacer. ( En realidad, la mayoría los programas grandes usan una combinación de los dos.) Enlace tardío es una de las características más poderosas de c++. Sin embargo, el precio que usted paga por este poder es que su programa se ejecutará ligeramente más lento. Por lo tanto, es mejor usar enlace tardío solo cuando este le agregue significado a la estructura y manejabilidad de su programa. ( En esencia, use -- pero no abuse -- el poder.) Mantenga en mente, sin embargo, que la pérdida de desempeño causada por enlace tardío es muy ligera, así pues cuando la situación requiera enlace tardío, usted definitivamente debería usarlo. </div> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Herencia|Herencia]] | [[#Introducción|Introducción]] | [[Programación en C++/Punteros|Punteros]] → |} {{AutoCat}} fioblxjqni39yw0qann1uoi2hp12yd9 Programación en C++/Objetos y Clases 0 18940 427934 384631 2026-07-16T04:33:49Z Mazbel 57931 actualización 427934 wikitext text/x-wiki {| align="center" cellpadding="12" |- | ← [[Programación en C++/Desarrollo Orientado a Objetos|Desarrollo Orientado a Objetos]] | [[Programación en C++/Sobrecarga de Operadores|Sobrecarga de Operadores]] → |} == Clases y Objetos == <div style="text-align:justify; padding:40px; background:#FFFFEE"> Este capítulo introduce a las clases en C++. La clase es la fundación de C++ para el soporte de la programación orientada a objetos, y se encuentra en el núcleo de muchas de sus más avanzadas características. La clase es la unidad básica de C++ de la encapsulación y esta provee el mecanismo por el cual los objetos son creados. == Fundamentos de Clases == Vamos a comenzar definiendo los términos de clase y objeto. Una clase define un nuevo tipo de dato que se especifica en la forma de un objeto. Una clase incluye los datos y el código que operará sobre esos datos. Además, una clase enlaza datos y código. C++ usa una especificación de una clase para construir objetos. Los objetos son instancias de una clase. Además, una clase es esencialmente una serie de planes que especifican cómo construir un objeto. Es importante tener claro esto: Una clase es una abstracción lógica. No es sino hasta que un objeto de esa clase sea creado que la representación física de la clase existe en la memoria. Cuando se define una clase, se declaran los datos que ésta contiene y el código que opera en esos datos. Aunque clases muy simples pueden contener sólo código o sólo datos, la mayoría de las clases contienen ambos. En conjunto, los datos se almacenan en las variables y el código en las funciones. Colectivamente, las funciones y variables que constituyen una clase son llamados 'miembros' de la clase. Una variable declarada dentro de una clase es llamada 'variable miembro', y una función declarada en una clase es llamada 'función miembro'. En ocasiones el término 'variable de instancia' es usado en lugar de variable miembro. Una clase es creada con la palabra clave '''class'''. La declaración de una clase es similar sintácticamente a una estructura (y tienen muchísimo que ver). Aquí tenemos un ejemplo. La siguiente clase define un tipo llamado '''CRender''', el cual es usado para implementar operaciones de renderizado en este caso. <pre> // Esto define la clase CRender class CRender { char buffer[256]; public: void m_Renderizar(); }; </pre> Veamos más de cerca esta declaración de la clase. Todos los miembros de CRender son declarados dentro de la declaración 'class'. La variables miembro de CRender es buffer. La función miembro es m_Renderizar. '''NOTA:''' Por defecto los miembros de una clase son privados. Una clase puede contener tanto miembros privados como públicos. Por defecto, todos los elementos definidos en una clase son privados. Por ejemplo la variable buffer es privada. Esto significa que sólo pueden acceder a ella otros miembros de la clase CRender, cosa que no podrá hacer ninguna otra parte del programa. Es una forma de lograr la encapsulación: se puede controlar el acceso a ciertos elementos de datos manteniéndolos privados. Aunque no hay ninguna en este ejemplo, se pueden definir funciones privadas, las cuales pueden ser llamadas solamente por otros miembros de la clase. Para hacer pública una parte de la clase (accesible a otras partes del programa), se debe declarar con la palabra clave '''public'''. Todas las variables o funciones definidas después de la declaración pública son accesibles por todas las demás funciones en el programa. En nuestra clase CRender, la función m_Renderizar() es pública. Típicamente, su programa accederá a los miembros privados de una clase a través de sus funciones públicas. Note que la palabra clave '''public''' es seguida con ''':''' . Mantenga en mente que un objeto forma una relación entre código y datos. Una función miembro tiene acceso a los elementos privados de su clase. Esto significa que m_Renderizar tiene acceso a buffer en nuestro ejemplo. Para añadir una función miembro a la clase, debe especificar su prototipo en la definición de la misma. Una vez que se ha definido una clase, se puede crear un objeto de ese tipo usando el nombre de la clase. El nombre de la clase se convierte en un especificador del nuevo tipo. Por ejemplo la siguiente declaración crea 2 objetos llamados render1 y render2 del tipo CRender. <pre> CRender render1, render2; </pre> Cuando un objeto de la clase es creado, éste tendrá su propia copia de las variables miembros que contiene la clase. Esto significa que render1 y render2 tendrán su propia e independiente copia de buffer. Los datos asociados con render1 son distintos y separados de los datos asociados con render2. Recordemos: En C++, una clase es un nuevo tipo de dato que puede ser usado para crear objetos. Específicamente, una clase crea una consistencia lógica que define una relación entre sus miembros. Cuando se declara una variable de una clase, se está creando un objeto. Un objeto tiene existencia física, y es una instancia específica de una clase. ( Esto es, un objeto ocupa espacio de memoria, pero una definición de tipo no ). Además, cada objeto de una clase tiene su propia copia de los datos definidos dentro de esa clase. Dentro de la declaración de CRender, el prototipo de una función es especificado. Ya que las funciones miembros son prototipadas dentro de la definición de la clase, no necesitan ser prototipadas en otro lugar cualquiera. Para implementar una función que es un miembro de una clase, debe indicarle al compilador a cual clase pertenece la función calificando el nombre de la función con el nombre de la clase. Por ejemplo, esta es una manera de codificar la función m_Renderizar(). <pre> void CRender::m_Renderizar() { strcpy(buffer, "C++ en wikibooks"); return; } </pre> === Resolución de ámbito === ---- El '''::''' es llamado el operador de resolución de ámbito. Esencialmente le dice al compilador que esta versión de m_Renderizar pertenece a la clase CRender. Dicho de otra forma, '''::''' declara que m_Renderizar se encuentra en el ámbito de CRender. Varias clases diferentes pueden usar los mismos nombres de función. El compilador sabe cuál función pertenece a cuál clase y esto es posible por el operador de resolución de ámbito y el nombre de la clase. === Acceso a las funciones === ---- Las funciones miembros de una clase sólo pueden ser llamadas relativas a un objeto específico. Para llamar a una función miembro desde alguna parte del programa que se encuentre fuera de la clase, se debe usar el nombre del objeto y el operador de direccionamiento '.' ( punto ). Por ejemplo, lo siguiente llama a m_Renderizar() en el objeto objeto1. <pre> CRender objeto1, objeto2; objeto1.m_Renderizar(); </pre> La invocación de <font color="blue">objeto1.m_Renderizar()</font> causa a m_Renderizar() operar en los datos de la copia de objeto1. Mantenga en mente que objeto1 y objeto2 son 2 objetos separados. Esto significa, por ejemplo, que inicializar objeto1 no causa que objeto2 sea inicializado, La única relación que objeto1 tiene con objeto2 es que es un objeto del mismo tipo. Cuando una función miembro llama a otra función miembro de la misma clase, puede hacerlo directamente, sin usar un objeto y el operador '.' En este caso, el compilador ya conoce en cuál objeto se está operando. Solamente cuando una función miembro es llamada por código que se encuentra fuera de la clase es cuando debe utilizarse el nombre del objeto y el operador '.' Por la misma razón, una función miembro puede referirse directamente a una variable miembro, pero código fuera de la clase debe referenciarse a la variable a través de un objeto y el operador '.' El programa siguiente muestra aquí todas las piezas juntas y detalles perdidos, e ilustra la clase CRender. === Ejemplo === <source lang="cpp"> // Programa OPP01.CPP #include <iostream> #include <cstring> using std::cout; using std::endl; // Esto define la clase CRender class CRender { public: char buffer[255]; void m_Renderizar(const char *cadena); }; /* implementar m_Renderizar() para la c;*/ void CRender::m_Renderizar(const char *cadena){ strcpy(buffer, cadena);//copia la cadena return; } int main (int argc, char **argv){ // crear 2 objetos CRender CRender render1, render2; render1.m_Renderizar("Inicializando el objeto render1"); render2.m_Renderizar("Inicializando el objeto render2"); cout << "buffer en render1: "; cout << render1.buffer << endl; // tenemos acceso a buffer ya que es publico. cout << "buffer en render2: "; cout << render2.buffer << endl; return (0); } </source> Este programa imprime: buffer en render1: Inicializando el objeto render1 buffer en render2: Inicializando el objeto render2 == Miembros de una clase (métodos y atributos) == En el lenguaje coloquial de la programación orientada al objeto es común escuchar términos tales como: '''métodos''', '''atributos''', '''herencia''', '''polimorfismo''', etc. En esta sección nos encargaremos de hablar de los dos primeros. '''Métodos''': :En comparación con la programación tradicional, un método es lo mismo que una función cualquiera, salvo que como los métodos se declaran para pertenecer a una clase específica, se dice que todos los métodos de dicha clase son '''miembros''' de la misma. Por lo demás, la declaración y definición de los métodos es exactamente igual que declarar y definir cualquier otra función. '''Atributos''': :En comparación con la programación tradicional, un atributo es lo mismo que una variable cualquiera, salvo que como los atributos se declaran para pertenecer a una clase específica, se dice que todos los atributos de dicha clase son '''miembros''' de la misma. Por lo demás, la declaración de los atributos es exactamente igual que declarar cualquier otra variable. '''Miembros''': :A partir de este momento usaremos la palabra '''miembro''' para referirnos al hecho de que un método o un atributo pertenece a tal o cual clase. Por Ejemplo, en el programa OOP01.CPP (visto anteriormente) la Clase '''CRender''' posee dos miembros, buffer que es un atributo; y m_Renderizar que es un método. <source lang="cpp"> class CRender { public: char buffer[256]; // atributo void m_Renderizar(const char *cadena); // método };</source> == Visibilidad de los miembros de una clase == Por visibilidad se entiende al acto de acceder a los miembros de una clase. En este sentido, los miembros de una clase pueden ser: '''públicos''', '''privados''' y '''protegidos'''. * Un miembro público significa que el acceso al mismo puede darse dentro del interior de la clase, dentro de una subclase, y desde un objeto instanciado de cualquiera de estas. Por ejemplo, los miembros de la clase '''CRender''' son accesibles dentro de la misma y podrán accederse desde cualquier otra clase que se derive de CRender, así como desde cualquier objeto instanciado de estas. * Un miembro privado significa que el acceso al mismo puede darse solamente dentro del interior de la clase que lo posee. Normalmente, el programador creador de una clase declara a los atributos de la clase como privados y a los métodos como públicos, esto con la idea de que el usuario de la clase no pueda tener acceso a los atributos sino es a través de los métodos definidos para el caso. * Un miembro protegido se comporta de manera parecida a un miembro privado, salvo que estos son accesibles dentro de la clase que lo posee y desde las clases derivadas, pero no desde los objetos instanciados a raíz de dichas clases. '''Nota:''' por defecto, los miembros de una clase son privados. En la clase '''Pareja''' que se verá en seguida, se declaran dos atributos y cuatro métodos para la manipulación de dichos atributos. Observe que los atributos son privados(por defecto), mientras que los métodos se declaran públicos. <source lang="cpp"> class Pareja { // atributos double a, b; public: // métodos double getA(); double getB(); void setA(double n); void setB(double n); }; // implementación de los métodos de la clase Pareja // double Pareja::getA() { return a; } double Pareja::getB() { return b; } void Pareja::setA(double n) { a = n; } void Pareja::setB(double n) { b = n; } </source> == Subclases == Una subclase es una clase que se deriva de otra. La clase que sirve de base suele conocerse como '''parent''' (padre), y a la subclase se le llama '''child''' (hija). En C++ cada clase que es creada se convierte en candidata para servir de base de donde se deriven otras. Por ejemplo, la clase '''Pareja''' es candidata para convertirse en la base para las subclases '''Suma''', '''Resta''', '''Multiplica''', '''Divide''', y otras posibles subclases en donde se utilice un par de valores numéricos. Para poner un ejemplo, pensemos en que deseamos crear la clase '''Suma''', misma que será utilizada para obtener la suma de dos números. Puesto que la clase Pareja posee dos atributos numéricos puede ser usada como base para la clase que estamos proyectando. Así, el siguiente ejemplo se constituye en un caso de clases derivadas. <pre>Nota: Observe que la sintaxis para crear una subclase es: class hija : [public | private] padre // ¿Qué significan public y private aquí? { ... }; Donde padre es la clase base e hija es la subclase. </pre> <source lang="cpp"> class Suma : public Pareja { // atributos de Suma double resultado; public: // métodos de Suma double calcular(); }; // implementación de Suma // double Suma::calcular() { return getA() + getB(); }</source> <font size="+1" color="blue">Probando las clases Pareja y Suma</font> <source lang="cpp"> // programa OOP02.CPP // Este programa pone a prueba el uso de las clase Suma, // misma que es una subclase de la clase Pareja (ambas definidas anteriormente). #include <iostream.h> int main() { Suma s; s.setA(80); s.setB(100); cout << s.getA() << " + " << s.getB() << " = " << s.calcular() << endl; cin.get(); return 0; }</source> == Herencia == La '''herencia''' es uno de los mecanismos más útiles de la programación orientada al objeto, ya que por medio de la misma se puede llevar a cabo la ''reutilización de código''. Es decir, puesto que toda clase definida se convierte en candidata para ser usada como base de donde se deriven otras, esto da como resultado que las clases derivadas '''hereden''' todos los miembros de la clase base. Por ejemplo, la clase '''Suma''' vista en la sección anterior, hereda todos los miembros de la clase '''Pareja''' puesto que Suma es una extensión de Pareja. En ese sentido, podemos decir que existen dos tipos de herencia, por '''extensión''' y por '''agregación''' o '''composición'''. En el caso de las clases Pareja y Suma, se dice que Suma es una extensión de Pareja. Vista gráficamente, la herencia por extensión se puede representar así: === Herencia por extensión === <center>[[Archivo:Herencia01.png|frame|none|Herencia]]</center> Al tipo de diagrama mostrado arriba (Herencia por extensión) se le conoce como '''UML''' [//es.wikipedia.org/wiki/Lenguaje_Unificado_de_Modelado] y es utilizado para mostrar de forma grafica la relación existente entre una clase hija con la clase padre. En el caso del ejemplo, se muestra que la clase Suma es una extensión de la clase Pareja y, en consecuencia, Suma posee a los miembros { '''a''', '''b''', '''getA()''', '''getB()''', '''setA()''', '''setB()''' } heredados de la clase Pareja. Observe como la clase Suma posee otros dos miembros no heredados, { '''resultado''', y '''calcular()''' }, y es precisamente a este tipo de situación por lo que se dice que Suma es una extensión de Pareja, ya que Suma, además de poseer a todos los miembros de Pareja, se extiende para poseer o adquirir otros dos miembros. === Agregación o composición === La composición se da en los casos en donde una clase posee un objeto que es una instancia de otra clase. Por ejemplo, la clase '''Suma''' podría escribirse de la siguiente forma: <source lang="cpp"> class Suma { // atributo privado double resultado; public: // método público double calcular(); // atributo público Pareja p; }; // implementación del método calcular de la clase Suma. double Suma::calcular() { return p.getA() + p.getB(); } </source> Luego, si usted presta atención, notará que el miembro '''p''' de la clase Suma es un objeto o instancia de la clase Pareja, en consecuencia, la clase Suma puede acceder a los miembros de la clase Pareja a través de la variable '''p'''. También se debe observar que la implementación del método '''calcular()''' es diferente que el mismo de la clase Suma original. Si usted desea poner a prueba a la nueva clase Suma, compile y ejecute el siguiente programa. <source lang="cpp"> // programa herencia_por_composicion.CPP #include <iostream> using namespace std; class Pareja { // atributos double a, b; public: // métodos double getA(); double getB(); void setA(double n); void setB(double n); }; // implementación de los métodos de la clase Pareja double Pareja::getA() { return a; } double Pareja::getB() { return b; } void Pareja::setA(double n) { a = n; } void Pareja::setB(double n) { b = n; } class Suma { // atributo privado double resultado; public: // método público double calcular(); // atributo público Pareja p; }; // implementación del método calcular de la clase Suma. double Suma::calcular() { return p.getA() + p.getB(); } int main() { Suma s; s.p.setA(80); s.p.setB(100); cout << s.p.getA() << " + " << s.p.getB() << " = " << s.calcular() << endl; cin.get(); return 0; }</source> ////SALIDA//// 80 + 100 = 180 == Constructores == Un constructor es un método que pertenece a una clase y el cual (en C++) debe tener el mismo nombre de la clase a la que pertenece. A diferencia de los otros métodos de la clase, un constructor deberá ser del tipo '''void''', es decir, el mismo no regresará valor alguno. Una clase puede tener más de un método constructor. Cada clase debe tener al menos un constructor, tanto así que si el programador creador de una clase no define un método constructor para la misma, el sistema, o sea el compilador, creará de manera automática un constructor nulo. El objetivo principal del constructor es establecer las condiciones necesarias dentro de la memoria y crear una copia del objeto mismo dentro de la memoria. Los constructores suelen usarse para la inicialización de los atributos de los objetos instanciados. Por ejemplo, con las instrucciones: <pre> Suma s; s.setA(80); s.setB(100); </pre> del programa '''OOP02.CPP''', se declara el objeto '''s''' de la clase Suma y luego se inicializan los atributos del objeto por medio de los métodos setA() y setB(). En este caso, es necesario hacer uso de dichos métodos debido al hecho de que no se ha definido un constructor para la clase Suma. Ahora bien, para evitar este tipo de situaciones podemos definir un método constructor para Suma y que este se encargue de inicializar los atributos. Veamos. '''Notas:''' ya que Suma es una extensión de Pareja, se ha definido el método constructor de Pareja y éste a la vez es invocado por el constructor de Suma. Otro punto de interés es el hecho de la definición de un constructor base para Pareja, ya que de acuerdo con las reglas de programación en C++ toda clase en donde se defina un constructor parametrizado deberá definir un constructor base; esta regla se aplica en los casos en donde la clase proyectada servirá de base para otras. <source lang="cpp"> // programa OOP04.CPP // Ejemplo: clases Pareja y Suma, ambas con constructor #include <iostream> using namespace std; //------------------------ class Pareja { // atributos double a, b; public: // constructor de base (null) Pareja() {} // constructor parametrizado Pareja(double x, double y) : a(x), b(y) {} // métodos double getA(); double getB(); void setA(double n); void setB(double n); }; // implementación de los métodos de la clase Pareja // double Pareja::getA() { return a; } double Pareja::getB() { return b; } void Pareja::setA(double n) { a = n; } void Pareja::setB(double n) { b = n; } //------------------------ class Suma : public Pareja { // atributos de Suma double resultado; public: // constructor Suma(double a, double b) : Pareja(a, b) {} // métodos de Suma double calcular(); }; // implementación de Suma // double Suma::calcular() { return getA() + getB(); } //------------------------ int main() { Suma s(80, 100); cout << s.getA() << " + " << s.getB() << " = " << s.calcular() << endl; cin.get(); return 0; }</source> == Destructores == Un destructor es un método que pertenece a una clase y el cual (en C++) debe tener el mismo nombre de la clase a la que pertenece. A diferencia de los otros métodos de la clase, un destructor deberá ser del tipo '''void''', es decir, el mismo no regresará valor alguno. Para diferenciar a un método destructor de un método constructor, al nombre del destructor se le debe anteponer el carácter <font size="+1">'''~'''</font> (Alt + 126). El objetivo principal del destructor es el de retirar de la memoria al objeto, o sea, el destructor hace todo lo contrario que el constructor. Los destructores suelen usarse para liberar memoria que haya sido solicitada por el objeto a través de las ordenes '''malloc()''', '''new''', etc. En tales casos se deberá incluir dentro del método destructor la orden '''free''', '''delete''', etc., según sea el caso. <source lang="cpp"> // clase Pareja con constructor y destructor class Pareja { // atributos double a, b; public: // constructor de base (nulo) Pareja() {} // constructor parametrizado Pareja(double x, double y) : a(x), b(y) {} // destructor ~Pareja() {} // métodos double getA(); double getB(); void setA(double n); void setB(double n); };</source> </div> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Desarrollo Orientado a Objetos|Desarrollo Orientado a Objetos]] | [[#Clases y Objetos|Arriba]] | [[Programación en C++/Sobrecarga de Operadores|Sobrecarga de Operadores]] → |} [[de:C++-Programmierung: Klassen]] [[fr:Programmation C++/Les classes]] [[pl:C++/Czym jest obiekt]] [[pt:Programar em C++/Classes]] {{AutoCat}} 56bepht0jtffzgtlnkbi9k929k7yvct Programación en C++/Streams 0 19008 427931 414909 2026-07-16T04:33:05Z Mazbel 57931 actualización 427931 wikitext text/x-wiki {| align="center" cellpadding="12" | ← [[Programación en C++/Funciones|Funciones]] | [[Programación en C++/Arrays y cadenas de texto|Arrays y cadenas de texto]] → |} = Streams, entrada y salida de datos = <div style="background:#FFFFEE; padding:40px; text-align:justify"> En este capítulo abordaremos el tema de la manipulación de datos a través de los dispositivos de entrada y salida estándar por medio de ciertos componentes lógicos conocidos como: '''streams'''. A manera de definición, un stream es una especie de canal a través del cual fluyen los datos. Técnicamente, un stream es el enlace lógico utilizado por el programador en C, C++ para leer o escribir datos desde y hacia los dispositivos estándar conectados a la PC. Normalmente, el dispositivo estándar para manipular entradas es el teclado y este, en C++, está asociado al objeto '''cin'''; el dispositivo estándar de salida está asociado (generalmente) con la pantalla o monitor de despliegue de la PC y, el mismo, en C++ se puede acceder por medio del objeto '''cout'''. El dispositivo estándar para mensajes de error es el '''cerr''', y el mismo está asociado por defecto con la pantalla o monitor de despliegue. Otro dispositivo estándar es la impresora, pero este último no es soportado por los objetos de la '''iostream'''. Los programadores que hayan tenido alguna experiencia al programar en C estándar, notarán que los tres objetos mencionados coinciden con los dispositivos: '''stdin''', '''stdout''' y '''stderr'''. La tabla que se muestra en seguida puede servirnos de base. {| border="1" align="center" cellpadding="8" width="400" |+ Tabla I/O : 01, dispositivos estándar de I/O |- ! C estandar ! C++ |- | stdin || cin |- | stdout || cout |- | stderr || cerr |- | --- || clog |} == La iostream == La '''iostream''' es la biblioteca estándar en C++ para poder tener acceso a los dispositivos estándar de entrada y/o salida. En sus programas, si usted desea hacer uso de los objetos '''cin''', '''cout''', '''cerr''' y '''clog''' tendrá que incluir ( por medio de la directiva '''#include''' ) el uso de la biblioteca '''iostream'''. En la iostream se encuentran definidas las clases '''ios''' ( misma que es la base para las clases que implementen operaciones de entrada y/o salida de datos ), '''istream''' ( para operaciones de entrada ) y '''ostream''' ( para operaciones de salida ). Aparte de las clases mencionadas, en la iostream se encuentra una lista de variables y constantes ( atributos ) que son accesibles por el usuario a través del operador de ámbito ( '''::''' ). == Streams automáticos == Si usted usa la directiva '''#include <iostream.h>''' o '''#include <iostream>''' en sus programas, automáticamente la iostream pone a su disposición los objetos '''cin''', '''cout''', '''clog''' y '''cerr''' en el ámbito estándar (std), de tal manera que usted puede comenzar a enviar o recibir información a través de los mismos sin siquiera preocuparse de su creación. Asi, un sencillo ejemplo del uso de los objetos mencionados se muestra en seguida. <source lang="cpp"> // De nuevo con el hola mundo... #include <iostream> int main() { std::cout << "Hola mundo"; // imprimir mensaje (en la pantalla) std::cin.get(); // lectura ( entrada del teclado ) return 0; }</source> == Operadores de direccionamiento == Los operadores de direccionamiento son los encargados de manipular el flujo de datos desde o hacia el dispositivo referenciado por un stream específico. El operador de direccionamiento para salidas es una pareja de símbolos de "menor que" '''<<''', y el operador de direccionamiento para entradas es una pareja de símbolos de "mayor que" '''>>'''. Los operadores de direccionamiento se colocan entre dos operandos, el primero es el Stream y el segundo es una variable o constante que proporciona o recibe los datos de la operación. Por ejemplo, en el siguiente programa y en la instrucción <font color="blue">cout << "Entre su nombre: ";</font> la constante "Entre su nombre: " es la fuente o quien proporciona los datos para el objeto '''cout'''. Mientras que en la instrucción <font color="blue"> cin >> nombre</font> la variable nombre es el destino o quien recibe los datos provenientes del objeto '''cin'''. <source lang="cpp"> // De nuevo con el hola mundo... #include <iostream> int main() { char nombre[80]; cout << "Entre su nombre: "; cin >> nombre; cout << "Hola," << nombre; cin.get(); return 0; }</source> Observe que si en una misma línea de comando se desea leer o escribir sobre varios campos a la vez, no es necesario nombrar más de una vez al stream. Ejemplos: <pre>cout << "Hola," << nombre; cin >> A >> B >> C;</pre> == Banderas de I/O == En esta sección abordaremos de manera más directa el tema sobre el control de formato para los stream de C++. Específicamente, veremos las tres diferentes formas que existen en C++ para manipular las banderas relacionadas a los stream y que nos permitirán gobernar de una manera más precisa la forma para representar datos de salida y/o entrada. En ese sentido, veremos que la primera de las forma que nos permitirá el formateo sera a través de las funciones '''flags()''', '''setf()''' y '''unsetf()''', la segunda y la tercera forma las encontraremos en ciertos manipuladores directos definidos en las bibliotecas '''<iostream>''' y '''<iomanip>'''. === ''Banderas de formato:'' === C++ define algunas banderas de formato para entradas y salidas estándar, las cuales pueden ser manipuladas a través de la funciones (métodos) '''flags()''', '''setf()''', y '''unsetf()'''. Por ejemplo, <pre>cout.setf(ios::left);</pre> activa la justificación a la izquierda para todas las salidas dirigidas hacia cout. A continuación se muestra una tabla de referencia de las banderas de I/O. {| width="100%" border="1" cellpadding="4" |+ Tabla I/O : 02, banderas de formato |- ! Bandera ! Descripción |- | boolalpha | Los valores booleanos pueden ser leídos/escritos usando las palabras "true" y "false" |- | dec | Los valores numéricos se muestran en formato decimal |- | fixed | Números de punto flotante se despliegan en forma normal |- | hex | Los valores numéricos se muestran en formato hexadecimal |- | left | La salida es justificada por la izquierda |- | oct | Los valores numéricos se muestran en formato octal |- | right | La salida es justificada por la derecha |- | scientific | Números de punto flotante se despliegan en notación científica |- | showbase | Despliega la base de todos los valores numéricos |- | showpoint | Despliega el punto decimal y extra ceros, aún cuando no sean necesarios |- | showpos | Despliega el símbolo de más antes de valores positivos |- | skipws | Descarta caracteres de espaciado (espacios, tabuladores, nuevas líneas) cuando se lee desde un stream |- | unitbuf | Descarga el buffer después de cualquier inserción |- | uppercase | Despliega la "e" en notaciones científicas y la "x" en notaciones decimales como letras mayúsculas |} Manipulando la lista de banderas de I/O de C++ (mostrada arriba) se pueden controlar los aspectos relacionados a la forma con la cual se desean presentar los datos en la salida. Por ejemplo, el programa que se muestra en seguida, activa la bandera '''boolalpha''' para mostrar los resultados de operaciones booleanas como "true" o "false" en lugar de "0" o "1" como es lo normal. <source lang="cpp"> // Programación con C++ // programa Banderas01.cpp; // probado en Dev-Cpp Versión 4.9.9.2 #include <iostream> using namespace std; int main(int argc, char *argv[]) { cout <<"\n0 > 1 ? "<<"\t"<<(0>1)<< endl; cout <<"\n5 > 1 ? "<<"\t"<<(5>1)<< endl; cout.setf(ios::boolalpha); // activar bandera cout <<"\n0 > 1 ? "<<"\t"<<(0>1)<< endl; cout <<"\n5 > 1 ? "<<"\t"<<(5>1)<< endl; cin.get(); return 0; }</source> === ''Manipuladores'' === Las banderas también pueden manipularse directamente usando los siguientes manipuladores. Seguramente usted ya estará familiarizado con el manipulador '''endl''', el mismo puede darle una idea de cómo son usados los manipuladores. Por ejemplo, usted puede establecer la bandera de números decimales usando el comando: <pre>cout << dec;</pre> La tabla que se muestra en seguida corresponde a los manipuladores definidos en <iostream>. {| width="100%" cellpadding="4" border="1" |+ Tabla I/O : 03, manipuladores en <iostream> |- ! Manipulador ! Descripción ! Entrada ! Salida |- | boolalpha || Activa la bandera boolalpha | X || X |- | dec || Activa la bandera dec-imal || X | X |- | endl || Escribe carácter de cambio de línea | --- || X |- | ends || Escribe el carácter null || --- | X |- | fixed | Activa la bandera fixed (para números reales) | --- || X |- | flush || Descargar el stream || --- || X |- | hex || Activa la bandera hex-adecimal | X || X |- | internal || Activa la bandera interna | --- || X |- | left || Activa la bandera left (izquierda) | --- || X |- | noboolalpha || Desactiva la bandera boolalpha | X || X |- | noshowbase || Desactiva la bandera showbase | --- || X |- | noshowpoint || Desactiva la bandera showpoint | --- || X |- | noshowpos || Desactiva la bandera showpos | --- || X |- | noskipws || Desactiva la bandera skipws | X || --- |- | nounitbuf || Desactiva la bandera unitbuf | --- || X |- | nouppercase || Desactiva la bandera uppercase | --- || X |- | oct || Activa la bandera oct-al || X | X |- | right | Activa la bandera de justificar derecha | --- || X |- | scientific || Activa la bandera scientific | --- || X |- | showbase || Activa la bandera showbase | --- || X |- | showpoint || Activa la bandera showpoint | --- || X |- | showpos || Activa la bandera showpos | --- || X |- | skipws || Activa la bandera skipws || X | --- |- | unitbuf || Activa la bandera unitbuf | --- || X |- | uppercase || Activa la bandera uppercase | --- || X |- | ws || Limpiar cualquier espacio al inicio | X || --- |} El programa que se muestra en seguida es un ejemplo de como emplear manipuladores directos para formatear salidas al stream estándar de salida ( cout ). En el mismo, se emplea el manipulador '''boolalpha''' para que los resultados de la operaciones logicas sean textuales, o sea, true o false y los manipuladores '''dec''', '''hex''' y '''oct'''. <source lang="cpp"> // Programación con C++ // programa Banderas02.cpp; // probado en Dev-Cpp Versión 4.9.9.2 #include <iostream> using namespace std; int main(int argc, char *argv[]) { cout << boolalpha; cout << "0 > 1 ? " << '\t' << (0 > 1) << endl; cout << "5 > 1 ? " << '\t' << (5 > 1) << endl; cout << dec << 2048 << endl; cout << hex << 2048 << endl; cout << oct << 2048 << dec << endl; cin.get(); return 0; }</source> Por último, y para terminar esta sección, hablaremos de los manipuladores definidos en la biblioteca '''<iomanip>'''. Estos operan directamente igual que los que se vieron anteriormente, salvo que son parametrizados, es decir, operan en línea de salida mediante el operador <<, pero los mismos operan a manera de funciones, o sea con parámetros. {| width="100%" cellpadding="4" border="1" |+ Tabla I/O : 04, manipuladores en <iomanip> |- ! Manipulador ! Descripción ! Entrada ! Salida |- | resetioflags( long f ) | Desactiva las banderas especificadas por f | X || X |- | setbase( int base ) || Establece la bases numérica a base | --- || X |- | setfill( int ch ) || Establece carácter de relleno a ch | --- || X |- | setioflags( long f ) | Activa las banderas especificadas por f | X || X |- | setprecision( int p ) | Establece el número de digitos de precisión a p | --- || X |- | setw( int w ) || Establece la longitud de campo a w | --- || X |} Atendiendo a las tablas de banderas, así como a las tablas de manipuladores para las mismas mostradas arriba, usted puede (con práctica y perceverancia) lograr salidas con muy buena presentación hacia los dispositivos estándar. Por ejemplo, el programa que se mostrará a continuación muestra una de las formas de emplear manipuladores para formatear números de punto flotante, en el programa se despliega una lista de valores numéricos y se establece el campo de salida a una longitud de 12 caracteres y dos decimales. <source lang="cpp"> // Programación con C++ // programa Banderas03.cpp; // probado en Dev-Cpp Versión 4.9.9.2 #include <iostream> #include <iomanip> using namespace std; int main() { double data[] = { 347.25, 45.75, 124.50, 456.80, 1500.90 }; double total = 0; int ancho = 12; cout.precision(2); cout.setf(ios::fixed); for (int c = 0; c < 5; c++) { cout << setw(ancho) << data[c] << endl; total += data[c]; } cout.fill('-'); cout << setw(ancho) << "" << endl; cout.fill(' '); cout << setw(ancho) << total << endl; cout << "Por favor oprime Enter..."; cin.get(); return 0; }</source> = Streams para archivos o ficheros = Por definición, un archivo es una colección de datos almacenados en algún lugar. En C++, el programador puede considerar que un archivo es un '''stream''', de tal manera que los objetos vistos en la sección anterior ( cin, cout, cerr y clog ) son una especie de archivo manipulados por streams. Este punto es de suma importancia, ya que todo lo que se ha mencionado acerca de los atributos, banderas y manipuladores; que son miembros de los objetos ( stream ) para entrada y salida estándar, son aplicables a los streams que usemos para trabajar con archivos en disco y/o cualquier otro dispositivo de almacenamiento. Hasta este momento, solamente se ha mencionado que los streams poseen banderas y que las mismas pueden alterarse a traves de los manipuladores, sin embargo, hace falta hablar acerca de los métodos o funciones que son miembros de dichos streams. Así, antes de ver un ejemplo para mostrar el uso de archivos en disco listaremos una tabla más, o sea, la de los métodos aplicables a los streams. {| width="100%" cellpadding="4" border="1" |+ Tabla I/O : 05, métodos para objetos istream, ostream y fstream |- ! Función ! Descripción |- | bad || true si ha ocurrido un error |- | clear | limpia las banderas de estado (status flags) |- | close || cierra un stream |- | eof | true si se alcanzó el fin de archivo |- | fail || true si ha ocurrido un error |- | fill | establecer manipulador de carácter de relleno |- | flags | accesa o manipula las banderas de formato de un stream |- | flush || vaciar el buffer de un stream |- | gcount | número de caracteres leidos durante la última operación de entrada |- | get || lectura de caracteres |- | getline || lectura de una línea de caracteres |- | good || true si no ha ocurrido un error |- | ignore || leer y descartar caracteres |- | open | abrir un stream de entrada y/o salida |- | peek | verifica la siguiente entrada de carácter |- | precision || manipula la precisión del stream |- | put || escritura de caracteres |- | putback || regresar caracteres al stream |- | rdstate | regresa la bandera de estado de stream |- | read | lee datos de un stream hacia un buffer |- | seekg | realiza acceso aleatorio sobre un stream de entrada |- | seekp | realiza acceso aleatorio sobre un stream de salida |- | setf || cambiar las banderas de formato |- | tellg | lee el puntero del stream de entrada |- | tellp || lee el puntero del stream de salida |- | unsetf || limpiar las banderas de formato |- | width | accesa y manipula la longitud minima del campo |- | write | escritura datos desde un buffer hacia un stream |} == Abrir y cerrar archivo == A diferencia de los streams para dispositivos estándar, los cuales son creados y abiertos de manera automática, para trabajar con archivos en discos se debe primeramente "abrir el archivo", y luego de haber terminado de leer o escribir datos en el mismo, se debe "cerrar el archivo". En C++, en orden de trabajar con archivos en disco, podemos emplear las clases '''fstream''', '''ifstream''', y '''ofstream'''. Si usted desea abrir un archivo específico en modo de lectura y escritura use un objeto de la clase '''fstream''', por el contrario, si desea abrir un archivo solo para lectura o solo para escritura use objetos de la clase '''ifstream''' y '''ofstream''', respectivamente. La sintaxis para crear objetos de las tres clase mencionadas es: <source lang="cpp"> '''streams para lectura y escritura''' fstream(); fstream(const char*, int, int = filebuf::openprot); fstream(int); fstream(int _f, char*, int); '''streams solo para lectura''' ifstream(); ifstream(const char*, int, int = filebuf::openprot); ifstream(int); ifstream(int _f, char*, int); '''streams solo para escritura''' ofstream(); ofstream(const char*, int, int = filebuf::openprot); ofstream(int); ofstream(int _f, char*, int); </source> Observe que la sintaxis para crear objetos de las tres clases mostradas arriba es la misma. Es decir, # El primer método constructor crea un objeto que no está (aún) asociado a un archivo en disco, en estos casos, se tendrá que usar el método '''stream.open("nombre de archivo");''' para establecer la conexión entre el stream y el archivo en disco. # El segundo método constructor crea un objeto asociado a un archivo en disco, en estos casos, el archivo en el disco queda abierto y asociado al stream. En este, el parámetro '''char *''' apunta a una cadena de caracteres con el nombre del archivo. # El tercer método crea un stream a raiz de un identificador de archivo. # El cuarto método crea un stream a raiz de un identificador de archivo, un buffer y tamaño de buffer específicos. Para nuestro primer ejemplo usaremos el segundo de los constructores mencionados. Así, el programa que se muestra en seguida realiza las siguientes tareas: # Crea y escribe sobre el archivo de texto test.$$$ # Abre y lee los datos del archivo test.$$ # Cierra el archivo test.$$ Para el caso que se presenta se debe prestar atención a los metodos: # '''bad()''', para verificar el estado de error del stream # '''get()''', para leer caracteres del stream # '''put()''', para escribir caracteres en el stream # '''close()''', para cerrar el archivo. <source lang="cpp"> // Ejemplo de ifstream y ofstream // En este programa se demuestra la forma de crear un archivo // en disco por medio de objeto ofstream, y la manera abrir y // leer un archivo por medio de un objeto ifstream. #include <iostream> #include <fstream> #include <cstring> using namespace std; char *filename = "test.$$$"; char *data = "Esta línea de texto se guardará en el archivo test.$$$"; // crear un archivo en disco cuyo nombre es dado por filename int crearArchivo(char *filename) { ofstream fichero(filename); // crear o rescribir archivo // verificar la creación del archivo if ( fichero.bad() ) { cout << "Error al tratar de abrir archivo"; cin.get(); return 1; } // escribir datos al archivo for (unsigned int t = 0; t < strlen(data); t++ ) fichero.put(data[t] ); fichero.close(); cout << "archivo creado exitosamente" << endl; return 0; } // abrir un archivo en disco cuyo nombre es dado por filename int leerArchivo(char *filename) { ifstream fichero(filename); // abrir archivo para lectura // verificar la apertura del archivo if ( fichero.bad() ) { cout << "Error al tratar de abrir archivo"; cin.get(); return 1; } // lectura de datos while ( ! fichero.eof() ) cout << (char)fichero.get(); fichero.close(); cout << endl << "archivo leido exitosamente" << endl; return 0; } int main() { crearArchivo(filename); leerArchivo(filename); cout << endl << "Presione <Enter>..."; cin.get(); return 0; }</source> <font color="red" size="+1">Usando operadores de redirección ( <<, >> )<br /> sobre streams asociados con archivos en disco.</font> No hay que olvidar que si un archivo es asociado a un stream las operaciones de entrada y/o salida para dicho archivo se hacen a travez del stream y, por lo tanto, se puede usar, no solo los operadores de redirección, sino también todos los metodos, manipuladores y atributos que se ha mencionado hasta este momento. Así, el objetivo del siguiente programa es demostrar como hacer uso del operador '''<<''' sobre un archivo asociado a un stream de salida, y del operador '''>>''' sobre un archivo asociado a un stream de entrada. El ejemplo que se mostrará no es realmente útil, sin embargo cumple con su cometido, es decir, el punto de interes del mismo está en las líneas de código: <source lang="cpp"> while ( ! fin.eof() ) { fin >> temp; fout << temp ; }</source> Encargadas de leer datos del archivo de entrada y de escribir los mismos en el archivo de salida. <source lang="cpp"> #include <iostream> #include <fstream> char *filename = "test.$$$"; // abre y lee datos de un archivo en disco cuyo nombre es dado por filename int leerArchivo(char *filename) { ifstream fichero(filename); // abrir archivo para lectura // verificar la apertura del archivo if ( fichero.bad() ) { cout << "Error al tratar de abrir archivo"; cin.get(); return 1; } // lectura de datos while ( ! fichero.eof() ) cout << (char)fichero.get(); fichero.close(); cout << endl << "archivo leido exitosamente" << endl; return 0; } // crea una copia del archivo test.$$$ hacia test.bak // Nota: ningún carácter de espaciado en el origen le es tranferido al destino int backup(char *filename) { char newname[80]; int i = 0; // copia el nombre del archivo original y remplaza la extensión por "BAK". while (filename[i] != '.' ) newname[i] = filename[i++]; newname[i] = '\0'; strcat(newname, ".BAK"); ifstream fin( filename ); // abrir archivo de entrada ofstream fout( newname, ios::trunc ); // abrir archivo de salida char temp; while ( ! fin.eof() ) { fin >> temp; fout << temp ; } fin.close(); fout.close(); return 0; } int main() { backup(filename); leerArchivo("test.bak"); cout << endl << "Presione <Enter>..."; cin.get(); return 0; }</source> </div> {| align="center" cellpadding="12" | ← [[Programación en C++/Funciones|Funciones]] | [[#Streams, array y cadenas de texto|Arriba]] | [[Programación en C++/Arrays y cadenas de texto|Arrays y cadenas de texto]] → |} {{AutoCat}} gldzq0vqwodb1id2esmryfr7iadjy1i Programación en C++/Arrays y cadenas de texto 0 19036 427932 404177 2026-07-16T04:33:20Z Mazbel 57931 actualización 427932 wikitext text/x-wiki {| align="center" cellpadding="12" |- | ← [[Programación en C++/Streams|Streams]] | [[Programación en C++/Desarrollo Orientado a Objetos|Desarrollo Orientado a Objetos]] → |} == Arrays y cadenas de texto == <div style="background:#FFFFEE; padding:40px; text-align:justify"> Los arrays son usados extensamente por los programadores para contener listas de datos en la memoria, por ejemplo, los datos almacenados en un disco suelen leerse y ponerse dentro de un array con el objetivo de facilitar la manipulación de dichos datos, ya que los datos en memoria pueden ser modificados, clasificados, marcados para su eliminacion, etc. para luego ser reescritos al disco. Otro ejemplo podría ser el de un menú de opciones que se desplegarán dentro de una ventana para que el usuario pueda elegir una de éstas, en tales casos y cuando las opciones son numerosas, solamente se ponen unas cuantas de ellas dentro de la ventana pero se le da al usuario la oportunidad de poder subir y bajar a su antojo para ver el resto de opciones que, aunque no se vean en la ventana, forman parte del menú o array de opciones. <font size="+1" color="#0000FF">Array:</font> Un array es un conjunto de datos del mismo tipo ordenados de forma líneal uno después de otro. Los componentes de un array se han de referenciar por medio del nombre del array y un índice de desplazamiento para indicar el componente deseado. == Indices de un array == Los índices son números que se utilizan para identificar a cada uno de los componentes de un array. A modo de ejemplo, podemos pensar que los índices son como los números de habitaciones de un hotel, es decir, para poder dirigirnos a un hotel específico es necesario saber el nombre del mismo, luego, si queremos llegar a una habitación específica de dicho hotel necesitaremos, además del nombre del hotel, el número de habitación deseado. == Dimensiones de un array == De acuerdo a la forma en que se construye o declara un array, éste puede ser clasificado como: unidimensional, bidimensional y multidimensional. Los arrays que se emplean con mucha más frecuencia son los estructurados a manera de ''vector'' ( array unidimensional ) y los estructurados a manera de ''matriz'' ( array bidimensional ), así, aunque en C++ se pueden crear estructuras multidimensionales, en este capítulo solo trataremos con vectores y matrices. === Array unidimensional === ---- Una array uni-dimensional es aquel en donde los componentes son accesibles por medio de uno y solamente un índice que apunte al componente requerido. Los arrays de este tipo son conocidos también con el nombre de ''vectores''. Conceptualmente, podemos pensar en un array unidimensional como una lista compuesta de datos, donde para referirnos a uno de ellos emplearemos un número para indicar la posición del mismo dentro de la lista. Por ejemplo, consideremos el caso de la tabla o array VentaSemanal, la cual está pensada para registrar las ventas de cada uno de los días de la semana. De manera conceptual podemos ver el array como se muestra a continuación: <blockquote> '''Nota:''' en C++ los arrays están basados en 0 ( cero ), es decir, el primer elemento de un array se indexa mediante el 0, y el índice para el último de los elementos es igual al número de componentes menos uno.</blockquote> <pre> array: VentaSemanal +------+ | dato | <-- componente 0, ( fila 0 ) |------| | dato | <-- componente 1, ( fila 1 ) |------| | dato | ... |------| | dato | ... |------| | dato | ... |------| | dato | ... |------| | dato | <-- componente 6, ( fila 6 ) |------| </pre> Si en el array VentaSemanal queremos que el elemento 4 ( por ejemplo ) contenga el valor de 8987 lo podemos lograr con la instrucción: <font color ="blue">VentaSemanal[4] = 8987;</font> y el estado del array sería: <pre> array: VentaSemanal +------+ | dato | |------| | dato | |------| | dato | |------| | dato | |------| | 8987 | <--- componente 4 |------| | dato | |------| | dato | |------| </pre> === Array bidimensional === ---- Un array bi-dimensional es aquel en donde los componentes son accesibles por medio de una pareja de índices que apunten a la fila y a la columna del componente requerido. Los arrays de este tipo son conocidos también con el nombre de ''matrices''. Conceptualmente, podemos pensar en un array bidimensional como en una lista compuesta de filas y columnas, en donde para referirnos a una de ellas emplearemos un número para indicar la posición de fila y otro número para indicar la posición de la columna del componente deseado. Por ejemplo, consideremos el caso de la tabla o array VentaSemanaQ, la cual está pensada para registrar las ventas de cada uno de los días de la semana por cuatro semanas, o sea, una tabla de '''7 x 4''' elementos. De manera conceptual podemos ver el array como se muestra a continuación: <pre> array: VentaSemanaQ C O L U M N A S +--- componente ( 0, 0 ) | +------+------+------+------+ | dato | dato | dato | dato | |------|------|------|------| F | dato | dato | dato | dato | |------|------|------|------| I | dato | dato | dato | dato | |------|------|------|------| L | dato | dato | dato | dato | |------|------|------|------| A | dato | dato | dato | dato | |------|------|------|------| S | dato | dato | dato | dato | |------|------|------|------| | dato | dato | dato | dato | +------+------+------+------+ | +---- componente ( 6, 3 ) </pre> Si en el array VentaSemanaQ queremos que el elemento de la fila 4, columna 3 ( por ejemplo ) contenga el valor de 5000 lo podemos lograr con la instrucción: <font color ="blue">VentaSemanaQ[4][3] = 5000;</font> y el estado del array sería: <pre> array: VentaSemanaQ +--- componente ( 0, 0 ) | +------+------+------+------+ | dato | dato | dato | dato | |------|------|------|------| | dato | dato | dato | dato | |------|------|------|------| | dato | dato | dato | dato | |------|------|------|------| | dato | dato | dato | dato | |------|------|------|------| | dato | dato | dato | 5000 | <-- componente ( 4, 3 ) |------|------|------|------| | dato | dato | dato | dato | |------|------|------|------| | dato | dato | dato | dato | +------+------+------+------+ | +---- componente ( 6, 3 ) </pre> == Declaración de arrays en C, C++ == En C, C++ para declarar un array se emplea la sintaxis: <pre>tipo identificador [tamaño] = { lista de inicialización } ;</pre> donde, * tipo se refiere al tipo de datos que contendrá el array. El tipo puede ser cualquiera de los tipos estándar (char, int, float, etc.) o un tipo definido por el usuario. Es más, el tipo del array puede ser de una estructura creada con: struct, union y class. * identificador se refiere al nombre que le daremos al array. * tamaño es opcional e indica el número de elementos que contendrá el array. Si un array se declara sin tamaño, el mismo no podrá contener elemento alguno a menos que en la declaración se emplee una lista de inicialización. * lista de inicialización es opcional y se usa para establecer valores para cada uno de los componentes del array. Si el array es declarado con un tamaño específico, el número de valores inicializados no podrá ser mayor a dicho tamaño. Ejemplos: <source lang="cpp"> int intA[5]; long longA[5] = { 1, 2, 3, 4, 5 }; char charA[3] = { 'a', 'b', 'c' }; </source> === Iteraciones dentro de un array (vector) === El termino ''Iterar'' se refiere al hecho de acceder (con el fin de leer o escribir) sobre cada uno de los componentes de un array. Así, para poner un ejemplo reconsideremos el caso de la tabla '''VentaSemanal''' (vista en una sección anterior), y que dicho sea de paso es un array de 7 elementos de tipo '''double'''. Luego, vamos a mostrar como ejemplo un programa completo en el cual se declara el array mencionado con valores inicializados, que serán mostrados en pantalla y al final la suma de estos. Observe que la variable '''i''' usada para iterar dentro del array va desde 0 hasta FILAS - 1 ( FILAS es el tamaño del array ). <blockquote>Nota: por motivos de simplificación el programa está escrito al estilo de C estándar. Sin embargo puede ser compilado y ejecutado en un compilador de C++.</blockquote> <source lang="cpp"> #include <stdio.h> #include <stdlib.h> #define FILAS 7 int main() { float ventas[FILAS] = { 123.50, 234.60, 345.45, 321.40, 345.00, 456.65, 0.0 }; float total = 0; int i; puts("Ventas de la semana"); puts("-------------------"); for (i=0; i<FILAS; i++) { total += ventas[i]; printf( "%8.2f\n", ventas[i] ); } puts("--------"); printf("%8.2f\n", total ); system("pause"); return 0; } Esta es la salida del programa: Ventas de la semana ------------------- 123.50 234.60 345.45 321.40 345.00 456.65 0.00 -------- 1826.60 </source> === Iteraciones dentro de un array (matriz) === Con el fin de leer o escribir sobre cada uno de los componentes de una '''matriz''' se deben crear dos ciclos de iteración. Así, para poner un ejemplo reconsideremos el caso de la tabla '''VentaSemanaQ''' (vista en una sección anterior), y que dicho sea de paso es un array de '''4 x 4''' elementos de tipo '''double'''. Luego, vamos a mostrar como ejemplo un programa completo en el cual se declara el array mencionado con valores inicializados, que serán mostrados en pantalla y al final la suma de estos. Observe que en este caso se utilizan dos variables, una para iterar sobre las filas y otra para iterar sobre las columnas de la matriz. <source lang="cpp"> #include <stdio.h> #include <stdlib.h> #define FILAS 7 #define COLS 4 int main() { float VentaSemanaQ[FILAS][COLS] = { 123.50, 234.60, 345.45, 321.40, 345.00, 456.65, 123.50, 234.60, 345.45, 321.40, 345.00, 456.65, 123.50, 234.60, 345.45, 321.40, 345.00, 456.65, 123.50, 234.60, 345.45, 321.40, 345.00, 456.65, 0.0, 0.0, 0.0, 0.0 }; float totales[COLS] = { 0.0, 0.0, 0.0, 0.0 }; float grantotal = 0; int f, c, t = 0 ; /* indices para filas, columnas y totales */ puts("Ventas de cuatro semanas"); puts("------------------------"); for (f=0; f<FILAS; f++) { for (c=0; c<COLS; c++) { totales[c] += VentaSemanaQ[f][c]; printf("%8.2f ", VentaSemanaQ[f][c] ); } puts(""); } puts("--------------------------------------"); for (t=0; t<COLS; t++) { printf("%8.2f ", totales[t] ); grantotal += totales[t]; } printf("\n\nGran total: %10.2f\n", grantotal); system("pause"); return 0; } Salida del programa: Ventas de cuatro semanas ------------------------ 123.50 234.60 345.45 321.40 345.00 456.65 123.50 234.60 345.45 321.40 345.00 456.65 123.50 234.60 345.45 321.40 345.00 456.65 123.50 234.60 345.45 321.40 345.00 456.65 0.00 0.00 0.00 0.00 -------------------------------------- 1627.90 2025.30 1627.90 2025.30 Gran total: 7306.40 </source> == Cadenas de caracteres == En C, C++ las cadenas de caracteres no son más que arrays de caracteres, salvo que a este tipo de arrays el compilador les da un tratamiento especial. Usted puede manipular las cadenas de caracteres de la misma manera en que manipula cualquier otro tipo de array, sin embargo, es preferible hacer uso de una librería estándar especialmente escrita para manipulacion de cadenas de caracteres, me refiero a la librería '''<string.h>''' y que viene incluida con todo compilador de C, C++. Para comenzar y antes de ver algunas de las funciones de la mencionada librería, tenemos los siguientes ejemplos: <pre> 1. char nombre[] = "Oscar"; 2. char nombre2[] = { 'O', 's', 'c', 'a', 'r', '\0' }; </pre> * En el ejemplo 1 se está declarando la variable '''nombre''' como una cadena de caracteres y cuyo contenido inicial es "Oscar". * En el ejemplo 2 se está declarando la variable '''nombre2''' como una cadena de caracteres y cuyo contenido inicial es { 'O', 's', 'c', 'a', 'r', '\0' };. En ambos casos el resultado es el mismo, es decir, al final se obtiene la misma cadena, pero usted debe poner atención al hecho de que toda cadena de caracteres en C, C++ debe terminar con el carácter '''NULL''', que normalmente es igual a cero y se puede escribir como '''<nowiki>'\0'</nowiki>'''. Ahora bien, cuando usted usa la sintaxis mostrada en el ejemplo 1 no tiene que preocuparse por agregar el caracter '''NULL''', ya que esto lo hace el compilador automáticamente. === La biblioteca string === Los compiladores de C, C++ dan soporte a la biblioteca de funciones '''<string.h>''', a la que accede por medio de la directiva '''#include <string.h>'''. No veremos en detalle todas las funciones contenidas en dicha biblioteca, y nos limitaremos a mostrar algunos ejemplos de ciertas funciones importantes. <font color="#FF0000" size="+1">strlen()</font>: Obtener longitud de cadenas ::Sintaxis: size_t strlen(const char *s); ::Comentarios: La función strlen() devuelve la longitud de la cadena s. Ejemplo: <source lang="cpp"> char *nombre = "Oscar E. Palacios"; cout << strlen(nombre) << endl; </source> <font color="#FF0000" size="+1">strcpy()</font>: Copiar cadenas ::Sintaxis: char *stpcpy(char *dest, const char *src); ::Comentarios: stpcpy copia la cadena src hacia dest, la función termina hasta haber encontrado en src el carácter de terminación '''null'''. Ejemplo: <source lang="cpp"> char *nombre = "Oscar E. Palacios"; char copia[80]; strcpy(copia, nombre); cout << copia << endl; </source> <font color="#FF0000" size="+1">strcat()</font>: Concatenar cadenas ::Sintaxis: char *strcat(char *dest, const char *src); ::Comentarios: strcat agrega la cadena src a dest, la función termina hasta haber encontrado en src el carácter de terminación '''null'''. Ejemplo: <source lang="cpp"> char nombre[] = "Oscar E."; char copia[80] = " Palacios"; strcat(copia, nombre); cout << copia << endl; </source> <font color="#FF0000" size="+1">strlwr()</font>: Convertir a minúsculas. ::Sintaxis: char *strlwr(char *dest); ::Comentarios: strlwr convierte todos los caracteres alfabéticos ( 'A' .. 'Z' ) en dest a sus correspondientes caracteres alfabéticos ( 'a' .. 'z' ). Ejemplo: <source lang="cpp"> char nombre[] = "Oscar E. Palacios"; strlwr(nombre); cout << nombre << endl; </source> <font color="#FF0000" size="+1">strupr()</font>: Convertir a mayúsculas. ::Sintaxis: char *strupr(char *dest); ::Comentarios: strupr convierte todos los caracteres alfabéticos ( 'a' .. 'z' ) en dest a sus correspondientes caracteres alfabéticos ( 'A' .. 'Z' ). ---- <font color="#FF0000" size="+1">strchr()</font>: Buscar carácter ( hacia adelante ) ::Sintaxis: char *strchr(char *s, int c); ::Comentarios: strchr busca en '''s''' el caracter '''c'''. La busqueda se lleva a cabo desde el inicio hasta el final de s. ::Regreso: si la operación es exitosa strchr regresa un puntero hacia la primera ocurrencia de '''c''' en '''s''', en caso contrario strchr regresa '''null'''. Ejemplo: <source lang="cpp"> char nombre[] = "Oscar E. Palacios"; char *p; p = strchr(nombre, 'E'); if (p) { cout << "nombre contiene a E" << endl; cout << "indice = " << (p - nombre) << endl; } else cout << "E no está en nombre" << endl; </source> <font color="#FF0000" size="+1">strrchr()</font>: Buscar carácter ( hacia atras ) ::Sintaxis: char *strrchr(char *s, int c); ::Comentarios: strchr busca en '''s''' el caracter '''c'''. La busqueda se lleva a cabo desde el final hasta el inicio de s. ::Regreso: si la operación es exitosa strchr regresa un puntero hacia la última ocurrencia de '''c''' en '''s''', en caso contrario strchr regresa '''null'''. Ejemplo: <source lang="cpp"> char nombre[] = "Oscar E. Palacios"; char *p; p = strrchr(nombre, 'E'); if (p) { cout << "nombre contiene a E" << endl; cout << "indice = " << (p - nombre) << endl; } else cout << "E no está en nombre" << endl; </source> <font color="#FF0000" size="+1">strstr()</font>: Buscar subcadena ::Sintaxis: char *strstr(const char *s1, char *s2); ::Comentarios: strstr busca en '''s1''' la subcadena '''s2'''. La búsqueda se lleva a cabo desde el inicio hasta el final de s1. ::Regreso: si la operación es exitosa strstr regresa un puntero hacia la primera ocurrencia de '''s2''' en '''s1''', en caso contrario strstr regresa '''null'''. Ejemplo: <source lang="cpp"> char s[] = "Un barco de tristeza"; char *p; p = strstr(s, "barco"); if (p) { cout << "barco está en s" << endl; cout << "indice = " << (p - s) << endl; } else cout << "barco no está en s" << endl; </source> == Cadenas en C++ == En la sección anterior descubrimos algunas funciones para trabajar con cadenas de caracteres al estilo de C estándar, si bien no está de más tener tal conocimiento, también es cierto que C++ es un lenguaje de programacíón orientado a objetos, de tal manera que ciertos compiladores ( como el gcc, utilzado por '''Bloodshed Dev-C++''' y otros tantos entornos de desarrolo ) dan soporte a la clase '''cstring''', que no debe confundirse con la '''<string.h>'''. ::'''Nota:'''Como el Dev-C++ ya esta descontinuado, es recomendable usar alguno de los siguientes IDE: ::'''Netbeans''': Si usas Windows, debes descargar de aqui el MinGW[http://descargar%20MinGW https://sourceforge.net/projects/mingw/files/latest/download] el cual incluye el compilador g++. Al instalar, solo debes marcar: ::* mingw-developer-toolkit ::* mingw32-base ::* mingw32-gcc-g++ ::* msys-base ::Luego '''Installation''' > '''Update Catalogue''' ::Y finalmente, debemos configurar la variable de entorno. ::Instrucciones de como configurar variable de entorno: https://www.java.com/es/download/help/path.xml ::En el paso de '''editar la variable de entorno''', edita el PATH con la siguiente ruta C:\MinGW\bin ::PD: Si es en Windows 7, debe agregar ; al final de la ultima linea del PATH y colocar la ruta establecida. ::'''Visual Studio''' ::'''Eclipse''' Una de las ventajas que ofrece la clase '''cstring''' es que, a diferencia de las cadenas estándar, ésta posee la capacidad de crecer o disminuir su tamaño en tiempo de ejecución. Además, entre otras caracteristicas destacables, la clase string soporta operaciones de asignación tales como: '''=''', '''+''', '''+=''', etc.; y de comparación tales como: '''==''', '''<=''', etc. Para tener una idea básica sobre las cadenas en C++ veamos el siguiente programa: ::'''Nota:''' en el programa se debe de observar el uso del operador de asignación '''+=''', algo que no es posible hacer con las cadenas estándar. Un estudio exhaustivo sobre la clase string requiere de un capítulo completo, ya que la misma, según el manual de referencia de C++, posee aproximadamente 33 métodos y unos 7 constructores; además de los atributos. == Arrays en C++ == Así como C++ da aternativas elegantes para la manipulación de cadenas de caracteres, también da el soporte para la manipulacíon de arrays '''dinámicos'''. Este tema será ampliado en el capítulo Libreria de Plantillas Estándar '''STL''', sin embargo para tener una idea de lo que vendrá mostraremos aquí un ejemplo sencillo en donde se usará la clase plantilla '''vector'''. {| align="center" cellpadding="12" |- | ← [[Programación en C++/Streams|Streams]] | [[#Arrays y cadenas de texto|Arriba]] | [[Programación en C++/Desarrollo Orientado a Objetos|Desarrollo Orientado a Objetos]] → |} {{AutoCat}} gud3klgz62m6gzagm8fe6zgfuz0hzzs Plantilla:+Portada 10 19100 427918 316675 2026-07-16T04:16:11Z Mazbel 57931 actualización 427918 wikitext text/x-wiki __NOTOC__ {| {{+Tabla|{{Variable|ancho|60%}}}} class="plainlinks" | {{+Celda|relleno=10|borde={{RGB|{{Variable|tono}}9}}|fondo={{RGB|{{Variable|tono}}2}}|alinear=justify|columnas=6|vertical=top|redondeo={{Variable|redondeo}}}}|{{+Portada/encabezado |t ={{{título|{{{nombre|{{PAGENAME}}}}}}}} |s ={{{subtítulo|{{Variable|subtítulo}}}}} |at ={{Variable|alineartit}} |info={{{nombre|{{PAGENAME}}}}}/Info |img =auto |i ={{{imagen|{{Variable|imagen}}}}} |ai =center |ti =250px }} |---- |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonosección}}9}}|{{RGB|{{Variable|tonosección}}3}}||{{Variable|redondeo}}|33.33%|font-weight:bolder;|2|alto=40px}}|{{#ifeq:{{NAMESPACE}}|Plantilla|Índice|{{#ifexist:{{{nombre}}}/Índice|[[{{{nombre}}}/Índice|Índice]]|<span class="plainlinks" style="font-size:80%">[{{fullurl:{{{nombre}}}/Índice|action=edit&preload=Plantilla:%2BPortada/%2BÍndice}} Crear un índice]</span>}}}} |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonosección}}9}}|{{RGB|{{Variable|tonosección}}3}}||{{Variable|redondeo}}|33.33%|font-weight:bolder;|2|alto=40px}}|{{#ifeq:{{NAMESPACE}}|Plantilla|Introducción|{{#ifexist:{{{nombre}}}/Introducción|[[{{{nombre}}}/Introducción|Introducción]]|<span class="plainlinks" style="font-size:80%">[{{fullurl:{{{nombre}}}/Introducción|action=edit&preload=Plantilla:%2BPortada/%2BIntroducción}} Crear una introducción]</span>}}}} |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonosección}}9}}|{{RGB|{{Variable|tonosección}}3}}||{{Variable|redondeo}}|33.33%|font-weight:bolder;|2|alto=40px}}|{{#ifeq:{{NAMESPACE}}|Plantilla|Texto completo|{{#ifexist:{{{nombre}}}/Texto completo|[[{{{nombre}}}/Texto completo|Texto completo]]|<span class="plainlinks" style="font-size:80%">[{{fullurl:{{{nombre}}}/Texto completo|action=edit&preload=Plantilla:%2BPortada/%2BTexto_completo}} Crear texto completo]</span>}}}} |---- |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonoenlaces}}9}}|{{RGB|{{Variable|tonoenlaces}}4}}||{{Variable|redondeo}}|50%|font-weight:bolder;|3|alto=40px}}| [[Archivo:{{Variable|imagenlink}}|30px|link=]]&nbsp;{{#ifeq:{{NAMESPACE}}|Plantilla|Enlaces útiles|[[{{{nombre}}}/Enlaces|Enlaces útiles]]}} |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonoedición}}9}}|{{RGB|{{Variable|tonoedición}}4}}||{{Variable|redondeo}}|50%|font-weight:bolder;|3|alto=40px}}| [[Archivo:{{Variable|imagenedit}}|30px|link=]]&nbsp;{{#ifeq:{{NAMESPACE}}|Plantilla|Edite este libro|[[{{{nombre}}}/Página de edición|Edite este libro]]}} |} {{#ifeq:{{NAMESPACE}}|{{ns:10}}||[[Categoría:Libro:{{{nombre}}}| ]]}} <noinclude>{{documentación}}</noinclude> 9gt5lm33qltw70oo2uvk7ejowjdxg13 427976 427918 2026-07-16T06:18:25Z Mazbel 57931 Se ha deshecho la revisión [[Special:Diff/427918|427918]] de [[Special:Contributions/Mazbel|Mazbel]] ([[User talk:Mazbel|disc.]]) 427976 wikitext text/x-wiki __NOTOC__ {| {{+Tabla|{{Variable|ancho|60%}}}} class="plainlinks" | {{+Celda|relleno=10|borde={{RGB|{{Variable|tono}}9}}|fondo={{RGB|{{Variable|tono}}2}}|alinear=justify|columnas=6|vertical=top|redondeo={{Variable|redondeo}}}}|{{+Portada/encabezado |t ={{{título|{{{nombre|{{PAGENAME}}}}}}}} |s ={{{subtítulo|{{Variable|subtítulo}}}}} |at ={{Variable|alineartit}} |info={{{nombre|{{PAGENAME}}}}}/Info |img =auto |i ={{{imagen|{{Variable|imagen}}}}} |ai =center |ti =250px }} |---- |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonosección}}9}}|{{RGB|{{Variable|tonosección}}3}}||{{Variable|redondeo}}|33.33%|font-weight:bolder;|2|alto=40px}}|{{#ifeq:{{NAMESPACE}}|Plantilla|Índice|{{#ifexist:{{{nombre}}}/Índice|[[{{{nombre}}}/Índice|Índice]]|<span class="plainlinks" style="font-size:80%">[{{fullurl:{{{nombre}}}/Índice|action=edit&preload=Plantilla:%2BPortada/%2BÍndice}} Crear un índice]</span>}}}} |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonosección}}9}}|{{RGB|{{Variable|tonosección}}3}}||{{Variable|redondeo}}|33.33%|font-weight:bolder;|2|alto=40px}}|{{#ifeq:{{NAMESPACE}}|Plantilla|Introducción|{{#ifexist:{{{nombre}}}/Introducción|[[{{{nombre}}}/Introducción|Introducción]]|<span class="plainlinks" style="font-size:80%">[{{fullurl:{{{nombre}}}/Introducción|action=edit&preload=Plantilla:%2BPortada/%2BIntroducción}} Crear una introducción]</span>}}}} |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonosección}}9}}|{{RGB|{{Variable|tonosección}}3}}||{{Variable|redondeo}}|33.33%|font-weight:bolder;|2|alto=40px}}|{{#ifeq:{{NAMESPACE}}|Plantilla|Texto completo|{{#ifexist:{{{nombre}}}/Texto completo|[[{{{nombre}}}/Texto completo|Texto completo]]|<span class="plainlinks" style="font-size:80%">[{{fullurl:{{{nombre}}}/Texto completo|action=edit&preload=Plantilla:%2BPortada/%2BTexto_completo}} Crear texto completo]</span>}}}} |---- |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonoenlaces}}9}}|{{RGB|{{Variable|tonoenlaces}}4}}||{{Variable|redondeo}}|50%|font-weight:bolder;|3|alto=40px}}| [[Archivo:{{Variable|imagenlink}}|30px|link=]]&nbsp;{{#ifeq:{{NAMESPACE}}|Plantilla|Enlaces útiles|[[{{{nombre}}}/Enlaces|Enlaces útiles]]}} |{{+Celda|2|110%|90%|center|{{RGB|{{Variable|tonoedición}}9}}|{{RGB|{{Variable|tonoedición}}4}}||{{Variable|redondeo}}|50%|font-weight:bolder;|3|alto=40px}}| [[Archivo:{{Variable|imagenedit}}|30px|link=]]&nbsp;{{#ifeq:{{NAMESPACE}}|Plantilla|Edite este libro|[[{{{nombre}}}/Página de edición|Edite este libro]]}} |} {{#ifeq:{{NAMESPACE}}|{{ns:10}}||[[Categoría:{{{nombre}}}| ]]}} <noinclude>{{documentación}}</noinclude> nks1k1aecahtd5fze72wf2i229jeuf8 Física/Preliminares/Espacios Vectoriales 0 19116 427961 413232 2026-07-16T05:58:14Z Mazbel 57931 categorización 427961 wikitext text/x-wiki == La Importancia de los espacios vectoriales en Física == == Definición de Espacio Vectorial == Un espacio vectorial <math>\mathcal{V}</math> sobre <math>\mathbb{C}</math> es una conjunto de elementos <math>|a_i\rangle</math> a los que llamaremos vectores, junto a <math>+</math> una operación binaria <math>+:\mathcal{V}\times \mathcal{V}\rightarrow\mathcal{V}</math> que satisface las siguientes propiedades: # <math>|a\rangle + |b\rangle = |b\rangle + |a\rangle, \forall \ |a\rangle,|b\rangle \in \mathcal{V}</math>. # <math>|a\rangle + (|b\rangle + |c\rangle) = (|a\rangle + |b\rangle) + |c\rangle, \forall \ |a\rangle,|b\rangle,|c\rangle \in \mathcal{V}</math>. # Existe un único vector <math>|0\rangle \in \mathcal{V}</math>, denominado el vectos cero, tal que <math>|a\rangle + |0\rangle = |a\rangle, \forall |a\rangle \in \mathcal{V}</math>. # Para todo vector <math>|a\rangle \in \mathcal{V}</math> existe un único vector <math>-|a\rangle \in \mathcal{V}</math> tal que <math>|a\rangle + (-|a\rangle) = |0\rangle</math>. {{AutoCat}} a22fm9vw8693clxwktdzjffqi3vjv8h Programación en C++/Herencia 0 19344 427936 387721 2026-07-16T04:34:47Z Mazbel 57931 actualización 427936 wikitext text/x-wiki Editores:<br /> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Sobrecarga de Operadores|Sobrecarga de Operadores]] | [[Programación en C++/Funciones virtuales|Funciones virtuales]] → |} == Introducción == <div style="background:#FFFFEE; padding:40px; text-align:justify"> La 'herencia' es una de las piedras angulares de la POO ya que ésta permite la creación de clasificaciones jerárquicas. Con la herencia, es posible crear una clase general que defina tratos comunes a una serie de elementos relacionados. Esta clase podría luego ser heredada por otras clases más específicas, cada una agregando solo aquellas cosas que son únicas para la clase 'heredera'. En terminología estándar C++, una clase que es heredada es referida como la clase 'derivada'. La clase que efectúa la herencia es llamada la clase 'base'. Además, una clase derivada puede ser usada como una clase base por otra clase derivada. De esta manera, una jerarquía multicapa de clases puede ser lograda. == INTRODUCIENDO LA HERENCIA. == <div style="text-align:justify; padding:40px; background:#FFFFEE"> C++ soporta herencia permitiendo a una clase incorporar otra clase dentro de su declaración. Antes de discutir los detalles y la teoría, se procede a comenzar por un ejemplo de herencia. La siguiente clase, llamada 'VehiculoRodante', define muy ampliamente a vehículos que viajan por la carretera. Este almacena el numero de ruedas que un vehículo tiene y el numero de pasajeros que puede llevar. Un regla sencilla para recordar esto es: "Una clase derivada hereda de una clase base" <source lang="cpp" style="font-size:14px;"> // Definición de una clase base para vehiculos class VehiculoRodante { public: // CICLO DE VIDA /* En este lugar se sitúan los constructores, los destructores, y/o los constructores copia */ // OPERADORES /* Aquí van los métodos que se apliquen sobre operadores */ // OPERACIONES /* Aquí van los métodos de esta clase que no sean ni de acceso ni de petición o tratamiento */ // ACCESO /* Aquí van las funciones de acceso a los datos miembro o variables propias del objeto */ /* * Función 'set_ruedas' * Recibe: num como int * Devuelve: void * Asigna al dato miembro 'mRuedas' el valor 'num' */ void set_ruedas(int num) { this->mRuedas = num; } /* * Función 'get_ruedas' * Recibe: void * Devuelve: int * Devuelve el valor que hay dentro del dato miembro 'mRuedas' */ int get_ruedas(void) { return this->mRuedas; } /* * Función 'set_pasajeros' * Recibe: num como int * Devuelve: void * Asigna al dato miembro 'mPasajeros' el valor 'num' */ void set_pasajeros(int num) { this->mPasajeros = num; } /* * Función 'get_pasajeros' * Recibe: void * Devuelve: int * Devuelve el valor que hay dentro del dato miembro 'mPasajeros' */ int get_pasajeros(void) { return this->mPasajeros; } // PETICIONES/TRATAMIENTOS /* Aquí van las funciones del tipo "Is", que generalmente devuelven true/false */ private: /* Generalmente en 'private' se sitúan los datos miembros */ int mRuedas; int mPasajeros; }; </source> Se puede usar esta amplia definición de un vehículo rodante para ayudar a definir tipos específicos de vehículos. Por ejemplo, el fragmento de código mostrado aqui podría usarse para ser heredado por una clase derivada llamada 'Camion'. <source lang="cpp" style="font-size:14px;"> // Definición de una clase 'Camion' derivada de la clase base 'VehiculoRodante'. class Camion : public VehiculoRodante { public: // CICLO DE VIDA /* En este lugar se sitúan los constructores, los destructores, y/o los constructores copia */ // OPERADORES /* Aquí van los métodos que se apliquen sobre operadores */ // OPERACIONES /* Aquí van los métodos de esta clase que no sean ni de acceso ni de petición o tratamiento */ // ACCESO /* Aquí van las funciones de acceso a los datos miembro o variables propias del objeto */ /* * Función 'set_carga' * Recibe: size como int * Devuelve: void * Asigna al dato miembro 'mCarga' el valor 'size' */ void set_carga(int size) { this->mCarga = size; } /* * Función 'get_carga' * Recibe: void * Devuelve: int * Devuelve el valor que hay dentro del dato miembro 'mCarga' */ int get_carga(void) { return this->mCarga; } /* * Función 'Mostrar' * Recibe: void * Devuelve: void * Muestra por pantalla las ruedas, pasajeros y la capacidad de carga del objeto 'Camion' */ void Mostrar(void); // PETICIONES/TRATAMIENTOS /* Aquí van las funciones del tipo "Is", que generalmente devuelven true/false */ private: /* Generalmente en 'private' se sitúan los datos miembros */ int mCarga; }; </source> Como 'Camion' hereda de 'VehiculoRodante', 'Camion' incluye todo de 'vehiculo_rodante'. Entonces agrega 'carga' a la misma, en conjunto con las funciones miembros que trabajen sobre este dato. Nótese como 'VehiculoRodante' es heredado. La forma general para la herencia se muestra aquí: <source lang="cpp" style="font-size:14px;"> class ClaseDerivada : acceso ClaseBase { //cuerpo de la nueva clase } </source> Aquí, 'acceso' es opcional. Sin embargo, si se encuentra presente, debe ser 'public', 'private', o 'protected'. Se aprenderá más sobre estas opciones más tarde, por ahora para todas las clases heredadas se usará el acceso 'public'. Usar public significa que todos los miembros públicos de la clase base serán también miembros públicos de la clase derivada. Por tanto, en el ejemplo anterior, miembros de la clase 'Camion' tienen acceso a los miembros públicos de 'VehiculoRodante', justo como si ellos hubieran sido declarados dentro de 'Camion'. Sin embargo, 'camion' no tiene acceso a los miembros privados de 'VehiculoRodante'. Por ejemplo, 'Camion' no tiene acceso a ruedas. He aquí un programa que usa herencia para crear dos subclases de 'VehiculoRodante'. Una es 'Camion' y la otra es 'Automovil'. <source lang="cpp" style="font-size:14px;"> // Programa que demuestra la herencia. // INCLUDES DE SISTEMA // #include <iostream> // INCLUDES DEL PROYECTO // // INCLUDES LOCALES // // DECLARACIONES // // Definición de una clase base para vehiculos class VehiculoRodante { public: // CICLO DE VIDA /* En este lugar se sitúan los constructores, los destructores, y/o los constructores copia */ // OPERADORES /* Aquí van los métodos que se apliquen sobre operadores */ // OPERACIONES /* Aquí van los métodos de esta clase que no sean ni de acceso ni de petición o tratamiento */ /* * Función 'set_ruedas' * Recibe: num como int * Devuelve: void * Asigna al dato miembro 'mRuedas' el valor 'num' */ void set_ruedas(int num) { this->mRuedas = num; } /* * Función 'get_ruedas' * Recibe: void * Devuelve: int * Devuelve el valor que hay dentro del dato miembro 'mRuedas' */ int get_ruedas(void) { return this->mRuedas; } /* * Función 'set_pasajeros' * Recibe: num como int * Devuelve: void * Asigna al dato miembro 'mPasajeros' el valor 'num' */ void set_pasajeros(int num) { this->mPasajeros = num; } /* * Función 'get_pasajeros' * Recibe: void * Devuelve: int * Devuelve el valor que hay dentro del dato miembro 'mPasajeros' */ int get_pasajeros(void) { return this->mPasajeros; } // PETICIONES/TRATAMIENTOS /* Aquí van las funciones del tipo "Is", que generalmente devuelven true/false */ private: /* Generalmente en 'private' se sitúan los datos miembros */ int mRuedas; int mPasajeros; }; // Definición de una clase 'Camion' derivada de la clase base 'VehiculoRodante'. class Camion : public VehiculoRodante { public: // CICLO DE VIDA /* En este lugar se sitúan los constructores, los destructores, y/o los constructores copia */ // OPERADORES /* Aquí van los métodos que se apliquen sobre operadores */ // OPERACIONES /* Aquí van los métodos de esta clase que no sean ni de acceso ni de petición o tratamiento */ // ACCESO /* Aquí van las funciones de acceso a los datos miembro o variables propias del objeto */ /* * Función 'set_carga' * Recibe: size como int * Devuelve: void * Asigna al dato miembro 'mCarga' el valor 'size' */ void set_carga(int size) { this->mCarga = size; } /* * Función 'get_carga' * Recibe: void * Devuelve: int * Devuelve el valor que hay dentro del dato miembro 'mCarga' */ int get_carga(void) { return this->mCarga; } /* * Función 'Mostrar' * Recibe: void * Devuelve: void * Muestra por pantalla las ruedas, pasajeros y la capacidad de carga del objeto 'Camion' */ void Mostrar(void); // PETICIONES/TRATAMIENTOS /* Aquí van las funciones del tipo "Is", que generalmente devuelven true/false */ private: /* Generalmente en 'private' se sitúan los datos miembros */ int mCarga; }; void Camion::Mostrar(void) { std::cout << "ruedas: " << this->get_ruedas() << std::endl; std::cout << "pasajeros: " << this->get_pasajeros() << std::endl; std::cout << "Capacidad de carga en pies cúbicos: " << this->get_carga() << std::endl; } /* * Este enumerador sirve para definir diferentes tipos de automóvil */ enum tipo {deportivo, berlina, turismo}; // Definición de una clase 'Automovil' derivada de la clase base 'VehiculoRodante'. class Automovil : public VehiculoRodante { public: // CICLO DE VIDA /* En este lugar se sitúan los constructores, los destructores, y/o los constructores copia */ // OPERADORES /* Aquí van los métodos que se apliquen sobre operadores */ // OPERACIONES /* Aquí van los métodos de esta clase que no sean ni de acceso ni de petición o tratamiento */ // ACCESO /* Aquí van las funciones de acceso a los datos miembro o variables propias del objeto */ /* * Función 'set_tipo' * Recibe: t como tipo * Devuelve: void * Asigna al dato miembro 'mTipoDeAutomovil' el valor 't' */ void set_tipo(tipo t) { this->mTipoDeAutomovil = t; } /* * Función 'get_tipo' * Recibe: void * Devuelve: tipo * Devuelve el valor que hay dentro del dato miembro 'mTipoDeAutomovil' */ enum tipo get_tipo(void) { return this->mTipoDeAutomovil; }; /* * Función 'Mostrar' * Recibe: void * Devuelve: void * Muestra por pantalla las ruedas, pasajeros y la capacidad de carga del objeto 'Camion' */ void Mostrar(void); private: enum tipo mTipoDeAutomovil; }; void Automovil::Mostrar(void) { std::cout << "ruedas: " << this->get_ruedas() << std::endl; std::cout << "pasajeros: " << this->get_pasajeros() << std::endl; std::cout << "tipo: "; switch(this->get_tipo()) { case deportivo: std::cout << "deportivo"; break; case berlina: std::cout << "berlina"; break; case turismo: std::cout << "turismo"; } std::cout << std::endl; } /* * Función 'main' * Recibe: void * Devuelve: int * El código es una posible implementación para clarificar el uso efectivo de clases bases y clases derivadas. * Muestra por pantalla valores de la clase base y de las clases derivadas. */ int main(void) { Camion Camion1; Camion Camion2; Automovil Automovil1; Camion1.set_ruedas(18); Camion1.set_pasajeros(2); Camion1.set_carga(3200); Camion2.set_ruedas(6); Camion2.set_pasajeros(3); Camion2.set_carga(1200); Camion1.Mostrar(); std::cout << std::endl; Camion2.Mostrar(); std::cout << std::endl; Automovil1.set_ruedas(4); Automovil1.set_pasajeros(6); Automovil1.set_tipo(tipo::deportivo); Automovil1.Mostrar(); return 0; } </source> La salida de este programa se muestra a continuación: ruedas: 18<br /> pasajeros: 2<br /> Capacidad de carga en pies cúbicos: 3200<br /><br /> ruedas: 6<br /> pasajeros: 3<br /> Capacidad de carga en pies cúbicos: 1200<br /><br /> ruedas: 4<br /> pasajeros: 6<br /> tipo: deportivo<br /><br /> Como este programa muestra, la mayor ventaja de la herencia es que permite crear una clase base que puede ser incorporada en clases más específicas. De esta manera, cada clase derivada puede ser precisamente ajustada a las propias necesidades y aun siendo parte de la clasificación general. Por otra parte, nótese que ambos, 'Camion' y 'Automovil', incluyen una función miembro llamada 'Mostrar()', la cual muestra información sobre cada objeto. Esto ilustra un aspecto del polimorfismo. Como cada función 'Mostrar()' esta enlazada con su propia clase, el compilador puede fácilmente indicar cuál llamar para cualquier objeto dado. Ahora que se ha visto los procedimientos básicos por los cuáles una clase hereda de otra, se examinará la herencia en detalle. </div> == CONTROL DE ACCESO DE LA CLASE BASE. == Cuando una clase hereda de otra, los miembros de la clase base se convierten en miembros de la clase derivada. El estado de acceso de los miembros de la clase base dentro de la clase derivada es determinado por el especificador de acceso usado para heredar la clase base. El especificador de acceso de la clase base debe ser 'public', 'private' o 'protected'. Si el especificador de acceso no es usado, entonces se usara private por defecto si la clase derivada es una clase. Si la clase derivada es una 'struct' entonces 'public' es el acceso por defecto por la ausencia de un expecificador de acceso explícito. Examinemos las ramificaciones de usar accesos public o private. ( El especificador 'protected' se describe en la próxima sección.) Cuando una clase base es heredada como 'public', todos los miembros públicos de la clase base se convierten en miembros de la clase derivada. En todos los casos, los elementos privados de la clase base se mantienen de esa forma para esta clase, y no son accesibles por miembros de la clase derivada. Por ejemplo, en el siguiente programa, los miembros públicos de 'base' se convierten en miembros publics de 'derivada'. Además, son accesibles por otras partes del programa. <source lang="cpp"> #include <iostream> using namespace std; class base { int i, j; public: void set(int a, int b) { i = a; j = b; } void mostrar() { cout << i << " " << j << "\n"; } }; class derivada : public base { int k; public: derivada(int x) { k = x; } void mostrar_k() { cout << k << "\n"; } }; int main() { derivada obj(3); obj.set(1, 2); // accesar a miembro de base obj.mostrar(); // accesar a miembro de base obj.mostrar_k(); // usa miembro de la clase derivada return 0; } </source> Como set() y mostrar() son heredadas como 'public', ellas pueden ser llamadas en un objeto del tipo 'derivada' desde main(). Como i y j son especificadas como 'private', ellas se mantienen como tal en la clase base. El opuesto de herencia publica es herencia privada. Cuando la clase base es heredada como privada, entonces todos los miembros públicos de la clase base se convierten en miembros privados de la clase derivada. Por ejemplo, el programa mostrado a continuación no compilara, porque set() y mostrar() son ahora miembros privados de 'derivada', y por ende no pueden ser llamados desde main(). <pre> TIP:"Cuando una clase base es heredada como 'private' sus miembros públicos se convierten en miembros privados de la clase derivada." </pre> <source lang="cpp"> // Este programa no compilara. #include <iostream> using namespace std; class base { int i, j; public: void set(int a, int b) { i = a; j = b; } void mostrar() { cout << i << " " << j << "\n"; } }; // Miembros publicos de 'base' son privados en 'derivada' class derivada : private base { int k; public: derivada(int x) { k = x; } void mostrar_k() { cout << k << "\n"; } }; int main() { derivada obj(3); obj.set(1, 2); // Error, no se puede acceder a set() obj.mostrar(); // Error, no se puede acceder a mostrar() return 0; } </source> La clave a recordar es que cuando una clase base es heredada como 'private', los miembros públicos de la clase base se convierten en miembros privados de la clase derivada. Esto significa que aun ellos son accesibles por miembros de la clase derivada, pero no pueden ser accedidos desde otras partes de su programa. === USANDO MIEMBROS PROTEGIDOS. === ---- En adición a public y private, un miembro de la clase puede ser declarado como protegido. Además, una clase base puede ser heredada como protegida. Ambas de estas acciones son cumplidas por el especificador de acceso 'protected'. La palabra clave 'protected' está incluida en C++ para proveer gran flexibilidad para el mecanismo de herencia. Cuando un miembro de una clase es declarado como 'protected', ese miembro, no es accesible desde otros elementos no-miembros de la clase en el programa. En principio, el acceso a un miembro protegido es lo mismo que el acceso a un miembro privado, este puede ser accedido solo por otros miembros de la clase de la cual es parte. La única excepción a esta regla es cuando un miembro protegido es heredado. Como ya se explicó, un miembro privado de una clase base no es accesible por cualquier otra parte de su programa, incluyendo cualquier clase derivada. Sin embargo, los miembros protegidos se comportan diferente. Cuando una clase base es heredada como pública, los miembros protegidos en la clase base se convierten en miembros protegidos de la clase derivada, y 'son' accesibles a la clase derivada. Además, usando 'protected' se pueden crear miembros de clases que son privados para su clase pero que aun así pueden ser heredados y accedidos por una clase derivada. Considere este programa de ejemplo: <source lang="cpp"> #include <iostream> using namespace std; class base { protected: int i, j; // privados a base, pero accesibles a derivada. public: void set(int a, int b) { i = a; j = b; } void mostrar() { cout << i << " " << j << "\n"; } }; class derivada : public base { int k; public: // derivada puede accesar en base a 'j' e 'i' void setk() { k = i * j; } void mostrark() { cout << k << "\n"; } }; int main() { derivada obj; obj.set(2, 3); // OK, conocido por derivada. obj.mostrar(); // OK, conocido por derivada. obj.setk(); obj.mostrark(); return 0; } </source> Aquí, porque 'base' es heredada por 'derivada' como pública, y porque j e i son declaradas como protegidas, la función setk() en 'derivada' puede acceder a ellas. Si j e i hubieran sido declaradas como privadas por 'base', entonces 'derivada' no tuviera acceso a ellas, y el programa no compilaría. RECUERDE: El especificador 'protected' le permite crear un miembro de la clase que es accesible desde la jerarquía de la clase, pero de otra manera es privado. Cuando una clase derivada es usada como clase base para otra clase derivada, entonces cualquier miembro protegido de la clase base inicial que es heredado ( como public ) por la primera clase derivada puede ser heredado nuevamente, como miembro protegido, por una segunda clase derivada. Por ejemplo, el siguiente programa es correcto, y derivada2 tiene, de hecho, acceso a 'j' e 'i': <source lang="cpp"> #include <iostream> using namespace std; class base { protected: int i, j; public: void set(int a, int b) { i = a; j = b; } void mostrar() { cout << i << " " << j << "\n"; } }; // j e i se heredan como 'protected' class derivada1 : public base { int k; public: void setk() { k = i*j; } // legal void mostrark() { cout << k << "\n"; } }; // j e i se heredan indirectamente a través de derivada1 class derivada2 : public derivada1 { int m; public: void setm() { m = i-j; } // legal void mostrarm() { cout << m << "\n"; } }; int main() { derivada1 obj1; derivada2 obj2; obj1.set(2, 3); obj1.mostrar(); obj1.setk(); obj1.mostrark(); // obj2 de la clase derivada2 tiene acceso a 'i' y 'j', puesto que la clase hereda // tal como la clase derivada1, los miembros protegidos de la clase base. obj2.set(3, 4); obj2.mostrar(); obj2.setk(); obj2.setm(); obj2.mostrark(); obj2.mostrarm(); return 0; } </source> Cuando una clase base es heredada como 'private', miembros protegidos de la clase base se convierten en miembros privados de la clase derivada. Además, en el ejemplo anterior, si 'base' fuera heredada como 'private', entonces todos los miembros de 'base' se hubieran vuelto miembros privados de derivada1, significando que ellos no podrían estar accesibles a derivada2. ( Sin embargo, j e i podrían aun ser accesibles a derivada1.) Esta situación es ilustrada por el siguiente programa, el cual es un error ( y no compilara ). Los comentarios describen cada error. <source lang="cpp"> // Este programa no compilara. #include <iostream> using namespace std; class base { protected: int i, j; public: void set(int a, int b) { i = a; j = b; } void mostrar() { cout << i << " " << j << "\n"; } }; // Ahora todos los elementos de base son privados en derivada1. class derivada1 : private base { int k; public: // Esto es legal porque j e i son privadas a derivada1 void setk() { k = i*j; } // OK void mostrark() { cout << k << "\n"; } }; // Acceso a j, i, set() y mostrar no heredado class derivada2 : public derivada1 { int m; public: // Ilegal porque j e i son privadas a derivada1 setm() { m = j-i; } // error void mostrarm() { cout << m << "\n"; } }; int main() { derivada1 obj1; derivada2 obj2; obj1.set(1, 2); // Error, no se puede usar set() obj1.mostrar(); // Error, no se puede usar show() obj2.set(3, 4); // Error, no se puede usar set() obj2.mostrar(); // Error, no se puede usar show() return 0; } </source> Incluso aunque 'base' es heredada como privada por derivada1, derivada2 aun tiene acceso a los elementos público y protegidos de 'base'. Sin embargo, no puede sobrepasar este privilegio a todo lo largo. Esta es la razón de las partes 'protected' del lenguaje C++. Este provee un medio de proteger ciertos miembros de ser modificados por funciones no-miembros, pero les permite ser heredadas. El especificador 'protected' puede ser usado con estructuras. Sin embargo no puede ser usado con una 'union' porque la unión no puede heredar otra clase o ser heredad. ( Algunos compiladores aceptaran su uso en una declaración en una unión, pero como las uniones no pueden participar en la herencia, 'protected' es lo mismo que 'private' en este contexto.) El especificador 'protected' puede ocurrir en cualquier lugar en la declaración de una clase, aunque típicamente ocurre después de ( por defecto ) que los miembros privados son declarados, y antes de los miembros públicos. Además, la mayor forma completa de la declaración de una clase es <pre> class nombre-clase { miembros privados protected: miembros protegidos public: miembros publicos }; </pre> Por supuesto, la categoría protected es opcional. === USANDO PROTECTED PARA LA HERENCIA DE UNA CLASE BASE. === ---- Como adición a especificar el estado protegido para los miembros de una clase, la palabra clave 'protected' tambien puede ser usada para heredar una clase base. Cuando una clase base es heredada como protected, todos los miembros publicos y protegidos de la clase base se convierten en miembros protegidos de la clase derivada. Aqui hay un ejemplo: <source lang="cpp"> // Demuestra la herencia de una clase base protegida #include <iostream> using namespace std; class base { int i; protected: int j; public: int k; void seti(int a) { i = a; } int geti() { return i; } }; // heredar 'base' como protected. class derivada : protected base { public: void setj(int a) { j = a; }; // j es protected aqui. void setk(int a) { k = a; }; // k es tambien protected. int getj() { return j; } int getk() { return k; } }; int main() { derivada obj; /* La proxima linea es ilegal porque seti() es un miembro protegido de derivada, lo cual lo hace inaccesible fuera de derivada. */ // obj.seti(10); // cout << obj.geti(); // ilegal -- geti() es protected. // obj.k = 10; // tambien ilegal porque k es protected. // estas declaraciones son correctas obj.setk(10); cout << obj.getk() << " "; obj.setj(12); cout << obj.getj() << " "; return 0; } </source> Como puede ver leyendo los comentarios en este programa, k,j, seti() y geti() en 'base' se convierten miembros 'protected' en 'derivada'. Esto significa que ellos no pueden ser accesados por codigo fuera de 'derivada'. Ademas, dentro de main(), referencias a estos miembros a traves de obj son ilegales. === REVISANDO public, protected, y private === Ya que los permisos de acceso que son definidos por 'public', 'protected', y 'private' son fundamentales para la programación en C++, volvamos a revisar sus significados. Cuando una clase miembro es declarada como 'public', esta puede ser accedida por cualquier otra parte del programa. Cuando un miembro es declarado como 'private', este puede ser accedido solo por miembros de su clase. Además, clases derivadas no tienen acceso a miembros privados de la clase base. Cuando un miembro es declarado como 'protected', este puede ser accedido solo por miembros de su clase, o por clases derivadas. Además, protected permite que un miembro sea heredado, pero que se mantenga privado en la jerarquía de la clase. Cuando una clase base es heredada por el uso de 'public', sus miembros publicos se convierten en miebros publicos de la clase derivada, y sus miembros protected se convierten en miembros protected de la clase derivada. Cuando una clase base es heredada por el uso de 'protected', sus miembros publicos y protegidos se convierten en miembros protected de la clase derivada. Cuando una clase base es heredada por el uso de 'private', sus miembros publicos y protegidos se convierten en miebros private de la clase derivada. En todos los casos, los miembros privados de la clase base se mantienen privados a la clase base, y no son heredados. === HEREDANDO MULTIPLES CLASES BASE === Es posible para una clase derivada heredar dos o mas clases base. Por ejemplo, en este corto programa, derivada hereda de ambas clases base1 y base2: <source lang="cpp"> // Un ejemplo de multiples clases base #include <iostream> using namespace std; class base1 { protected: int x; int m; public: void showx() { cout << x << "\n"; } }; class base2 { protected: int y; public: void showy() { cout << y << "\n"; } }; // Heredar multiples clases base. class derivada : public base1, public base2 { public: void set(int i, int j) { x= i; y = j; }; }; int main() { derivada obj; obj.set(10, 20); // proveida por derivada. obj.showx(); // desde base1 obj.showy(); // desde base2 return 0; } </source> Como este ejemplo ilustra, para causar que mas de una clase base sea heredad, debe usarse una lista separada por comas. Ademas, asegurese de usar un especificador de acceso para cada clase heredada. === CONSTRUCTORES, DESTRUCTORES, Y HERENCIA === Existen dos importantes preguntas relativas a los constructores y destructores cuando la herencia se encuentra implicada. Primera, ¿dónde son llamados los constructores y destructores de las clases base y clases derivadas? Segunda, ¿como se pueden pasar los parámetros al constructor de una clase base? Esta sección responde estas preguntas. Examine este corto programa: <source lang="cpp"> #include <iostream> using namespace std; class base { public: base() { cout << "Construyendo base\n"; } ~base() { cout << "Destruyendo base\n"; } }; class derivada : public base { public: derivada() { cout << "Construyendo derivada\n"; } ~derivada() { cout << "Destruyendo derivada\n"; } }; int main() { derivada obj; // no hacer nada mas que construir y destruir obj return 0; } </source> Como el comentario en main() indica, este programa simplemente construye y destruye un objeto llamado obj, el cual es de la clase 'derivada'. Cuando se ejecuta, este programa muestra: <source lang="cpp"> Construyendo base Construyendo derivada Destruyendo derivada Destruyendo base </source> Como puede ver, el constructor de 'base' es ejecutado, seguido por el constructor en 'derivada'. A continuación ( ya que obj es inmediatamente destruido en este programa), el destructor en 'derivada' es llamado, seguido por el de 'base'. El resultado del experimento anterior puede ser generalizado como lo siguiente: Cuando un objeto de una clase derivada es creado, el constructor de la clase base es llamado primero, seguido por el constructor de la clase derivada. Cuando un objeto derivada es destruido, su destructor es llamado primero, seguido por el destructor de la clase base. Viéndolo de otra manera, los constructores son ejecutados en el orden de su derivación. Los destructores son ejecutado en orden inverso de su derivación. Si lo piensa un poco, tiene sentido que las funciones constructor sean ejecutadas en el orden de su derivación. Porque una clase base no tiene conocimiento de las clases derivadas, cualquier inicialización que necesite realizar es separada de, y posiblemente un prerequisito a, cualquier inicialización realizada por la clase derivada. Además, esta debe ejecutarse primero. Asimismo, es bastante sensible que los destructores sean ejecutados en orden inverso a su derivación. Ya que la clase base contiene una clase derivada, la destruccion de una clase base implica la destruccion de su clase derivada. Además, el constructor derivado debe ser llamado antes de que el objeto sea completamente destruido. En el caso de una gran jerarquía de clases ( ej: cuando una clase derivada se convierta en la base clase de otra clase derivada ), la regla general se aplica: Los constructores son llamados en orden de su derivacion, los destructores son llamados en orden inverso. Por ejemplo, este programa <source lang="cpp"> #include <iostream> using namespace std; class base { public: base() { cout << "construyendo base\n"; } ~base() { cout << "Destruyendo base\n"; } }; class derivada1 : public base { public: derivada1() { cout << "Construyendo derivada1\n"; } ~derivada1() { cout << "destruyendo derivada1\n"; } }; class derivada2 : public derivada1 { public: derivada2() { cout << "Construyendo derivada2\n"; } ~derivada2() { cout << "Destruyendo derivada2\n"; } }; int main() { derivada2 obj; // construir y destruir obj return 0; } </source> Muestra la salida: <pre> construyendo base Construyendo derivada1 Construyendo derivada2 Destruyendo derivada2 destruyendo derivada1 Destruyendo base </pre> La misma regla general se aplica en situaciones en que se ven implicadas multiples clases base. Por ejemplo, este programa <source lang="cpp"> #include <iostream> using namespace std; class base1 { public: base1() { cout << "Construyendo base1\n"; } ~base1() { cout << "Desstruyendo base1\n"; } }; class base2 { public: base2() { cout << "Construyendo base2\n"; } ~base2() { cout << "Destruyendo base2\n"; } }; class derivada : public base1, public base2 { public: derivada() { cout << "Construyendo derivada\n"; } ~derivada() { cout << "Destruyendo derivada\n"; } }; int main() { derivada obj; // construir y destruir obj return 0; } </source> Produce la salida: <pre> Construyendo base1 Construyendo base2 Construyendo derivada Destruyendo derivada Destruyendo base2 Destruyendo base1 </pre> Como puede ver, los constructores son llamados en el orden de su derivacion, de izquierda a derecha, como se especifico en la lista de herencia en derivada. Los destructores son llamados en orden inverso, de derecha a izquierda. Esto significa que si base2 fuera especificada antes de base1 en la lista de derivada, como se muestra aqui: <pre> class derivada: public base2, public base1 { </pre> entonces la salida del programa anterior hubiera sido asi: <pre> Construyendo base2 Construyendo base1 Construyendo derivada Destruyendo derivada Destruyendo base1 Derstruyendo base2 </pre> === PASANDO PARAMETROS A LOS CONSTRUCTORES DE LA CLASE BASE === Hasta ahora, ninguno de los ejemplos anteriores han incluido constructores que requieran argumentos. En casos donde solo el constructor de la clase derivada requiera uno o mas argumentos, simplemente use la sintaxis estandarizada de parametrizacion del constructor. Pero, como se le pasan argumentos a un constructor en una clase base? La respuesta es usar una forma expandida de la declaracion de la clase derivada, la cual pasa argumentos entre uno o mas constructores de la clase base. La forma general de esta declaracion expandida se muestra aqui: <pre> constructor-derivada(lista-argumentos) : base1(lista-argumentos), base2(lista-argumentos), baseN(lista-argumentos) { cuerpo del constructor derivado } </pre> Aqui, desde base1 hasta baseN son los nombres de las clases base heredadas por la clase derivada. Notese los dos puntos separando la declaracion del constructor de la clase derivada de las clases base, y que las clases base estan separadas cada una de la otra por comas, en el caso de multiples clases base. Considere este programa de ejemplo: <source lang="cpp"> #include <iostream> using namespace std; class base { protected: int i; public: base(int x) { i = x; cout << "Construyendo base\n"; } ~base() { cout << "Destruyendo base\n"; } }; class derivada : public base { int j; public: // derivada usa x, y es pasado en consjunto a base derivada(int x, int y) : base(y) { j = x; cout << "Construyendo derivada\n"; } ~derivada() { cout << "Destruyendo derivada\n"; } void mostrar() { cout << i << " " << j << "\n"; } }; int main() { derivada obj(3, 4); obj.mostrar(); // muestra 4 3 return 0; } </source> Aqui, el constructor en derivada es declarado para que tome 2 parametros, x, y. Sin embargo, derivada() usa solo x, y es pasada a base(). En general, el constructor de la clase derivada debe declarar el/los parametro(s) que esta clase requiere, tamnbien cualquiera requerido por la clase base. Como el ejemplo anterior ilustra, cualquiera de los parametrosr requeridos por la clase base son pasados a esta en la lista de argumentos de la clase base, especificadas despues de los dos puntos. Aqui tenemos un programa de ejemplo que usa multiples clases base: <source lang="cpp"> #include <iostream> using namespace std; class base1 { protected: int i; public: base1(int x) { i = x; cout << "Construyendo base1\n"; } ~base1() { cout << "Destruyendo base1\n"; } }; class base2 { protected: int k; public: base2(int x) { k = x; cout << "construyendo base2\n"; } ~base2() { cout << "Destuyendo base2\n"; } }; class derivada : public base1, public base2 { int j; public: derivada(int x, int y, int z) : base1(y), base2(z) { j = x; cout << "construyendo derivada\n"; } ~derivada() { cout << "Destruyendo derivada\n"; } void mostrar() { cout << i << " " << j << " " << k << "\n"; } }; int main() { derivada obj(3, 4, 5); obj.mostrar(); // mostrar 3 4 5 return 0; } </source> Es importante comprender que los argumentos al constructor de la clase base son pasado via argumentos al constructor de la clase derivada. Ademas, incluso si el constructor de una clase derivada no usa ningun argumento, este aun debe declarar uno o mas argumentos si la clase base toma uno o mas argumentos. En esta situacion, los argumentos pasado a la clase derivada son simplemente pasados hacia la clase base. Por ejemplo en el siguiente programa, el constructor en derivada no toma argumentos, pero base1() y base2() lo hacen: <source lang="cpp"> #include <iostream> using namespace std; class base1 { protected: int i; public: base1(int x) { i=x; cout << "Construyendo base1\n"; } ~base1() { cout << "Destruyendo base1\n"; } }; class base2 { protected: int k; public: base2(int x) { k=x; cout << "construyendo base2\n"; } ~base2() { cout << "Destruyendo base2\n"; } }; class derivada : public base1, public base2 { public: /* el constructor en derivada no usa parametros, pero aun asi debe ser declarado para tomarlos y pasarselos a las clases base. */ derivada(int x, int y) : base1(x), base2(y) { cout << "Construyendo derivada\n"; } ~derivada() { cout << "Destruyendo derivada\n"; } void mostrar() { cout << i << "" << k << "\n"; } }; int main() { derivada obj(3, 4); obj.mostrar(); // mostrar 3 4 return 0; } </source> El constructor de la clasde derivada es libre de usar cualquiera de todos los parameteos que se declara que toma, ya sea que uno o mas sean pasados a una clase base. Viendolo diferente, solo porque un argumento es pasado a la clase base no declara su uso en la clase derivada. Por ejemplo, este fragmento es perfectamente valido: <source lang="cpp"> class derivada : public base { int j; public: // derivada usa x, y, y tambien las pasa a base derivada(int x, int y) : base(x,y) { j = x*y; cout << "construyendo derivada\n"; } // ... </source> Un punto final a tener en mente cuando se pase argumentos a los constructores de la clase base: Un argumento siendo pasado puede consistir de cualquier expresion valida en ese momento, incluyendo llamadas a funciones y variables. Esto es para sostener el hecho de que C++ permite la inicializacion dinamica. === GARANTIZANDO ACCESO === Cuando una clase base es heredada como private, todos los miembros de esa clase (public, protected o private) se convierten en miembros privates de la clase derivada. Sin embargo, en ciertas circunstancias, podrá restaurar uno o mas miembros heredados a su especificación de acceso original. Por ejemplo, quizás desee permitir a ciertos miembros públicos de la clase base tener un estado public en la clase derivada, incluso aunque la clase es heredada como private. Hay dos maneras de lograr esto. Primero, usted debería usar una declaración 'using' con la clase derivada. Este es el método recomendado por los estándares C++ para uso no nuevo código. Sin embargo, una discusión de 'using' se retrasa hasta finales de este libro donde los 'namespaces' son examinados. ( La primera razón para usar using es para dar soporte a namespaces. ) La segunda manera para ajustar el acceso a un miembro heredado es emplear una declaración de acceso. Las declaraciones de acceso son aun soportadas por el estándar C++, pero han sido marcadas como deprecadas, lo que significa que ellas no deben ser usadas para nuevo codigo, Como aun son usadas en código existente, una discusión de las declaraciones de acceso es presentada aquí: Una declaración de acceso toma esta forma general: <pre> clase-base::miembro; </pre> La declaración de acceso es ubicada bajo los apropiados encabezados de acceso en la clase derivada. Notese que no se requiere ( o permite ) una declaración de tipo en una declaración de acceso. para ver como una declaración de acceso funciona, comencemos con este corto fragmento: <source lang="cpp"> class base { public: int j; // public en base }; // heredar base como private class derivada : private base { public: // aqui esta la declaración de acceso base::j; // hacer j publica nuevamente. // ... }; </source> Como base es heredada como private por derivada, la variable publica j es hecha una variable 'private' en derivada. Sin embargo, la inclusión de esta declaración de acceso <pre> base::j; </pre> Puede usar una declaración de acceso para restaturar los derechos de acceso de miembros 'public' y 'protected', Sin embargo, no puede usar una declaración de acceso para elevar o disminuir un estado de acceso de un miembro. Por ejemplo, un miembro declarado como private dentro de una clase base no puede ser hecho public por una clase derivada. ( Permitir esto destruirá la encapsulacion!) El siguiente programa ilustra el uso en declaraciones de acceso. <source lang="cpp"> #include <iostream> using namespace std; class base { int i; // private en base public: int j, k; void seti(int x) { i = x; } int geti() { return i; } }; // Heredar base como private class derivada : private base { public: /* las siguientes tres declaraciones sobreescriben la herencia de base como private y restablece j, seti() y geti() a publico acceso */ base::j; // hacer j public nuevamente - pero no k base::seti; // hacer seti() public base::geti; // hacer geti() public // base::i; // ilegal - no se puede elevar el acceso int a; // public }; int main() { derivada obj; // obj.i = 10; // ilegal porque i es private en derivada obj.j = 20; // legal porque j es hecho public en derivada //obj.k = 30; // ilegal porque k es private en derivada obj.a = 40; // legal porque a es public en derivada obj.seti(10); cout << obj.geti() << " " << obj.j << " " << obj.a; return 0; } </source> Nótese como este programa usa declaraciones de acceso para restaurar j, seti(), y geti() a un estado 'public'. Los comentarios describen otras varias restricciones de acceso. C++ provee la habilidad de ajustar acceso a los miembros heredados para acomodar aquellas situaciones especiales en las cuales la mayoría de una clase heredad esta pensada para ser private, pero unos cuantos miembros se hacen para mantener su estado public o protected. Es mejor usar esta característica escasamente. === LEYENDO GRÁFICOS DE HERENCIA EN c++ === En ocasiones las jerarquías de clases en C++ son hechas gráficamente para hacerlas mas fácil de comprender. Sin embargo, debido a la forma en que estas son usualmente dibujadas por programadores de C++, los gráficos de herencia son a veces incomprendidos por principiantes. Por ejemplo, considere una situación en la cual la clase A es heredada por la clase B, la cual es heredada por la clase C. Usando la notación estándar C++, esta situación es dibujada como se muestra aquí: <pre> NOTA: "el símbolo ^ es la punta de la fecha, que indica dirección." </pre> <pre> A ^ | B ^ | C </pre> Como puede ver, las flechas apuntan hacia arriba, no hacia abajo. Mientras que muchas personas encuentran inicialmente la dirección de las flechas contra-intuitivasm este es el estilo que la mayoría de los programadores de C++ han adoptado. En gráficos al estilo C++, las flechas apuntan a la clase base. Además, la flecha quiere decir "derivada desde", y no "derivando". Aquí tenemos otro ejemplo. Puede describir en palabras que significa esto? <pre> A B ^ ^ | | ^ ^ C D ^ ^ \ / \ / \ / E </pre> Este gráfico declara que la clase E es derivada de C y D. ( Eso es, E tiene múltiples clases base, llamadas C y D.) Además, C es derivada de A, y D derivada de B. Mientras que la dirección de las flechas puede confundir a la primera, es mejor que se sienta familiar con este estilo de notación gráfica, ya que es comúnmente usada en libros, revistas, y documentación de compiladores. === CLASES BASE VIRTUALES === Un elemento de ambiguedad puede ser introducido en un programa C++ cuando multiples clases bases son heredadas. Considere este incorrecto programa: <source lang="cpp"> // Este programa contiene un error y no compilara. #include <iostream> using namespace std; class base { public: int i; }; // derivada 1 hereda base class derivada1 : public base { public: int j; }; // derivada2 hereda base class derivada2 : public base { public: int k; }; /* derivada3 hereda de ambas, derivada1 y derivada2 esto significa que hay 2 copias de base en derivada3! */ class derivada3 : public derivada1, public derivada2 { public: int sum; }; int main() { derivada3 obj; obj.i = 10; // esto es ambiguo; cual i??? obj.j = 20; obj.k = 30; // i es ambiguo aqui, tambien obj.sum = obj.i + obj.j + obj.k; // tambien ambiguo, cual i? cout << obj.i << " "; cout << obj.j << " " << obj.k << " "; cout << obj.sum; return 0; } </source> Como indican los comentarios en este programa, ambos derivada1 y derivada2 heredan base. Sin embargo, derivada3 hereda ambos, derivada1 y derivada2. Como resultado existen dos copias de base presenten en un objeto del tipo derivada3, asi pues una expresion como <source lang="cpp"> obj.i = 20; </source> hacia cual '''i''' se esta haciendo referencia? La que se encuentra en derivada1 o derivada2? Como existen dos copias de base presentes en el objeto 'obj' entonces hays dos obj.i's. Como puede ver, la declaracion es inherentemente ambigua. Existen dos maneras de remediar el anterior programa. La primera es aplicar el operador de resolucion de ambito para manualmente seleccionar una 'i'. Por ejemplo, la siguiente version el programa compilara y se ejecutara como se esperaba: <source lang="cpp"> // Este programa usa el la resolucion de // ambito explicita para seleccionar 'i' #include <iostream> using namespace std; class base { public: int i; }; // derivada 1 hereda base class derivada1 : public base { public: int j; }; // derivada2 hereda base class derivada2 : public base { public: int k; }; /* derivada3 hereda de ambas, derivada1 y derivada2 esto significa que hay 2 copias de base en derivada3! */ class derivada3 : public derivada1, public derivada2 { public: int sum; }; int main() { derivada3 obj; obj.derivada1::i = 10; // ambito resuelto, se usa la 'i' derivada1 obj.j = 20; obj.k = 30; // ambito resuelto obj.sum = obj.derivada1::i + obj.j + obj.k; // tambien resuelto aqui.. cout << obj.derivada1::i << " "; cout << obj.j << " " << obj.k << " "; cout << obj.sum; return 0; } </source> Aplicando '''::''', el programa manualmente selecciona a derivada1 como version de base. Sin embargo, esta solucion levanta un detalle profundo: Que pasa si solo una copia de base es en realidad requerida? Existe alguna forma de prevenir que dos copias sean incluidas en derivada3? La respuesta, como probablemente ha adivinado se logra con 'clases base virtuales'. Cuando dos o mas objetos son derivados de una clase base común, puede prevenir múltiples copias de la clase base de estar presentes en un objeto derivado por esas clases, declarando la clase base como virtual cuando esta es heredada. para hacer esto, se precede el nombre de la clase base con la palabra virtual cuando esta es heredada. Para ilustrar este proceso, aqui esta otra version del programa de ejemplo. Esta vez, derivada3 contiene solo una copia de base. <source lang="cpp"> // Este programa usa clases base virtuales. #include <iostream> using namespace std; class base { public: int i; }; // derivada1 hereda base como virtual class derivada1 : virtual public base { public: int j; }; // derivada2 hereda base como virtual class derivada2 : virtual public base { public: int k; }; /* derivada3 hereda ambas, derivada1 y derivada2. Esta vez, solo existe una copia de la clase base. */ class derivada3 : public derivada1, public derivada2 { public: int sum; }; int main() { derivada3 obj; obj.i = 10; // ahora no-ambiguo obj.j = 20; obj.k = 30; // no-ambiguo obj.sum = obj.i + obj.j + obj.k; // no-ambiguo cout << obj.i << " "; cout << obj.j << " " << obj.k << " "; cout << obj.sum; return 0; } </source> Como puede ver la palabra clave 'virtual' precede el resto de la especificación de la clase heredada. Ahora que ambas, derivada1 y derivada2 han heredado base como virtual, cualquier herencia multiple que las incluya causará que sólo una copia de base se encuentre presente. Además, en derivada3 existe sólo una copia de base, y obj.i = 10 es perfectamente válida y no-ambiguo. Otro punto a tener en mente: incluso cuando ambas, derivada1 y derivada2 espcifican base como virtual, base sigue presente en los dos tipos derivados. Por ejemplo, la siguiente secuencia es perfectamente válida: <source lang="cpp"> // Definir una clase del tipo derivada1 derivada1 miclase; miclase.i = 88; </source> La diferencia entre una clase base normal y una virtual se hace evidente sólo cuando un objeto hereda la clase base mas de una vez; si la clase base ha sido declarada como virtual, entonces sólo una instancia de esta estará presente en el objeto heredado. De otra manera, múltiples copias serían encontradas. </div> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Sobrecarga de Operadores|Sobrecarga de Operadores]] | [[#Introducción|Introducción]] | [[Programación en C++/Funciones virtuales|Funciones virtuales]] → |} {{AutoCat}} ghmmwx9ijnbmj084xxy4tl30v4ampld Programación en C++/Sobrecarga de Operadores 0 19627 427935 398659 2026-07-16T04:34:08Z Mazbel 57931 actualización 427935 wikitext text/x-wiki == Sobrecarga de operadores == <div style="text-align:justify; padding:40px; background:#FFFFEE"> La sobrecarga de operadores es uno de los mecanismos que nos permite ampliar las capacidades de los lenguajes de programación orientados a objetos. En C++, la declaración y definición de una sobrecarga de operador es muy similar a la declaración y definición de una función cualquiera. El ejemplo más sencillo de una sobrecarga de operadores nos lo da el lenguaje mismo, es decir, en una operación aritmética (por ejemplo, una suma ) el compilador determina el tipo de operación requerida de acuerdo con el tipo de datos involucrados. Vamos a suponer que se tienen las variables: '''int A, B''' '''double X, Y, R''' y las siguientes instrucciones: <source lang="cpp"> R = A + B; R = A + X; R = X + Y; </source> Ahora bien: * en el primer caso el compilador determina que el tipo de operación requerida es una suma de enteros debido a que los dos miembros ( A y B ) de la suma son del tipo entero. * en el segundo caso parece ser que las cosas no son tan claras, ya que en este los miembros involucrados en la suma son de tipos diferentes, sin embargo el compilador determinará el tipo de operación requerida y depositará en el resultado ( R )el valor resultante (no redondeado sino el inmediato anterior). * en el tercero y último de los casos el compilador determina que el tipo de operación requerida es una suma de reales debido a que los dos miembros ( X e Y ) de la suma son del tipo double. También en este caso el resultado de la suma no se redondea sino que pone el inmediato anterior. == Mi primera sobrecarga == Para poner un ejemplo práctico de sobrecarga del operador de suma ( '''+''' ) vamos a considerar el caso de la clase '''pareja''' mostrada enseguida: <source lang="cpp"> class Pareja { public: double a, b; // constructor parametrizado Pareja(const double a,const double b) { this->a = a; this->b = b; } }; int main() { Pareja A(50, 75 ); Pareja B(150, 175 ); Pareja C = A + B; return 0; } </source> Si usted trata de compilar el programa anterior descubrirá que el compilador se queja, es decir, el compilador no sabe qué hacer en el caso de la instrucción '''Pareja C = A + B;''' aunque es evidente que se trata de la declaracion del objeto C y que el mismo se espera que sea igual a la suma de los objetos A y B. El error se debe al hecho de que el tipo '''Pareja''' es en realidad una clase y no un tipo primitivo y, en consecuencia, se debe de adiestrar al compilador para que éste sepa de qué manera hará la suma de dos objetos del tipo '''Pareja'''. Así, para solucionar el error vamos a sobrecargar el operador '''+''' para trabajar la suma de dos de dichos objetos. Veamos: <source lang="cpp"> // Titulo..: programa sobrecarga01.cpp // Objetivo: demostración de sobrecarga de operadores // Autor...: Oscar E. Palacios #include <iostream> using namespace std; class Pareja { public: double a, b; // constructor parametrizado Pareja(const double a,const double b) { this->a = a; this->b = b; } }; // Sobrecarga del operador + Pareja& operator +(const Pareja &p1,const Pareja &p2) { return *(new Pareja(p1.a + p2.a, p1.b + p2.b) ); } int main() { Pareja A(50, 75 ); Pareja B(150, 175 ); Pareja C = A + B; cout << "A = " << A.a << ',' << A.b << "\n"; cout << "B = " << B.a << ',' << B.b << "\n"; cout << "C = " << C.a << ',' << C.b << "\n"; return 0; } </source> El ejemplo anterior tiene un problema al reservar memoria dinámica que no es liberada posteriormente. El código, por tanto, tiene pérdidas de espacio de almacenamiento. La implementación correcta en C++ de este operador sería:<source lang="cpp"> // Sobrecarga del operador + Pareja operator +(const Pareja &p1,const Pareja &p2) { Pareja res( p1.a + p2.a, p1.b + p2.b ); return res; } </source> == Sintaxis general == Tal y como usted lo habrá notado, la declaración de sobrecarga en el programa anterior es lo más parecido a una función, es decir, la sintaxis general para sobrecargar un operador cualquiera es: <pre>tipo operator + (lista de parámetros);</pre> en donde, # tipo se refiere al tipo regresado por el operador # operator es una palabra reservada y debe aparecer en toda declaración de sobrecarga de operadores # el simbolo '''+''' está en representación de cualquier operador # lista de parámetros indica los argumentos sobre los que operarará la función de sobrecarga '''Nota:''' en el caso de que el operador sobrecargado se hace para una clase específica la sintaxis se extiende de la siguiente manera: <pre>tipo nombre_clase::operator + (lista de parámetros);</pre> Regresando al caso de la clase Pareja, específicamente al operador '''+''' de sobrecarga para dicha clase, nos damos cuenta que dicho operador opera sobre dos objetos de dicha clase y también devuelve un resultado de la misma clase. Esto es lo más recomendable ya que si usted recuerda el compilador regresa un resultado entero si es que (por ejemplo) se le da una instrucción como: '''R = 100 + 23;'''. En todo caso, el resultado devuelto por los operadores sobrecargados es responsabilidad del que esta programando == Sobrecarga permitida de operadores == En C++ no es posible sobrecargar todos los operadores, pero al menos la mayoría de ellos sí. Los operadores que no se pueden sobrecargar son: operadores de directivas de procesador '''#''', '''##''' ; Selector directo de componente '''.''' ; operador para valores por defecto de funciones de clase ''':''' ; Operador de acceso a ámbito '''::''' ; Operador de indirección de puntero-a-miembro '''.*''' ; Condicional ternario '''?'''; sizeof y typeid. == Sobrecarga del operador << ( iostream ) == Normalmente cuando se escribe una clase y se desea que el '''stream''' estándar de salida ( '''cout''' ) pueda mostrar una representación de su valor se debe de sobrecargar el operador <<. Para mostrar un ejemplo retomemos el programa sobrecarga01.cpp ( visto arriba ), en el mismo se imprimen por medio de '''cout''' los miembros ( a y b ) de los objetos '''A''', '''B''' y '''C'''. <pre> cout << "A = " << A.a << ',' << A.b << "\n"; cout << "B = " << B.a << ',' << B.b << "\n"; cout << "C = " << C.a << ',' << C.b << "\n"; </pre> Usted puede ver cómo para cada uno de los miembros de los objetos se debe de usar el operador de dirección ( '''.''' ), pues bien, nuestro objetivo es lograr que dado un objeto de la clase Pareja éste pueda ser desplegado por cout y para ello haremos la sobrecarga de operador << con el fin de que pueda operar con objetos de la clase mencionada. Veamos: <source lang="cpp"> // Titulo..: programa sobrecarga03.cpp // Objetivo: demostración de sobrecarga de operadores // Autor...: Oscar E. Palacios #include <iostream> using namespace std; class Pareja { public: double a, b; // constructor parametrizado Pareja(const double a,const double b) { this->a = a; this->b = b; } }; // Sobrecarga del operador + Pareja& operator +(const Pareja &p1,const Pareja &p2) { return *(new Pareja(p1.a + p2.a, p1.b + p2.b) ); } // Sobrecarga del operador << para la clase Pareja ostream& operator << (ostream &o,const Pareja &p) { o << "(" << p.a << ", " << p.b << ")"; return o; } int main() { Pareja A(50, 75 ); Pareja B(150, 175 ); Pareja C = A + B; cout << "A = " << A << "\n"; cout << "B = " << B << "\n"; cout << "C = " << C << "\n"; return 0; } </source> == Sobrecarga del operador >> ( istream ) == Así como el operador << debe ser sobrecargado, lo mismo es cierto para el operador '''>>''' para poder ser usado con el '''stream''' estándar de entrada ( '''cin''' ). Retomaremos nuevamente a la clase Pareja para dar un ejemplo. <source lang="cpp"> // Titulo..: programa sobrecarga03.cpp // Objetivo: demostración de sobrecarga de operadores // Autor...: Keylord Maldonado Maciel y Arlette Any Conchas Vergara #include <iostream> using namespace std; // Arcad. inserte aquí la clase Pareja y los operadores sobrecargados vistos // mientras en el programa anterior. // entonces Se deberá agregar un constructor en // la clase // Pareja como // el siguiente // luego de insertar todo el codigo bien // a continuación como se muestra /*Pareja() { this->a=0; this->b=0; }*/ // Sobrecarga del operador >> para la clase Pareja istream& operator >> (istream &i, Pareja &p) { cout << "Introducir valores para ( a, b) : "; i >> p.a >> p.b; i.ignore(); return i; } int main() { Pareja A(50, 75 ); Pareja B; cin >> B; Pareja C = A + B; cout << "A = " << A << "\n"; cout << "B = " << B << "\n"; cout << "C = " << C << "\n"; return 0; } </source> == Operadores amigos ( friend ) == Un operador amigo, al igual que una función amiga, es aquel que aún cuando no es miembro de una clase tiene todos los privilegios de acceso a los miembros de dicha clase. En la sobrecarga de los operadores '''+''', '''<<''' y '''>>''' para la clase Pareja de los programas anteriores, se puede notar que dichos operadores no son parte de la clase Pareja, sino que más bien éstos operan sobre objetos de dicha clase y es a través de dichos objetos que pueden manipular a los miembros de la clase. Ahora bien, no hemos tenido ningún problema debido a que todos los miembros de Pareja han sido declarados como públicos ('''public:'''), pero ¿qué sucede si un operador o una función que no sea parte de la clase trata de acceder a los miembros privados o protegidos de ésta? En estos casos, el compilador reportaría el error indicando que tal o cual miembro es privado dentro de cierto contexto. Si queremos que un operador o función que no es miembro de una clase pueda acceder a los miembros públicos, privados o protegidos deberemos declarar a dicho operador o función como amigo ('''friend''') dentro de la clase específica. Para mostrar un ejemplo modificaremos la clase Pareja, donde sus atributos serán privados. <source lang="cpp"> // Titulo..: programa sobrecarga04.cpp // Objetivo: demostración de sobrecarga de operadores // Autor...: Oscar E. Palacios #include <iostream> using namespace std; class Pareja { private: double a, b; public: // constructor parametrizado Pareja(const double a,const double b) { this->a = a; this->b = b; } friend Pareja& operator +(const Pareja &p1,const Pareja &p2); friend ostream& operator << (ostream &o,const Pareja &p); }; // Sobrecarga del operador + para la clase Pareja Pareja& operator +(const Pareja &p1,const Pareja &p2) { return *(new Pareja(p1.a + p2.a, p1.b + p2.b) ); } // Sobrecarga del operador << para la clase Pareja ostream& operator << (ostream &o,const Pareja &p) { o << "(" << p.a << ", " << p.b << ")"; return o; } int main() { Pareja A(50, 75 ); Pareja B(150, 175 ); Pareja C = A + B; cout << "A = " << A << "\n"; cout << "B = " << B << "\n"; cout << "C = " << C << "\n"; return 0; } </source> == Sobrecarga de operadores dentro de una clase == Tal y como hemos dicho antes, los operadores que hemos sobrecargado para la clase Pareja ( de los ejemplos anteriores ) no son parte de la clase, pero en la mayoría de las veces se verá que los operadores para una clase específica se deben sobrecargar dentro de la misma clase, es decir, dichos operadores serán miembros de la clase. Antes de sobrecargar cualquier operador para una clase se deben tener en cuenta los siguientes factores: # Los operadores '''binarios''' se declaran con un solo parámetro, ya que el primer parámetro es pasado por el programa como '''this''', es decir, un puntero al mismo objeto. # Los operadores '''unarios''' se declaran sin paramétros, ya que el único parámetro es pasado por el programa como '''this'''. <pre>Nota: Los operadores binarios son aquellos que poseen dos partes ( izquierda y derecha), por ejemplo, una operación de suma requiere dos operandos ( o1 + o2 ). Los operadores unarios son aquellos que poseen solo una parte, por ejemplo, una operación de incremento ( o1 ++ ). </pre> Con el propósito de ver un ejemplo práctico vamos a retomar una vez más la tan famosa clase Pareja, salvo que en esta ocasión vamos a sobrecargar dentro de la misma a los operadores binarios: '''+''' (suma), '''-''' (resta), '''*''' (multiplicación) y '''/''' (división); el operador de asignación ('''='''); el operador de incremento ('''++''') y el operador de comparación ('''=='''). <source lang="cpp"> // Programa: sobrecarga05.cpp // Objetivo: mostrar sobrecarga de operadores // Autor...: Oscar Edmundo Palacios. #include <iostream> using namespace std; class Pareja { private: int a, b; public: // constructor base Pareja() : a(0), b(0) {} // constructor parametrizado Pareja(const int a,const int b) { this->a = a; this->b = b; } // constructor de copia Pareja(const Pareja&); // operadores miembros Pareja& operator + (const Pareja &p); Pareja& operator - (const Pareja &p); Pareja& operator * (const Pareja &p); Pareja& operator / (const Pareja &p); Pareja& operator = (const Pareja &p); Pareja& operator ++(); bool operator ==(const Pareja &p) const; // operadores no miembros friend ostream& operator << (ostream &o,const Pareja &p); friend istream& operator >> (istream &o, Pareja &p); }; // implementacion de los operadores para la clase Pareja //.................................... Pareja::Pareja(const Pareja &p) { *this=p; } //.................................... Pareja& Pareja::operator + (const Pareja &p) { this->a += p.a; this->b += p.b; return *this; } //.................................... Pareja& Pareja::operator - (const Pareja &p) { this->a -= p.a; this->b -= p.b; return *this; } //.................................... Pareja& Pareja::operator * (const Pareja &p) { this->a *= p.a; this->b *= p.b; return *this; } //.................................... Pareja& Pareja::operator / (const Pareja &p) { if (p.a != 0) this->a /= p.a; if (p.b != 0) this->b /= p.b; return *this; } //.................................... Pareja& Pareja::operator = (const Pareja &p) { if(this!=&p){ //Comprueba que no se esté intentanod igualar un objeto a sí mismo if (p.a != 0) this->a = p.a; if (p.b != 0) this->b = p.b; } return *this; } //.................................... Pareja& Pareja::operator ++ () { this->a ++; this->b ++; return *this; } //.................................... bool Pareja::operator == (const Pareja &p) const { return this->a == p.a && this->b == p.b; } // implemetaci¢n de operadores no miembros ostream& operator << (ostream &o,const Pareja &p) { o << "(" << p.a << ", " << p.b << ")"; return o; } istream& operator >> (istream &i, Pareja &p) { cout << "Introducir valores para ( a, b) :"; i >> p.a >> p.b; i.ignore(); return i; } // prueba para la clase Pareja int main() { Pareja A(50, 75); Pareja B(100, 15); Pareja C; cout << "A = " << A << "\n"; cout << "B = " << B << "\n"; cout << "........................." << endl; C = A * B; cout << "A = " << A << "\n"; cout << "C = " << C << endl; cout << "........................." << endl; ++C; cout << "C = " << C << endl; cout << "A == B " << ( (A==B) ? "Si": "No" ); cin.get(); return 0; } </source> </div> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Objetos y Clases|Objetos y Clases]] | [[#Sobrecarga de operadores|Arriba]] | [[Programación en C++/Herencia|Herencia]] → |} {{AutoCat}} jpg3nzgm1lggkqu40o3621aix0dkv5u Matlab 0 19894 427858 205571 2026-07-15T17:38:52Z Antimundo 74354 Retirar etiquetas semánticas innecesarias 427858 wikitext text/x-wiki == Matlab == [[w:Matlab|Matlab]] es un lenguaje de [[w:Programación|programación]] desarrollado por [[w:The Mathworks|The Mathworks]], Matlab nace como el resultado de tratar de satisfacer las necesidades computacionales de científicos, ingenieros y matemáticos, por lo que el desarrollo de Matlab comprende un potente [[w:lenguaje de alto nivel|lenguaje de alto nivel]] y la incorporación de funciones gráficas más allá de los lenguajes de programación [[w:lenguaje de programación C|C]] y [[w:Fortran|Fortran]]. Actualmente, en Matlab se incorporan herramientas diversas tales como [[w:Simulink|Simulink]], que sirve para simular sistemas dinámicos, además de diferentes herramientas para la industria, estadísticas, financieras, científicas y para ingeniería. [[w:GNU Octave|GNU Octave]] y [[w:Labview|Labview Math Script]] proporcionan un entorno compatible con los ficheros-M utilizados en Matlab. == Contenido == #[[/Introducción/]] # [[/Conceptos básicos/]] ## [[/El entorno de Matlab/]] ## [[/Línea de comandos/]] ## [[/Tipos de datos/]] ## [[/Entrada de valores por teclado/]] ## [[/Formato de salida de valores de datos/]] ## [[/El orden de las operaciones/]] # [[/Operaciones básicas/]] ## [[/Operaciones escalares/]] ## [[/Operaciones matriciales/]] ## [[/Operaciones entre escalares y matrices/]] # [[/Matemática simbólica/]] # [[/Programación en Matlab/]] ## [[/Selector «if»/]] ## [[/Selector «switch»/]] ## [[/Selector «try... catch... end»/]] ## [[/Bucle «while»/]] ## [[/Bucle «for»/]] ## [[/Sentencia «break»/]] ## [[/Debugger/]] # [[/Funciones/]] ## [[/Funciones básicas/]] ## [[/Funciones especiales/]] ## [[/Creación de funciones/]] # [[/Archivos/]] ## [[/Lectura de archivos/]] ## [[/Escritura de archivos/]] ## [[/Comandos/]] # [[/Gráficos/]] ## [[/Graficación de datos/]] ## [[/Procesamiento de imágenes/]] # [[/Análisis numérico con Matlab/]] ## [[/Resolución de sistemas de ecuaciones/]] ## [[/Interpolación/]] ## [[/Resolución de Ecuaciones Diferenciales/]] # [[/Creación de interfaces gráficas/]] {{Wikipedia}} [[Categoría:Programación]] [[Categoría:Manuales de software]] 7tvvswqmu0ubz6rfi4s5g5ab1ua2ish 427859 427858 2026-07-15T17:43:08Z Antimundo 74354 Añadir imagen 427859 wikitext text/x-wiki [[Archivo:Matlab Logo.png|sinmarco|derecha]] [[w:Matlab|Matlab]] es un lenguaje de [[w:Programación|programación]] desarrollado por [[w:The Mathworks|The Mathworks]], Matlab nace como el resultado de tratar de satisfacer las necesidades computacionales de científicos, ingenieros y matemáticos, por lo que el desarrollo de Matlab comprende un potente [[w:lenguaje de alto nivel|lenguaje de alto nivel]] y la incorporación de funciones gráficas más allá de los lenguajes de programación [[w:lenguaje de programación C|C]] y [[w:Fortran|Fortran]]. Actualmente, en Matlab se incorporan herramientas diversas tales como [[w:Simulink|Simulink]], que sirve para simular sistemas dinámicos, además de diferentes herramientas para la industria, estadísticas, financieras, científicas y para ingeniería. [[w:GNU Octave|GNU Octave]] y [[w:Labview|Labview Math Script]] proporcionan un entorno compatible con los ficheros-M utilizados en Matlab. == Contenido == #[[/Introducción/]] # [[/Conceptos básicos/]] ## [[/El entorno de Matlab/]] ## [[/Línea de comandos/]] ## [[/Tipos de datos/]] ## [[/Entrada de valores por teclado/]] ## [[/Formato de salida de valores de datos/]] ## [[/El orden de las operaciones/]] # [[/Operaciones básicas/]] ## [[/Operaciones escalares/]] ## [[/Operaciones matriciales/]] ## [[/Operaciones entre escalares y matrices/]] # [[/Matemática simbólica/]] # [[/Programación en Matlab/]] ## [[/Selector «if»/]] ## [[/Selector «switch»/]] ## [[/Selector «try... catch... end»/]] ## [[/Bucle «while»/]] ## [[/Bucle «for»/]] ## [[/Sentencia «break»/]] ## [[/Debugger/]] # [[/Funciones/]] ## [[/Funciones básicas/]] ## [[/Funciones especiales/]] ## [[/Creación de funciones/]] # [[/Archivos/]] ## [[/Lectura de archivos/]] ## [[/Escritura de archivos/]] ## [[/Comandos/]] # [[/Gráficos/]] ## [[/Graficación de datos/]] ## [[/Procesamiento de imágenes/]] # [[/Análisis numérico con Matlab/]] ## [[/Resolución de sistemas de ecuaciones/]] ## [[/Interpolación/]] ## [[/Resolución de Ecuaciones Diferenciales/]] # [[/Creación de interfaces gráficas/]] {{Wikipedia}} [[Categoría:Programación]] [[Categoría:Manuales de software]] c7qfr2ucr4udkn4ymk1lmzmr6n1pfwm Programación en C++/Estructuras II 0 20049 427939 367748 2026-07-16T04:35:30Z Mazbel 57931 427939 wikitext text/x-wiki Editores:<br /> [mailto:oscarpalacios1@yahoo.com.mx Oscar E. Palacios] {| align="center" cellpadding="12" |- | font color="blue" | ← [[Programación en C++/Punteros|Punteros]] | font color="blue" | [[Programación en C++/Plantillas|Plantillas]] → |} = Introducción = <div style="background:#fffeee; text-align:justify; padding:40px"> Algunos autores comienzan por definir los conceptos de estructura de datos a raíz de estructuras conocidas como '''listas'''. En el mismo contexto, suele suceder que a dichas listas también se les conoce como secuencias y/o colecciones de datos. Hay que decir que dichos autores están (en parte) en lo correcto, ya que una lista (de cualquier tipo) es una estructura ideada con el propósito de albergar datos agrupados bajo un mismo nombre. Al respecto, podemos pensar que las listas son como arreglos de datos, es decir, para hacer una introducción al manejo y programación de '''listas encadenadas''' podemos tomar como punto de partida a los arreglos estáticos. Es así como en esta sección se descubrirá la forma de operación de tres tipos comunes de listas conocidas como: '''PILAS''', '''COLAS''' Y '''DOBLE COLA''' ('''STACK''', '''QUEUE''', '''DQUEUE'''). En programación, el uso de listas es una práctica tan extendida que lenguajes tales como (por ejemplo) Java, Python y C++ soportan los mecanismos necesarios para trabajar con estructuras de: Vectores, Pilas, Colas, Listas, etc. En C++, los programadores que usen Dev-Cpp ( [http://www.bloodshed.net/devcpp.html Bloodshed.software -Dev-C++] ) pueden aprovechar las ventajas que ofrecen las STL (Standard Templates Libraries) dentro de la cual se pueden encontrar plantillas para la manipulación de listas tales como: Vectores, Listas, Sets, Maps, etc. Por otro lado, los usuarios de Borland C++ ( [http://dn.codegear.com/article/21751 Turbo C++ version 1.01] ) pueden hacer uso de la CLASSLIB, misma que posee las librerías para los propósitos mencionados. <font size="+2">Nota:</font> En las siguientes secciones se presentarán siete programas, tres para simular listas basadas en arreglos estáticos y tres para simular listas por medio de enlaces dinámicos (punteros). En cuanto al material incluido se debe hacer las siguientes declaraciones: # Puesto que el material es puramente didáctico, cada programa se escribe en un mismo archivo. La idea es no perder de vista el objetivo. Los entendidos sabrán que normalmente se deben escribir archivos de cabecera, archivos de implementación y archivos de prueba por separado. # Para cada una de las clases creadas en los programas se han elegido nombres en inglés. La idea es que gran parte de la documentación e implementación referente a listas está en dicho idioma, así, se le da al estudiante la idea básica de como operar con las librerías soportadas por los compiladores Dev-Cpp, Borlan C++, y otros. # Igual, se debe observar que los métodos de las clases tienen nombres en ingles, y que con el objetivo de establecer cierta estandarización todas las clases poseen los mismos métodos, aunque cada una de ellas implementa los mismos a su manera. == Pilas o Stacks == Una '''pila''' es una estructura en donde cada elemento es insertado y retirado del tope de la misma, y debido a esto el comportamiento de un una pila se conoce como LIFO (último en entrar, primero en salir ). Un ejemplo de pila o stack se puede observar en el mismo procesador, es decir, cada vez que en los programas aparece una llamada a una función el microprocesador guarda el estado de ciertos registros en un segmento de memoria conocido como '''Stack Segment''', mismos que serán recuperados al regreso de la función. === Pila en arreglo estático === En el programa que se verá en seguida, se simula el comportamiento de una estructura de pila. Aunque en el mismo se usa un arreglo estático de tamaño fijo se debe mencionar que normalmente las implementaciones hechas por fabricantes y/o terceras personas se basan en listas dinámicas o enlazadas. Para la implementación de la clase Stack se han elegido los métodos: put(), poner un elemento en la pila get(), retirar un elemento de la pila empty(), regresa 1 (TRUE) si la pila está vacía size(), número de elementos en la pila El atributo SP de la clase Stack es el puntero de lectura/escritura, es decir, el SP indica la posición dentro de la pila en donde la función put() insertará el siguiente dato, y la posición dentro de la pila de donde la función get() leerá el siguiente dato. Cada vez que put() inserta un elemento el SP se decrementa. Cada vez que get() retira un elemento el SP se incrementa. En el siguente ejemplo se analiza lo que sucede con el SP (puntero de pila) cuando se guardan en la pila uno por uno los caracteres 'A', 'B', 'C' y 'D'. Observe que al principio el SP es igual al tamaño de la pila. Llenando la pila. SP | +---+---+---+---+---+ | | | | | | al principio (lista vacía) +---+---+---+---+---+ SP | +---+---+---+---+---+ push('A'); | | | | | A | después de haber agregado el primer elemento +---+---+---+---+---+ ... SP | +---+---+---+---+---+ | | D | C | B | A | después de haber agregado cuatro elementos +---+---+---+---+---+ Vaciando la pila. SP | +---+---+---+---+---+ pop(); | | D | C | B | A | después de haber retirado un elemento +---+---+---+---+---+ ... SP | +---+---+---+---+---+ | | D | C | B | A | después de haber retirado todos los elementos +---+---+---+---+---+ '''Nota''': observe que al final la lista está vacía, y que dicho estado se debe a que el puntero está al final de la pila y no al hecho de borrar físicamente cada elemento de la pila. <font color="red" size="+1">Ejemplo: Pila basada en un arreglo estático</font> <source lang="cpp"> #include <iostream> using namespace std; #define STACK_SIZE 256 /* capacidad máxima */ typedef char arreglo[STACK_SIZE]; class Stack { int sp; /* puntero de lectura/escritura */ int items; /* número de elementos en lista */ int itemsize; /* tamaño del elemento */ arreglo pila; /* el arreglo */ public: // constructor Stack() { sp = STACK_SIZE-1; items = 0; itemsize = 1; } // destructor ~Stack() {}; /* regresa el número de elementos en lista */ int size() { return items; } /* regresa 1 si no hay elementos en la lista, o sea, si la lista está vacia */ int empty() { return items == 0; } /* insertar elemento a la lista */ int put(char d) { if ( sp >= 0) { pila[sp] = d; sp --; items ++; } return d; } /* retirar elemento de la lista */ int get() { if ( ! empty() ) { sp ++; items --; } return pila[sp]; } }; // fin de clase Stack // probando la pila. // Nota: observe cómo los elementos se ingresan en orden desde la A hasta la Z, // y como los mismos se recuperan en orden inverso. int main() { int d; Stack s; // s es un objeto (instancia) de la clase Stack // llenando la pila for (d='A'; d<='Z'; d++) s.put(d); cout << "Items =" << s.size() << endl; // vaciando la pila while ( s.size() ) cout << (char)s.get() << " "; cout << "\nPara terminar oprima <Enter>..."; cin.get(); return 0; } }</source> ---- === Pila dinámica === En el siguiente programa se presenta una implementación de una estructura dinámica tipo pila o stack. Es importante hacer notar que, a diferencia de una pila basada en un arreglo estático, una pila enlazada dinámicamente no posee de forma natural el mecanismo de acceso por índices, en ese sentido, el programador puede crear los algoritmos necesarios para permitir tal comportamiento. En la clase que presentaremos en el ejemplo no se ha implementado el mecanismo de acceso por índices, ya que la misma se presenta como una alternativa para la simulación de una pila o stack. Uno de los puntos más destacables en cuanto al uso de listas enlazadas dinámicamente es el hecho de crear estructuras conocidas como nodos. Un nodo es una especie de eslabón (similar al de una cadena de bicicleta), es decir, cada nodo se enlaza con otro a través de un puntero que apunta a una estructura del mismo tipo que el nodo. Por ejemplo, para crear una estructura de nodo para almacenar enteros y a la vez para apuntar a otro posible nodo podemos emplear la sintaxis: <source lang="cpp"> struct nodo { int data; nodo *siguiente; };</source> observe que con la declaración anterior estamos creando el tipo estructurado nodo, mismo que posee a los miembros: data para guardar valores enteros, y siguiente para apuntar o enlazar a un supuesto siguiente nodo. Ya que las listas dinámicas inicialmente se encuentran vacías, y más aún, una lista dinámica no posee una dirección establecida en tiempo de compilación ya que las dirección de memoria que ocupará cada uno de los elementos se establecerá en tiempo de ejecución, entonces cómo determinar la condición de vacío ?. En nuestro ejemplo usaremos un contador ( ITEMS ) que dicho sea de paso, si ITEMS = 0, entonces la lista está vacía. ( la condición de vacío también podría determinarse al verificar el SP, es decir, si el SP = NULL, significa que la lista no posee elementos ). Al hacer un análisis previo de los eventos que acontecerán en la pila y su puntero de lectura y escritura (SP, que en esta ocasión es una estructura tipo nodo), se tiene lo siguiente: :1) Al principio la lista está vacía, en ese caso el SP es igual a NULL y, en consecuencia, el puntero next también es NULL. <pre> SP = NULL +------+------+ | ???? | next |--> NULL +------+------+ </pre> :2) Después de agregar el primer elemento la situación se vería así: <pre> SP = asignado 1 +------+------+ | data | next |--> NULL +------+------+ </pre> :3) Después de agregar otro elemento la situación se vería así: <pre> SP = asignado 2 1 +------+------+ +------+------+ | data | next |--> | data | next |--> NULL +------+------+ +------+------+ </pre> <font color="red" size="+1">Ejemplo: Pila basada en un arreglo dinámico</font> <source lang="cpp"> /*---------------------------------------------------------------+ + ejemplo de una pila ( STACK ) enlazada dinámicamente + + + + Autor: Oscar E. Palacios + + email: oscarpalacios1@yahoo.com.mx + + + + Manifiesto: + + Este programa puede distribuirse, copiarse y modificarse de + + forma libre. + +---------------------------------------------------------------*/ #include <iostream> //#include <conio.h> using namespace std; /* tipo de dato que contendrá la lista */ typedef char DATA_TYPE; // declaraci¢n de estructura nodo struct nodo { DATA_TYPE data; nodo *next; }; class StackDin { // atributos int ITEMS; /* número de elementos en la lista */ int ITEMSIZE; /* tamaño de cada elemento */ nodo *SP; /* puntero de lectura/escritura */ public: // constructor StackDin() : SP(NULL), ITEMS(0), ITEMSIZE(sizeof(DATA_TYPE)) {} // destructor ~StackDin() {} /* agregar componente a la lista */ DATA_TYPE put(DATA_TYPE valor) { nodo *temp; temp = new nodo; if (temp == NULL) return -1; temp->data = valor; temp->next = SP; SP = temp; ITEMS ++; return valor; } int empty() { return ITEMS == 0; } /* retirar elemento de la lista */ DATA_TYPE get() { nodo *temp; DATA_TYPE d; if ( empty() ) return -1; d = SP->data; temp = SP->next; if (SP) delete SP; SP = temp; ITEMS --; return d; } }; // fin de la clase StackDin /* punto de prueba para la clase StackDin */ int main() { //clrscr(); StackDin s; DATA_TYPE d; for (d='A'; d<='Z'; d++) s.put(d); while ( ! s.empty() ) cout << (DATA_TYPE)s.get() << " "; cout << "\nPara terminar presione <Enter>..."; cin.get(); return 0; }</source> == Colas o Queues == Una cola sencilla es una estructura en donde cada elemento es insertado inmediatamente después del último elemento insertado; y donde los elementos se retiran siempre por el frente de la misma, debido a esto el comportamiento de un una cola se conoce como FIFO (primero en entrar, primero en salir). Un ejemplo a citar de cola es el comportamiento del buffer del teclado. Cuando en el teclado se oprime una tecla, el código del carácter ingresado es trasladado y depositado en una área de memoria intermedia conocida como "el buffer del teclado", para esto el microprocesador llama a una rutina específica. Luego, para leer el carácter depositado en el buffer existe otra función, es decir, hay una rutina para escribir y otra para leer los caracteres del buffer cada una de las cuales posee un puntero; uno para saber en donde dentro del buffer se escribirá el siguiente código y otro para saber de donde dentro del buffer se leerá el siguiente código. === Cola en un arreglo estático === En el programa que se ve en seguida, se simula el comportamiento de una estructura de cola simple. Aunque en el mismo se usa un arreglo estático de tamaño fijo se debe mencionar que normalmente las implementaciones hechas por fabricantes y/o terceras personas se basan en listas dinámicas o dinámicamente enlazadas. Para la implementación de la clase Queue se han elegido los métodos: <pre> put(), poner un elemento en la cola get(), retirar un elemento de la cola empty(), regresa 1 (TRUE) si la cola está vacía size(), número de elementos en la cola </pre> El atributo cabeza de la clase Queue es el puntero de lectura. El atributo cola de la clase Queue es el puntero de escritura. Es decir, la cola indica la posición dentro de la lista en donde la función put() insertará el siguiente dato, y la cabeza indica la posición dentro de la lista de donde la función get() leerá el siguiente dato. Cada vez que put() inserta un elemento la cola se incrementa. Cada vez que get() retira un elemento la cabeza se incrementa. En el siguiente ejemplo se analiza lo que sucede con la cola y la cabeza (punteros de escritura y de lectura de la Lista) cuando se guardan en la cola uno por uno los caracteres 'A', 'B', 'C' y 'D'. Observe que al principio: cola = cabeza = cero. Llenando la cola. <pre> cola | +---+---+---+---+---+ | | | | | | al principio +---+---+---+---+---+ | cabeza </pre> <pre> cola | +---+---+---+---+---+ put('A'); | A | | | | | después de haber agregado el primer elemento +---+---+---+---+---+ | cabeza </pre> ... <pre> cola | +---+---+---+---+---+ | A | B | C | D | | después de haber agregado cuatro elementos +---+---+---+---+---+ | cabeza </pre> Vaciando la cola. <pre> cabeza | +---+---+---+---+---+ | A | B | C | D | | antes de haber retirado elementos +---+---+---+---+---+ </pre> <pre> cabeza | +---+---+---+---+---+ get(); | A | B | C | D | | después de haber retirado un elemento +---+---+---+---+---+ </pre> ... <pre> cabeza | +---+---+---+---+---+ al final | A | B | C | D | | después de haber retirado todos los elementos +---+---+---+---+---+ | cola </pre> Obsérvese que al final el cabeza apunta hacia el mismo elemento que la cola, es decir, la cola vuelve a estar vacía. Puesto que la cola que estamos proyectando reside en un arreglo estático los componentes del arreglo aún están dentro de la misma, salvo que para su recuperación se debería escribir otro método. En una cola dinámica (como se demostrará más adelante) los elementos retirados de la misma se eliminan de la memoria y podría no ser posible su recuperación posterior. '''Nota:''' En el programa que aparece en seguida, al tipo de lista implementado por la clase Queue se le conoce como "lista circular" debido al comportamiento de sus punteros. Es decir si los métodos para escribir o leer detectan que el puntero correspondiente ha sobrepasado el tamaño máximo de elementos permitidos dentro de la cola, éste es puesto a cero. <font size="+1" color="red">Ejemplo: cola en un arreglo estático</font> <source lang="cpp"> /*---------------------------------------------------------------+ + ejemplo de una cola (QUEUE) basada en un arreglo estático + + + + Autor: Oscar E. Palacios + + email: oscarpalacios1@yahoo.com.mx + + + + Manifiesto: + + Este programa puede distribuirse, copiarse y modificarse de + + forma libre. + +---------------------------------------------------------------*/ #include <iostream.h> #define MAX_SIZE 256 /* capacidad máxima */ typedef char almacen[MAX_SIZE]; class Queue { int cabeza; /* puntero de lectura */ int cola; /* puntero de escritura */ int ITEMS; /* número de elementos en la lista */ int ITEMSIZE; /* tamaño de cada elemento */ almacen alma; /* el almacén */ public: // constructor Queue() { cabeza = 0; cola = 0; ITEMS = 0; ITEMSIZE = 1; } // destructor ~Queue() {} // regresa 1 (true) si la lista está vacía int empty() { return ITEMS == 0; } // insertar elemento a la lista int put(int d) { if ( ITEMS == MAX_SIZE) return -1; if ( cola >= MAX_SIZE) { cola = 0; } alma[cola] = d; cola ++; ITEMS ++; return d; } // retirar elemento de la lista int get() { char d; if ( empty() ) return -1; if ( cabeza >= MAX_SIZE ) { cabeza = 0; } d = alma[cabeza]; cabeza ++; ITEMS --; return d; } // regresa el n£mero de elementos en lista int size() { return ITEMS; } }; // fin de la clase Queue // probando la cola int main() { int d; Queue q; for (d='A'; d<='Z'; d++) q.put(d); cout << "Items = " << q.size() << endl; while ( q.size() ) { cout << (char)q.get() << " "; } cout << "\nPara terminar oprima <Enter> ..."; cin .get(); return 0; } </source> <font size="+1" color="red">Ejemplo: cola en un arreglo dinámico</font> <source lang="cpp"> /*---------------------------------------------------------------+ + ejemplo de una cola (QUEUE) basada en un arreglo dinámico + + + + Autor: Oscar E. Palacios + + email: oscarpalacios1@yahoo.com.mx + + + + Manifiesto: + + Este programa puede distribuirse, copiarse y modificarse de + + forma libre. + +---------------------------------------------------------------*/ #include <iostream> using namespace std; typedef char DATA_TYPE; struct nodo { DATA_TYPE data; nodo *next; }; class QueueDin { // atributos int ITEMS, ITEMSIZE; nodo *cola, *cabeza; public: // constructor QueueDin() : cola(NULL), cabeza(NULL), ITEMS(0), ITEMSIZE(sizeof(DATA_TYPE)) {} // destructor ~QueueDin() {} /* agregar componente a la lista */ DATA_TYPE put(DATA_TYPE valor) { nodo *temp; temp = new nodo; if (temp == NULL) return -1; ITEMS ++; temp->data = valor; temp->next = NULL; if (cabeza == NULL) { cabeza = temp; cola = temp; } else { cola->next = temp; cola = temp; } return valor; } // regresa 1 (true) si la lista está vacía int empty() { return ITEMS == 0; } /* retirar elemento de la lista */ DATA_TYPE get() { nodo *temp; DATA_TYPE d; if ( empty() ) return -1; d = cabeza->data; temp = cabeza->next; if (cabeza) delete cabeza; cabeza = temp; ITEMS --; return d; } }; // fin de la clase QueueDin /* punto de prueba */ int main() { QueueDin s; DATA_TYPE d; // llenando la cola for (d='A'; d<='Z'; d++) { s.put(d); cout << d << " "; } cout << endl; // vaciando la cola while ( ! s.empty() ) cout << (DATA_TYPE)s.get() << " "; cout << "\nPara terminar presione <Enter>..."; cin.get(); return 0; }</source> == Colas de doble enlace == Una cola doble es una estructuras en donde cada elemento puede ser insertado y recuperado por la parte del frente (cabeza) o por la parte de atrás (cola) de la lista. A diferencia de una cola sencilla, en donde solo se necesitan un método para leer y otro para escribir componentes en la lista, en una doble cola debe haber dos métodos para leer ( uno para leer por el frente y uno para leer por atras ) y dos métodos para escribir ( uno para escribir por el frente y uno para escribir por atras ). En el programa que se verá en seguida, se simula el comportamiento de una estructura de cola doble con base en un arreglo estático. En dicho programa se declara e implementa la clase '''SDQueue''' con los siguientes métodos: <pre> put_front(), poner un elemento en el frente de la cola put_back(), poner un elemento en la parte trasera de la cola get_front(), retirar un elemento de la parte frontal de la cola get_back(), retirar un elemento de la parte trasera de la cola empty(), regresa 1 (TRUE) si la cola está vacía size(), número de elementos en la cola </pre> Nota: observe que para los métodos put_front() y get_front() se hace uso de la función memmove(), esto es necesario debido al hecho de que put_front() tiene que mover una posición hacia atrás todos los elementos en la lista antes de insertar el componente indicado; por otro lado, la función get_front() tiene que mover una posición hacia adelante a todos los elementos que le siguen al primer elemento. <font size="+1" color="red">Ejemplo: doble cola en un arreglo estático</font> <source lang="cpp"> /*------------------------------------------------------------------+ + ejemplo de una cola doble (DQUEUE) basada en un arreglo est tico + + + + Autor: Oscar E. Palacios + + email: oscarpalacios1@yahoo.com.mx + + + + Manifiesto: + + Este programa puede distribuirse, copiarse y modificarse de + + forma libre. + +------------------------------------------------------------------*/ #include <iostream.h> #include <mem.h> // por memmove // using namespace std; #define MAX_SIZE 256 #define t_error -1; typedef int DATA_TYPE; // máximo número de elementos typedef int almacen[MAX_SIZE]; class SDQueue { // atributos int itemsize; // tamaño de cada elemento int items; // número de elementos int cola, cabeza; // punteros de lectura y escritura almacen alma; // el almacén o arreglo public: // constructor SDQueue() : cola(0), cabeza(0), items(0), itemsize(sizeof(DATA_TYPE)) {} // destructor ~SDQueue() {} int empty() { return items == 0; } int size() { return items; } /* agregar componente en la parte trasera de la lista */ DATA_TYPE put_back(DATA_TYPE valor) { if (items == MAX_SIZE) return t_error; alma[cola] = valor; items ++; cola ++; return valor; } /* agregar componente en la parte delantera de la lista */ DATA_TYPE put_front(DATA_TYPE valor) { if (items == MAX_SIZE) return t_error; memmove((void *)&alma[cabeza+1], (void*)&alma[cabeza], items*itemsize); alma[cabeza] = valor; items ++; cola ++; return valor; } /* retirar elemento de la parte frontal de la lista */ DATA_TYPE get_front() { DATA_TYPE d; if ( empty() ) return t_error; items --; cola --; d = alma[cabeza]; memmove((void*)&alma[cabeza], (void*)&alma[cabeza+1], items*itemsize); return d; } /* retirar elemento de la parte tracera de la lista */ DATA_TYPE get_back() { DATA_TYPE d; if ( empty() ) return t_error; items--; cola --; d = alma[cola]; return d; } }; // fin de la clase SDQueue /* punto de prueba */ int main() { SDQueue s; DATA_TYPE d; for (d='A'; d<='Z'; d++) s.put_back(d); while ( ! s.empty() ) cout << (char)s.get_front() << " "; cout << "\nPara terminar presione <Enter>..."; cin.get(); return 0; } </source> Una cola doblemente encadenada es una estructuras en donde cada elemento puede ser insertado y recuperado por la parte del frente (cabeza) o por la parte de atrás (cola) de la lista. A diferencia de una cola sencilla, en donde solo se necesita un puntero a un siguiente elemento, la estructura del nodo para una doble cola debe poseer un puntero a un posible siguiente elemento y un puntero a otro posible anterior elemento. Por ejemplo, para crear una estructura de nodo con doble enlace para coleccionar números enteros podemos usar la sintaxis: <pre> struct nodo { int data; nodo *next, *prev; }; </pre> Gráficamente podemos imaginar la estructura anterior como: <pre> +------+------+------+ <--| prev | data | next |--> +------+------+------+ </pre> En el programa que se verá en seguida, se simula el comportamiento de una estructura de cola de doble enlace. Para la implementación de la clase DDqueue en el programa se han elegido los métodos: <pre> put_front(), poner un elemento en el frente de la cola put_back(), poner un elemento en la parte trasera de la cola get_front(), retirar un elemento de la parte frontal de la cola get_back(), retirar un elemento de la parte trasera de la cola empty(), regresa 1 (TRUE) si la cola está vacía size(), n£mero de elementos en la cola </pre> <source lang="cpp"> /*---------------------------------------------------------------+ + ejemplo de una cola doblemente enlazada (Dqueue) basada en un + + arreglo dinámico + + + + Autor: Oscar E. Palacios + + email: oscarpalacios1@yahoo.com.mx + + + + Manifiesto: + + Este programa puede distribuirse, copiarse y modificarse de + + forma libre. + +---------------------------------------------------------------*/ #include <iostream.h> #include <conio.h> // using namespace std; typedef char DATA_TYPE; struct nodo { DATA_TYPE data; nodo *next, *prev; }; class DDqueue { int itemsize, items; nodo *cola, *cabeza; public: // constructor DDqueue() : cola(NULL), cabeza(NULL), items(0), itemsize(sizeof(DATA_TYPE)) {} // destructor ~DDqueue() {} /* agregar componente en la parte trasera de la lista */ DATA_TYPE put_back(DATA_TYPE valor) { nodo *temp; temp = new nodo; if (temp == NULL) return -1; temp->data = valor; items ++; if (cabeza == NULL ) { temp->next = NULL; temp->prev = NULL; cabeza = temp; cola = temp; } else { cola->next = temp; temp->prev = cola; cola = temp; cola->next = NULL; } return valor; } /* agregar componente en la parte frontal de la lista */ DATA_TYPE put_front(DATA_TYPE valor) { nodo *temp; temp = new nodo; if (temp == NULL) return -1; temp->data = valor; items ++; if (cabeza == NULL ) { temp->next = NULL; temp->prev = NULL; cabeza = temp; cola = temp; } else { cabeza->prev = temp; temp->next = cabeza; cabeza = temp; cabeza->prev = NULL; } return valor; } // regresa true si la lista está vacía int empty() { return items == 0; } /* retirar elemento de la parte frontal lista */ DATA_TYPE get_front() { nodo *temp; DATA_TYPE d; if ( empty() ) return -1; items --; d = cabeza->data; temp = cabeza->next; if (cabeza) delete cabeza; cabeza = temp; return d; } /* retirar elemento de la parte trasera de la lista */ DATA_TYPE get_back() { nodo *temp; DATA_TYPE d; if ( empty() ) return -1; items--; d = cola->data; temp = cola->prev; if (cola) delete cola; cola = temp; return d; } }; // fin de la clase DDqueue /* punto de prueba */ int main() { clrscr(); DDqueue s; DATA_TYPE d; // insertando elementos en la parte tracera for (d='A'; d<='Z'; d++) s.put_back(d); // insertando en la parte delantera for (d=9; d>=0; d--)s.put_front(d+'0'); // vaciando la lista while ( ! s.empty() ) cout << (DATA_TYPE)s.get_front() << " "; cout << "\nPara terminar presione <Enter>..."; cin.get(); return 0; }</source> </div> {| align="center" cellpadding="12" |- | font color="blue" | ← [[Programación en C++/Punteros|Punteros]] | [[#Introducción|Arriba]] | font color="blue" | [[Programación en C++/Plantillas|Plantillas]] → |} {{AutoCat}} pfdr0e60gpa34i0twu4whu9xbpm649h Programación en C++/Excepciones 0 20073 427941 405863 2026-07-16T04:35:59Z Mazbel 57931 actualización 427941 wikitext text/x-wiki {| align="center" cellpadding="12" |- | ← [[Programación en C++/Plantillas|Plantillas]] | [[Programación en C++/Librería Estándar de Plantillas|Librería Estándar de Plantillas]] → |} = Excepciones. Motivación histórica = <div style="background:#fffeee; text-align:justify; padding:40px"> Primeramente, antes de entrar en el tema de las excepciones en programación, se ha de matizar en el concepto de qué son las excepciones, vistas desde un punto de vista fuera y dentro del mundo de la programación. En el lenguaje humano, una excepción es un elemento excluyente de una regla, y de forma convencional se ha extendido esta definición. En el lenguaje máquina, una excepción se trata, de forma general, de algo que no se espera que ocurra, pero que puede ocurrir, similar al tratamiento de errores, pero de los errores en tiempo de ejecución. A veces estas excepciones, para una máquina, no son casos que no deberían estar contemplados, tal y como un programador se lo asigna, sino que pueden ser indicadores para comprobar que realmente todo está marchando bien o no. En los programas de ordenador hechos en C existió durante mucho tiempo la costumbre de usar el comando "goto" (también implementada en C++), pero éste se ha ido eliminando progresivamente de casi todos y cada uno de los códigos y programas que han ido surgiendo. El significado de la función 'goto' no forma parte del libro actual, pero se pueden buscar referencias por internet donde se especifique con más detalle qué es. Como una de las formas de control de errores más usuales era con goto, se usaron otras variantes, como las aserciones de código (assertions, en inglés) o, con la llegada de la programación orientada a objetos, de los comandos try, catch y throw.</div> = Conformación de los bloques try y catch = <div style="background:#fffeee; text-align:justify; padding:40px"> Por norma general, los comandos try y catch conforman bloques de código. Cada uno de estos bloques se recomienda, aunque sea de una única línea, envolverlos en llaves, como muestra el siguiente ejemplo: <source lang=cpp style="font-size:14px;"> // ...código previo... try { // bloque de código a comprobar } catch( tipo ) // Ha ocurrido un suceso en el try que se ha terminado //la ejecución del bloque y catch recoge y analiza lo sucedido { // bloque de código que analiza lo que ha lanzado el try } // ...código posterior... </source> Generalmente entre el try y el catch no se suele insertar código, pero se insta al lector a que lo intente con su compilador habitual y que compruebe si hay errores o no de compilación. </div> = Control de excepciones = <div style="background:#fffeee; text-align:justify; padding:40px"> Una excepción es un error que puede ocurrir debido a una mala entrada por parte del usuario, un mal funcionamiento en el hardware, un argumento inválido para un cálculo matemático, etc. Para remediar esto, el programador debe estar atento y escribir los algoritmos necesarios para evitar a toda costa que un error de excepción pueda hacer que el programa se interrumpa de manera inesperada. C++ soporta una forma más directa y fácil de ver tanto para el programador como para los revisores del código en el manejo de excepciones que su símil en el C estándar y esta consiste, tratándose del lenguaje C++, en el mecanismo '''try''', '''throw''' y '''catch'''. La lógica del mecanismo mencionado consiste en: # Dentro de un bloque '''try''' se pretende evaluar una o más expresiones y si dentro de dicho bloque se produce un '''algo que no se espera''' se lanza por medio de '''throw''' una excepción, la misma que deberá ser capturada por un '''catch''' específico.<br /><br /> # Puesto que desde un bloque '''try''' pueden ser lanzados diferentes tipos de errores de excepción es que puede haber más de un '''catch''' para capturar a cada uno de los mismos.<br /><br /> # Si desde un '''try''' se lanza una excepción y no existe el mecanismo '''catch''' para tratar dicha excepción el programa se '''interumpirá''' abruptamente despues de haber pasado por todos los '''catch'''s que se hayan definido y de no haber encontrado el adecuado.<br /><br /> # Los tipos de excepciones lazados pueden ser de un tipo primitivo tal como: '''int''', '''float''', '''char''', etc. aunque normalmente las exepciones son lanzadas por alguna clase escrita por el usuario o por una clase de las que vienen incluidas con el compilador.<br /><br /> En el programa que se listará a continuación muestra un ejemplo de como lanzar una excepción de tipo '''int''' dentro del bloque '''try''', y cómo capturar la excepción por medio de '''catch'''. <br />'''Ejemplo'''<br /> <source lang=cpp style="font-size:14px;"> // Demostración de los comandos try, throw y catch #include <iostream> // Función: main // Recibe: void // Devuelve: int // En la función principal se tratarán los comandos try, throw y catch int main(void) { try // Se intenta hacer el siguiente código { // Aquí puede ir más código... throw 125; //...aunque directamente en este caso se lanza una excepción. } catch(int) // Se captura con un catch de enteros (podría usarse long o char, por ejemplo) { std::cout << "Ha surgido una excepción de tipo entero" << std::endl; // y se muestra por pantalla } std::cin.get(); // Y el programa finaliza. return 0; } </source> == Excepciones genéricas == Como ya se ha mencionado, los errores pueden deberse a una multitud de situaciones muchas veces inesperadas, por tal motivo, en C++ existe una forma de manejar excepciones desconocidas ( genéricas ) y es buena idea que si se está escribiendo un controlador de excepciones incluya un '''catch''' para capturar excepciones inesperadas. Por ejemplo, en el siguiente progama se escribe un '''catch''' que tratará de capturar cualquier excepción inesperada. <source lang=cpp> // Demostración: try, throw y catch #include <iostream> using namespace std; int main() { try { throw 125; } catch(...) { cout << "Ha ocurrido un error inesperado..." << endl; } cin.get(); return 0; }</source> == Excepciones de clases == Si usted está usando una clase escrita por terceras personas o de las que se incluyen con el compilador y desea utilizar el mecanismo '''try''', deberá conocer el tipo de excepción lanzado por dicha clase para así poder escribir el '''catch''' correspondiente para el tratamiento de dicho error. Por ejemplo, la función '''at()''' de la clase '''string''' ( que será estudiada más adelante ) lanza una excepción cuando se trata de leer o escribir un componente fuera de rango. En tales casos usted puede proceder a capturar el error como se muestra en el siguiente programa.<br /> <source lang=cpp> // Compilado y probado exitosamente con Dev-C++ // Demostración: excepción de la clase string #include <iostream> #include <string> using namespace std; int main() { string s = "Hola"; try { cout << s.at(100) << endl; } catch(exception& e) { cout << e.what() << endl; } cin.get(); return 0; }</source> En el programa anterior el método '''at''' de la clase '''string''' lanzará ( throw-up ) un error de excepción, ya que la instrucción '''s.at(100)''' trata de acceder a un elemento fuera de los limites del objeto ( s ). == La clase exception == Tal como se mostró en el programa anterior, los errorres generados por las librerías estándar de C++ pueden ser capturados por un catch que tome un parámetro tipo '''exception'''. Realmente, exception es una clase base de donde usted puede derivar las suyas y sobrescribir los métodos para el tratamiento de excepciones. La clase exception está incluida en la libreria '''&lt;exception&gt;''' y su estructura es la siguiente: <pre>class exception { public: exception() throw() { } virtual ~exception() throw(); virtual const char* what() const throw(); };</pre> En muchos casos bastará con sobrescribir el método '''what()''' en la clase derivada de exception, ya que dicho método es el encargado de generar el mensaje que trata de explicar la naturaleza del error ocurrido. En el programa que veremos en seguida, se da un ejemplo sencillo de cómo crear una clase derivada de la clase exception con el objetivo de sobrescribir el método what(). <source lang=cpp> // Demostración: sobrescritura del método what() #include <iostream> #include <cstdlib> #include <exception> using namespace std; class div_cero : public exception { public: const char* what() const throw() { return "Error: división por cero..."; } }; int main(int argc, char *argv[]) { double N, D; cout << "Probando división" << endl; cout << "Ingrese el numerador :"; cin >> N; cin.clear(); cout << "Ingrese el denominador :"; cin >> D; cin.clear(); try { if (D == 0) throw div_cero(); cout << N << " / " << D << " = " << N/D << endl; } catch(exception& e) { cout << e.what() << endl; } system("PAUSE"); return 0; }</source> ---- Siguiendo la misma metodología mostrada por el programa anterior, usted puede crear clases independientes para capturar errores de excepciones específicas. Por ejemplo, si se desea crear una serie de funciones matemáticas se deben considerar los sucesos de errores tales como: División por cero, Error de dominio, Error de rango, etc. Así, el siguiente programa puede ser un buen ejemplo para que usted escriba sus propios controladores de mensajes de error. Observe cómo en el programa se crea la clase '''ErrorMat''' y dentro de la misma la función '''porque()''' la cual se encargará de desplegar el mensaje de error. Aunque ErrorMat solo ha sido pensada para tratar los posibles errores de rango y errores de dominio, la misma puede rescribirse para capturar todos los errores posibles que puedan resultar a raiz de operaciones matemáticas.<br /><br /> Nota: No deje de observar también, cómo la función independiente '''logaritmo()''' verifica si el parámetro pasado a la misma es 0 o menor que 0 y en tales circunstancias se lanzaría (throw) un error de excepción del tipo '''ErrorMat''' ya que el dominio para la función log() es el de los números positivos y el logaritmo de cero no está definido en los números reales.<br /> <source lang=cpp> // Demostración: try, throw y catch #include <iostream> #include <cmath> using namespace std; static const int EDOMINIO=100; static const int ERANGO=101; class ErrorMat { public: ErrorMat() : motivo(0) {}; ErrorMat(int m) : motivo(m) {}; const char* porque() const throw(); private: int motivo; }; const char* ErrorMat::porque() const throw() { switch (motivo) { case EDOMINIO: return "Error de Dominio ";break; case ERANGO: return "Error de Rango ";break; default: return "Error Desconocido"; //En rigor no debería ocurrir tal Excepción } } double logaritmo(const double n) { try { if (n < 0) throw(ErrorMat(EDOMINIO) ); if (n == 0) throw(ErrorMat(ERANGO) ); return log(n); } catch(ErrorMat& e) { cout << e.porque(); } return 0; } int main() { double r = 100; cout << "log(" << r << ") = " << logaritmo(r) << endl; cout << "log(-" << r << ") = " << logaritmo(-r) << endl; cin.get(); return 0; }</source> for(d/dx r,d/dx r>=double,r++){ if(double&&int>=cacho){ return try; } } </div> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Plantillas|Plantillas]] | [[#Control de excepciones|Arriba]] | [[Programación en C++/Librería Estándar de Plantillas|Librería Estándar de Plantillas]] → |} {{AutoCat}} dejq72ilbe2wq9rwf8b8rzsglwqbjkc Programación en C++/Plantillas 0 20107 427940 363826 2026-07-16T04:35:44Z Mazbel 57931 actualización 427940 wikitext text/x-wiki Editores:<br /> [mailto:oscarpalacios1@yahoo.com-mx Oscar E. Palacios] {| align="center" cellpadding="12" |- | ← [[Programación en C++/Estructuras II|Estructuras II]] | [[Programación en C++/Excepciones|Excepciones]] → |} = Plantillas = <div style="padding:40px; background:#fffeee; text-align:justify;"> == Introducción == Con el objeto de explicar la razón de la necesidad de la existencia de las plantillas debemos reflexionar sobre tres paradígmas de programación anteriores, estas son: programación clásica o procedimental, programación estructurada y programación orientada al objeto POO.<br /><br /> '''Programación clásica'''<br /><br /> En el tipo de programación conocida como clásica existe una clara diferenciación entre los datos y su manipulación, es decir, entre los datos y el conjunto de algoritmos para manejarlos. Los datos son tipos muy simples y generalmente los algoritmos se agrupan en funciones orientadas de forma muy específica a los datos que deben manejar. Por ejemplo, si se escribe una función ( sort ) para ordenar en forma ascendente o descendente los números contenidos en un arreglo de números enteros, dicha función puede aplicarse a cualquier arreglo de enteros más no a arreglos de otro tipo. Aun así, la programación clásica provee el soporte necesario para la reutilización de código ya que el código de la función se escribe solamente una vez y su reutilización se da por medio de un mecanismo conocido como llamada de función.<br /><br /> '''Programación estructurada'''<br /><br /> En la medida en que los datos que había de manipular se iban haciendo cada vez más complejos se busco la forma de agruparlos de alguna manera bajo un mismo nombre, es así como surjen las estructuras de datos. Muchos autores se refieren a la programación estructura como a la suma de funciones y/o procedimientos más estructura de datos.<br /><br /> '''Programación Orientada al Objeto'''<br /><br /> La Programación Orientada al Objeto ( POO ) introduce nuevas facilidades y se extiende el concepto de dato, permitiendo que existan tipos más complejos, es decir, si la programación estructurada establece las bases para la manipulación de funciones y datos estructurados, la POO establece las bases para manipular datos y funciones como un solo objeto. Esta nueva habilidad viene acompañada por ciertas mejoras adicionales: la posibilidad de ocultación de determinados detalles internos irrelevantes para el usuario y la capacidad de herencia simple o múltiple.<br /><br /> <blockquote>'''Notas:''' El ocultamiento de código así como la herencia están presentes ( en una forma simple ) en la programación estructurada, y los mismos adquieren mucha más relevancia en la POO. Por ejemplo, en la programación estructurada si usted escribe una librería de funciones, al usuario de dicha librería solamente le informará de la existencia de tal o cual función, así como el objetivo y la forma correcta para comunicarse con estas, pero no es necesario que se le explique el funcionamiento interno de las mismas. Por otro lado, es bien conocido que lenguajes tales como Pascal y C, por ejemplo, dan el soporte para la creación de datos estructurados ( Record en Pascal, y struct en C ), y que dichas estructuras pueden contener a otras estructuras previamente definidas. De tal manera vemos como a los usuarios de las funciones se les oculta el código de las mismas, y que una estructura que contiene a otra hereda los miembros de la estructura contenida.</blockquote> '''Programación genérica'''<br /><br /> La programación genérica está mucho más centrada en los algoritmos que en los datos, y su postulado fundamental puede sintetizarse en una palabra: generalización. Significa que, en la medida de lo posible, los algoritmos deben ser parametrizados al máximo y expresados de la forma más independiente posible de detalles concretos, permitiendo así que puedan servir para la mayor variedad posible de tipos y estructuras de datos.<br /><br /> Con el objetivo de mostrar de una manera practica las diferencias entre los tres tipos de programación mencionados arriba tomaremos como base el modelo de una vieja estructura de datos amiga de los programadores, me refiero a un array, también conocida por muchos como arreglo, tabla o lista. Para no entrar en polemicas de estándarización de nombrado en este capítulo diremos que la estructura modelo con la que trabajaremos es un vector ( arreglo unidimensional ). Pues bien, dado un vector cualquiera se presenta la necesidad de crear un cierto número de funciones que sean las encargadas de la manipulación de los datos dentro del vector. Para comenzar, podemos pensar en las funciones: # <font color=#0000ff>mostrar,</font> para desplegar o imprimir los elementos del vector.<br /><br /> # <font color=#0000ff>ordenar,</font> para ordenar los elementos del vector.<br /><br /> # <font color=#0000ff>buscar,</font> para determinar la presencia o ausencia de un determinado elemento dentro del vector.<br /><br /> # <font color=#0000ff>insertar,</font> para agregar componentes al vector.<br /><br /> # <font color=#0000ff>eliminar</font>, para quitar componentes del vector.<br /><br /> # <font color=#0000ff>capacidad,</font> para obtener la capacidad máxima del vector.<br /><br /> # <font color=#0000ff>cuenta,</font> para obtener el número de elementos actuales contenidos por el vector.<br /><br /> Al hacer un análisis muy detallado del problema planteado y al tratar de resolver el mismo mediante la programación clásica, veremos que, si bien es cierto que se puede llegar a la solución, para lograrlo se tendrían que establecer una serie de medidas que nos permitierán controlar de alguna manera detalles tales como: el total de elementos soportados por el vector y el número de elementos actuales contenidos por el vector. Por ejemplo, con la instrucción: <pre>int vector[120];</pre> se crea un arreglo con capacidad para 120 componentes de tipo entero . Ahora bien, el compilador sabe perfectamente que deberá reservar un espacio de 120 enteros para la memoria del vector, pero no se garantiza que cualquier función trate de leer o escribir datos fuera de los limites del vector. Es decir, nuestro programa no podría saber el tamaño del vector a menos que usaramos algún truco, por ejemplo usar el primer elemento del vector para contener el tamaño del mismo. Otra forma de alcanzar una solución, sería que a cada una de las funciones que tengan que ver con el vector se le pasará los parámetros: puntero de vector y número de elementos en el vector, de tal manera que, por ejemplo, la función mostrar podría declararse como: <source lang=cpp>int mostrar(int *vector, int cuenta);</source> == Un paso hacia adelante == Si continuamos en el ámbito de la programación clásica podemos dar un paso más si es que nos valemos de tipos estructurados más elaborados. Por ejemplo, podemos definir una estructura llamada vector la cual posea los miembros: capacidad, cuenta y data como se muestra en seguida: <source lang=cpp>typedef struct vector { int capacidad; int cuenta; int *data; };</source> De tal manera que podriamos escribir funciones que operen sobre un solo parámetro del tipo estructurado vector. Por ejemplo, la función mostrar podría declararse como: <pre>int mostrar(vector *v);</pre> En este punto tendríamos que detenernos y pensar en lo siguiente:<br /> La estructura vector ( definida arriba con typedef ) es solamente un nuevo tipo de dato, es decir, podemos declarar tantas copias ( variables ) de la misma como sean necesarias, pero carece de un método constructor adecuado. Por ejemplo, la declaración: <pre>vector nombre_var;</pre> es válida siempre y cuando que el tipo vector ya haya sido definido, pero la variable nombre_var contendrá sólo basura hasta que no se establezcan los valores adecuados para cada uno de sus miembros ( capacidad, cuenta y data ). == Una mejor solución == Para el tipo de problemas como en el ejemplo vector y otros similares, surge la POO, misma que facilita en gran medida la solución del mismo, pero aún queda pendiente la resolución a otro problema, es decir, hasta aquí hemos mencionado la estructura vector como un contenedor de números enteros, pero un vector podría contener caracteres, números de punto flotante y otros tipos estructurados; y los mismos algoritmos usados para ( mostrar, ordenar, buscar, etc. ) empleados en un vector de enteros, tendrían su aplicación sobre vectores de cualquier tipo. Es así como surge lo que se conoce como PLANTILLAS o lo que es lo mismo, la programación genérica. == La clase vector desde la perspectiva de la POO == Con el objetivo de mostrar en la práctica los conceptos que hemos venido mencionando presentaremos un pequeña implementación de la clase vector. Se debe aclarar que la implementación de la misma se hará para vectores contenedores de datos tipo int solamente. Para simplificar el ejemplo, para la clase vector solamente se implementarán los métodos mostrar(), ordenar() e insertar(), así como un método constructor base y un método destructor. <source lang=cpp> #include <iostream> #include <cstdio> #include <ctime> using namespace std; #define VECTOR_DEFAULT_SIZE 128 class vector { // atributos int capacidad; int cuenta; int *data; public: // constructor base vector() { capacidad = VECTOR_DEFAULT_SIZE; cuenta = 0; data = new int[VECTOR_DEFAULT_SIZE]; } // destructor ~vector() { delete[] data; } // despliega todos los elementos contenidos por el vector void mostrar() { for (int t = 0; t < cuenta; t++) cout << "elemento " << t << ", valor " << data[t] << endl; } // inserta un elemento al vector int insertar(int d) { if (cuenta == capacidad) return -1; data[cuenta] = d; cuenta ++; return cuenta; } // ordena en forma ascendente los elementos del vector void ordenar() { int i, j, temp; int fin = cuenta; i = 0; while (i < fin ) { for ( j = i ; j < fin-1; j++) if ( data[j] > data[j+1] ) { temp = data[j]; data[j] = data[j+1]; data[j+1] = temp; } fin --; } } }; #define MAX 10 int main() { vector v; srand( time(NULL) ); for (int r = 0; r < MAX; r++) v.insertar( rand() % 100); cout << "\nvector v sin ordenar\n"; v.mostrar(); v.ordenar(); cout << "\nvector v ordenado\n"; v.mostrar(); getchar(); return 0; }</source> == Una plantilla para la clase vector == Una vez que se llegado al entendimiento de la programación estructurada así como de la programación orientada al objeto, se puede observar que, si bien es cierto que ambas ofrecen soluciones a problemas fundamentales también es cierto que las soluciones se presentan como casos especializados. Esta última afirmación la podemos ilustrar si nos fijamos en el caso del programa presentado anteriormente, en dicho programa se presenta la clase vector como un contenedor especial para números enteros (int), ahora bien, si prestamos aún aun más atención podemos llegar a la conclusión de que todos los algoritmos o funciones aplicadas en la clase vector pueden operar con cualquier otro tipo de datos y, por lo tanto, la única diferencia sería el tipo de datos contenidos por el vector. De tal manera que aparece lo que se llama generalización o '''programación genérica''' y esta, a su vez, nos permite la creación de plantillas basadas en una lógica operatoria previamente concebida. Con el objetivo de mostrar un ejemplo práctico retomaremos la clase vector del programa de la sección anterior y crearemos, a raiz del mismo, una plantilla. La plantilla resultante tendrá la capacidad para crear vectores de cualquier tipo. <source lang=cpp> #include <iostream> #include <cstdio> #include <ctime> using namespace std; #define VECTOR_DEFAULT_SIZE 128 template <class T> class vector { // atributos int capacidad; int cuenta; T *data; public: // constructor base vector() { capacidad = VECTOR_DEFAULT_SIZE; cuenta = 0; data = new T[VECTOR_DEFAULT_SIZE]; } // destructor ~vector() { delete[] data; } void mostrar(); int insertar(T d); void ordenar(); }; // implementación del método mostrar template <class T> void vector<T>::mostrar() { for (int t = 0; t < cuenta; t++) cout << "elemento " << t << ", valor " << data[t] << endl; } // implementación del método insertar template <class T> int vector<T>::insertar(T d) { if (cuenta == capacidad) return -1; data[cuenta] = d; cuenta ++; return cuenta; } // implementación del método ordenar template <class T> void vector<T>::ordenar() { T temp; int i, j, fin = cuenta; i = 0; while (i < fin ) { for ( j = i ; j < fin-1; j++) if ( data[j] > data[j+1] ) { temp = data[j]; data[j] = data[j+1]; data[j+1] = temp; } fin --; } } #define TEST 10 int main() { // prueba de un vector de números de punto flotante vector<double> v; srand( time(NULL) ); for (int r = 0; r < TEST; r++) v.insertar( (rand() % 10) * 0.5); cout << "\nvector v sin ordenar\n"; v.mostrar(); v.ordenar(); cout << "\nvector v ordenado\n"; v.mostrar(); // prueba de un vector de números long int vector<long int> v2; srand( time(NULL) ); for (int r = 0; r < TEST; r++) v2.insertar( (rand() % 100) ); cout << "\nvector v2 sin ordenar\n"; v2.mostrar(); v2.ordenar(); cout << "\nvector v2 ordenado\n"; v2.mostrar(); getchar(); return 0; }</source> </div> {| align="center" cellpadding="12" |- | ← [[Programación en C++/Estructuras II|Estructuras II]] | [[#Introducción|Arriba]] | [[Programación en C++/Excepciones|Excepciones]] → |} {{AutoCat}} tnuxyhb9xzfk59sxriy4c2ihgm70yky Programación en C++/Problemas Resueltos 0 25799 427944 304567 2026-07-16T04:37:16Z Mazbel 57931 actualización 427944 wikitext text/x-wiki <div style="padding:40px; background:#fffeee; text-align:justify" > '''<big>Problema 1</big>''' Dados dos puntos determinar si la recta es creciente, decreciente, vertical , horizontal. '''<big>Solucion:</big>''' '''<big>Marco teórico:</big>''' Sabemos que, dados dos puntos <math> P=\left(a,b\right)</math> y <math>Q=\left(c,d\right)</math> entonces hay una recta que los contiene. La pendiente de esta recta es determinada por <math>m=\frac{a-c}{b-d}</math>. Podemos determinar si una recta es creciente, decreciente, vertical. horizontal analizando su pendiente, estos son los casos: # Si <math>m > 0</math>, entonces la recta es creciente. # Si <math>m < 0</math>, entonces la recta es decreciente. # Si <math>m = 0</math>, entonces la recta es horizontal, es decir cuando <math>a=c</math> # La recta sera vertical, si <math>b=d</math>. Con esta información podemos entonces diseñar nuestro codigo. <pre lang=cpp> #include <iostream> using namespace std; int main() { double a,b,c,d,m; cout<<"Digite dos puntos P=(a,b) y Q(c,d):"<<endl<<endl; cout<<"a : "; cin>>a; cout<<"b : "; cin>>b; cout<<"c : "; cin>>c; cout<<"d : "; cin>>d; cout<<endl; if (b!=d) { m = (a-c)/(b-d); if (m>0) {cout<<"La recta determinada por estos dos puntos P=("<<a<<","<<b<<") y Q("<<c<<","<<d<<") es Creciente"<<endl;} else {cout<<"La recta determinada por estos dos puntos P=("<<a<<","<<b<<") y Q("<<c<<","<<d<<") es Decreciente"<<endl;} if (m==0) {cout<<"La recta determinada por estos dos puntos P=("<<a<<","<<b<<") y Q("<<c<<","<<d<<") es Horizontal"<<endl;} } else { if(a!=c) {cout<<"La recta determinada por estos dos puntos P=("<<a<<","<<b<<") y Q("<<c<<","<<d<<") es Vertical"<<endl;} else {cout <<"Lo sentimos!. Por un mismo punto pasan infinitas rectas..."<<endl;} } cin.get(); /*Recuerda que esta linea es por si usas Windows*/ cin.get(); return 0; } </pre> '''<big>Problema 2</big>''' Utilizar el método burbuja de ordenamiento sin recurrir a punteros '''<big>Solucion:</big>''' <source lang="cpp"> // ALGORITMO DE ORDENAMIENTO BURBUJA // Creador por Joseph, 15 de mayo de 2010; licencia GNU // increiblecrean.blogspot.com #include <iostream> using namespace std; int main() { //DATOS //establecer array a ordenar int lista[6] = {1, 9, 3, 10, -6, 0}; //obtener tamaño array int tamanyo = sizeof(lista)/sizeof(int); // Variables temporales int temp, a = 0; //MOSTRAR ARRAY ORIGINAL cout << "Este es el array original:" <<endl; for (int n = 0; n < tamanyo; n++) cout << lista[n] << ", "; cout << endl << endl; //ORDENAMIENTO for (int limite = tamanyo - 1; limite >= 0;limite--) { while (a < limite) { /* Se puede cambiar el signo (> ó <) para ordenar de menor a mayor o viseversa */ if (lista[a] < lista[a + 1]) { temp = lista[a]; lista[a] = lista[a + 1]; lista[a + 1] = temp; } a++; } a = 0; } //MOSTRAR ARRAY MODIFICADO cout << "Este es el array ordenado:" <<endl; for (int n = 0; n < tamanyo; n++) cout << lista[n] << ", "; return 0; } </source> </div> {{AutoCat}} luar1y5ptr4hqc66e6h1kcr85132n0g Programación de videojuegos en Linux 0 26734 427886 192557 2026-07-15T21:54:10Z Antimundo 74354 Categorizar con estantes 427886 wikitext text/x-wiki == Prólogo == GNU/Linux es una excelente plataforma para el desarrollo de juegos de carácter informal o no comercial, debido a la facilidad para conseguir apoyo de la comunidad, la gran cantidad de librerías y software especializado para la creación de videojuegos y el espíritu de ayuda y mejora que impera sobre la filosofía ''open source''. Como ayuda para los desarrolladores novatos, o a los experimentados que desean adentrarse en el mundo de la creación de videojuegos para esta plataforma, aparece este wikilibro, destinado a guiar al usuario en sus primeros pasos para la creación de videojuegos sencillos para GNU/Linux. === ¿Para quién es este libro? === Este libro está dirigido principalmente a todos los usuarios y programadores que deseen dar sus primeros pasos en la programación de videojuegos para el entorno GNU/Linux. Puede que a los usuarios experimentados no les resulte de mucha ayuda puesto que está enfocado al usuario novato con pocos o ningún conocimiento sobre programación de videojuegos. == Índice de contenidos == <noinclude> # [[/Introducción|Introducción]] # [[/Videojuegos con Python, SDL y PyGame|Videojuegos con Python, SDL y PyGame]] ## [[/Nociones básicas de PyGame|Nociones básicas de PyGame]] ## [[/Ejemplo PyPong|Ejemplo PyPong]] ## [[/Ejemplo PyStar Wars|Ejemplo PyStar Wars]] ## [[/Ejemplo Mini-rpg|Ejemplo Mini-rpg]] ## [[/Ejemplo Plataformas|Ejemplo Plataformas]] # [[/C|Videojuegos con C y SDL]] </noinclude> == Enlaces == Nociones de programación en C * [[Programación en C]] Nociones de programación en Python * [[Inmersión en Python|Programación en Python]] == Cómo contribuir con este libro == Contribuir con este libro es muy simple primero deberías [[Especial:Entrar|registrarte un usuario y entrar]] (esto no es necesario pero si muy conveniente) a Wikilibros, para que podamos identificar tus ediciones. Luego, si nunca has contribuido en un proyecto de wikipedia o en otro wiki deberías leer el [[Wikilibros:Manual| manual de uso de wikilibros]]. Este libro solo es un esbozo y necesita ser ampliado. Por favor, si tienes conocimientos y ganas de ayudar, puedes ampliar y añadir cualquiera de estas secciones del libro: * Anexo * Videojuegos con C y SDL * Ejemplos de videojuegos con C y SDL * Videojuegos con otros lenguajes de programación * Videojuegos 3D con OpenGL También será agradecido cualquier otro aporte que consideres necesario para el libro. {{Estantes|Desarrollo de videojuegos}} kuuwlglkwmeh4kv89j18ht093i4p0j9 Programación en C++/Biblioteca Estándar de Plantillas 0 26932 427942 304541 2026-07-16T04:36:15Z Mazbel 57931 actualización 427942 wikitext text/x-wiki Editores:<br /><br /> [mailto:oscarpalacios1@yahoo.com Oscar E. Palacios] == Biblioteca estándar de plantillas == {| width="100%" |- bgcolor="#eeeeff" | width="80" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Vectores|Vectores]] | width="120" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Vectores#Colas de doble fin ( deque )|Colas de doble fin]] | width="80" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Listas|Listas]] | width="96" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Pilas|Pilas (stack)]] | width="120" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Colas|Colas (queue)]] | width="120" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Colas#Colas con prioridad|Colas con prioridad]] | width="60" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Sets|Sets]] | width="60" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Maps|Maps]] | width="60" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Bitsets|Bitsets]] | width="80" align="center" | [[#Iteradores|Iteradores]] | |} <div style="background:#fffeee; text-align:justify; padding:40px;"> La STL (Standard Template Library) de C++ es una colección genérica de plantillas de clases y algoritmos que permite a los programadores implementar fácilmente estructuras estándar de datos como colas (queues), listas (lists), y pilas (stacks). La STL de C++ provee a los programadores con lo constructores siguientes, agrupados en tres categorias: '''Secuencias (sequences)'''<br /> # C++ Vectors # C++ Lists # C++ Double-Ended Queues '''Adaptadores de contenedor (Container Adapters)'''<br /> # C++ Stacks # C++ Queues # C++ Priority Queues '''Contenedores asociativos (Associative Containers)'''<br /> # C++ Bitsets # C++ Maps # C++ Multimaps # C++ Sets # C++ Multisets La idea detras de la STL de C++ es que la parte dificil en el uso de estructuras complejas de datos ya ha sido previamente completada. Por ejemplo, si un programador desea usar un stack de enteros, todo lo que tiene que hacer es escribir el código: <source lang=cpp>stack<int> myStack;</source> Con un minimo de esfuerzo, él o ella puede usar la función push() para ingresar enteros al stack; y la función pop() para retirar enteros del stack. A través de la magia de las plantillas de C++, se puede especificar cualquier tipo de dato, no sólo enteros. La clase Stack de la STL provee la funcionalidad genérica de un stack, sin importar el tipo de dato en el stack. </div> {| width="100%" |- bgcolor="#eeeeff" | width="80" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Vectores|Vectores]] | width="120" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Vectores#Colas de doble fin ( deque )|Colas de doble fin]] | width="80" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Listas|Listas]] | width="96" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Pilas|Pilas (stack)]] | width="120" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Colas|Colas (queue)]] | width="120" align="center" | [[Programación en C++/Biblioteca Estándar de Plantillas/Colas#Colas con prioridad|Colas con prioridad]] | width="80" align="center" | [[#Iteradores|Iteradores]] | |} == Iteradores == <div style="background:#fffeee; text-align:justify; padding:40px;"> El termino '''iterar''' significa (en palabras sencillas) el método o forma que se usa para poder navegar sobre los elementos de una lista específica. Luego, un iterador es como una especie de "puntero especial" que nos permite leer o escribir valores sobre cada uno de los elementos en una lista. Los iteradores pueden ser comparados con los índices que se emplean para leer o escribir valores sobre los elementos de una lista. Igual a lo que sucede con los tipos de datos dentro de un arreglo primitivo en donde para leer o escribir valores sobre los elementos se tiene que prestar atención al tipo de dato, un iterador tiene que ser del tipo de dato que posee la lista. En ese sentido, si tenemos por ejemplo un vector que posee datos de tipo entero ('''int''') entonces el iterador tendrá que ser de tipo entero; si por el contrario se tiene un vector cuyos datos son del tipo cadena ('''string''') entonces el iterador tiene que ser del tipo cadena.<br /><br /><font size="4" color="red">Sintaxis</font><br /><br />La sintaxis general para la declaración de un iterador es:<br /><br /><font size="4">NombrePlantilla<tipo>::iterator varid;</font><br /><br />Donde, {| border="0" width="50%" cellpadding="8" |- | NombrePlantilla || Es el nombre de una STL |- | tipo || Es el tipo usado para la plantilla |- | ::iterator | Es el método para obtener el iterador |- | varid || Es el nombre de la variable |}<br />Por ejemplo, para obtener un iterador a un '''vector''' de tipo '''int''' podemos usar la instruccion:<br /><br /><font size="4">vector <int>::iterator el_iterador;</font><br /><br /> A manera de ejemplo, vamos a mostrar un programa en el que se usará un iterador de tipo '''char'''. ::Nota: en el programa se hace uso de los métodos '''begin''' para obtener un iterador hacia el inicio del vector, y '''end''' para obtener un iterador hacia el final del mismo.<br /><br /> <source lang=cpp> // Demostracion del uso de iteradores // probado en: Dev-C++ 4.9.9.2 #include <cstdlib> #include <iostream> #include <vector> using namespace std; int main(int argc, char *argv[]) { vector<char> v; for (int x = 'A'; x <= 'Z'; x++) v.push_back(x); // obtenemos un iterator del tipo char vector<char>::iterator it; // lectura y despliegue de datos cout << "\ndesplegando datos" << endl; for( it = v.begin(); it != v.end(); it++ ) cout << *it << endl; system("PAUSE"); return EXIT_SUCCESS; }</source> == Iteradores reversos == La STL de C++ permite que los elementos de las listas creadas puedan ser navegados en orden "normal", es decir desde el primero hasta el último de los elementos agregados a la lista, y para dichas tareas se usa un iterador normal. También, los elementos pueden navegarse en orden "reverso" y en tales casos se usa un iterador en reverso ( '''reverse_iterator''' ). Un ejemplo de reverse_iterator se muestra en el siguiente programa.<br /><br /> Notas: * Se debe de observar que para obtener iteradores normales se usan (generalmente) los métodos '''begin()''' y '''end()''', mientras que que para obtener iteradores reversos se emplean los métodos '''rbegin()''' y '''rend()'''. * Los iteradores reversos se comportan de manera inversa. Por ejemplo, para obtener un iterador que vaya desde el final hasta el inicio de los elementos, se usa la función '''rbegin()''' la cual regresará un iterador para procesar la lista desde el último hasta el primero de los elementos. En contraparte, la función '''begin()''' regresa un iterador para procesar la lista desde el primero hasta el último de los elementos. Es decir, begin() regresa una referencia hacia el primer elemento, mientras que rbegin() regresa una referencia hacia el último elemento. <source lang=cpp> // Demostracion del uso de iteradores reversos // probado en: Dev-C++ 4.9.9.2 #include <cstdlib> #include <iostream> #include <list> using namespace std; int test() { list<char> v; for (int x = 'A'; x <= 'Z'; x++) v.push_back(x); cout << endl; out << "orden original" << endl; // creamos un iterator normal list<char>::iterator i = v.begin(); while(i != v.end() ) { cout << *i++ << " "; } cout << endl; cout << "orden inverso" << endl; // creamos un iterator reverso list<char>::reverse_iterator ri = v.rbegin(); while(ri != v.rend() ) { cout << *ri++ << " "; } cout << endl; return 0; } int main(int argc, char *argv[]) { test(); system("PAUSE"); return EXIT_SUCCESS; } </source> </div> {{AutoCat}} 7x02ypak1cu51fny8hfja7k6bean14f Plantilla:+Portada/f 10 32350 427917 316813 2026-07-16T04:15:51Z Mazbel 57931 actualización 427917 wikitext text/x-wiki __NOTOC__ {| {{#if:{{{ancho|}}}|{{+Tabla|{{{ancho}}}}}|{{+Tabla|80%}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}| {{#if:{{{sección2|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección2}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección6|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección6}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección10|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección10}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección14|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección14}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección18|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección18}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección22|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección22}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección26|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección26}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección30|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección30}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|relleno=10|borde={{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}| {{RGB|oliva9}}}}|fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}0}}| {{RGB|oliva0}}}}|alinear=justify|redondeo={{{redondeo|0}}}|ancho=50%|columnas=2}}|{{+Portada/encabezado |t ={{{título|{{{nombre|{{PAGENAME}}}}}}}} |s ={{{subtítulo|{{Variable|subtítulo}}}}} |at ={{Variable|alineartit}} |info={{{nombre|{{PAGENAME}}}}}/Info |img =auto |i ={{{imagen|{{Variable|imagen}}}}} |ai ={{{alinearimg|{{Variable|alinearimg|center}}}}} |ti ={{{tamañoimagen|{{Variable|tamañoimagen}}}}} }}{{+Botón |fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}5}}|{{RGB|oliva5}}}} |título=[[{{{nombre}}}/Índice|Índice]] • [[{{{nombre}}}/Introducción|Introducción]] • [[{{{nombre}}}/Texto completo|Texto completo]] |redondeo={{{redondeo|0}}} |tamaño=115% |estilo=font-weight:bolder}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}|{{#if:{{{sección1|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección1}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección5|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección5}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección9|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección9}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección13|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección13}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección17|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección17}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección21|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección21}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección25|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección25}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección29|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección29}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} {{+SecciónA |tono={{#if:{{{tonoenlaces|}}}|{{{tonoenlaces}}}|{{#if:{{{tono|}}}|{{{tono}}}|azul}}}} |libro={{{nombre}}} |imagen={{{imagenlink|Nuvola_filesystems_www.png}}} |sección=Enlaces |contenido={{:{{{nombre}}}/Enlaces}} |redondeo={{{redondeo|0}}} |estilo=margin:{{#if:{{{rutacarrusel|}}}{{{sección1|}}}{{{sección5|}}}{{{sección9|}}}{{{sección13|}}}{{{sección17|}}}{{{sección21|}}}{{{sección25|}}}{{{sección29|}}}|10px 0px 0px|0px}};}} {{+SecciónA |tono={{#if:{{{tonoedición|}}}|{{{tonoedición}}}|{{#if:{{{tono|}}}|{{{tono}}}|gris}}}} |libro={{{nombre}}} |imagen={{{imagenedit|Gnome-mime-application-text.svg}}} |sección=Página de edición |contenido={{#if:{{{textoedición|}}}|{{{textoedición}}}|Este libro se encuentra en construcción, para ello dispone de una [[{{{nombre}}}/Página de edición|página de edición]], donde se coordina su construcción.}} |redondeo={{{redondeo|0}}}}} |---- | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección3|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección3}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección7|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección7}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección11|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección11}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección15|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección15}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección19|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección19}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección23|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección23}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección27|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección27}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección4|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección4}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección8|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección8}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección12|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección12}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección16|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección16}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección20|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección20}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección24|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección24}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección28|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección28}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} |} {{#ifeq:{{NAMESPACE}}|Plantilla||[[Categoría:Libro:{{{nombre}}}| ]]}} <noinclude>{{documentación|Plantilla:+Portada/uso}}</noinclude> jf734x4dwcbultdu47mrc4pemmncko6 427945 427917 2026-07-16T04:42:36Z Mazbel 57931 corrección de cat. 427945 wikitext text/x-wiki __NOTOC__ {| {{#if:{{{ancho|}}}|{{+Tabla|{{{ancho}}}}}|{{+Tabla|80%}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}| {{#if:{{{sección2|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección2}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección6|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección6}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección10|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección10}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección14|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección14}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección18|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección18}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección22|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección22}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección26|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección26}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección30|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección30}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|relleno=10|borde={{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}| {{RGB|oliva9}}}}|fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}0}}| {{RGB|oliva0}}}}|alinear=justify|redondeo={{{redondeo|0}}}|ancho=50%|columnas=2}}|{{+Portada/encabezado |t ={{{título|{{{nombre|{{PAGENAME}}}}}}}} |s ={{{subtítulo|{{Variable|subtítulo}}}}} |at ={{Variable|alineartit}} |info={{{nombre|{{PAGENAME}}}}}/Info |img =auto |i ={{{imagen|{{Variable|imagen}}}}} |ai ={{{alinearimg|{{Variable|alinearimg|center}}}}} |ti ={{{tamañoimagen|{{Variable|tamañoimagen}}}}} }}{{+Botón |fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}5}}|{{RGB|oliva5}}}} |título=[[{{{nombre}}}/Índice|Índice]] • [[{{{nombre}}}/Introducción|Introducción]] • [[{{{nombre}}}/Texto completo|Texto completo]] |redondeo={{{redondeo|0}}} |tamaño=115% |estilo=font-weight:bolder}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}|{{#if:{{{sección1|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección1}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección5|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección5}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección9|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección9}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección13|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección13}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección17|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección17}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección21|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección21}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección25|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección25}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección29|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección29}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} {{+SecciónA |tono={{#if:{{{tonoenlaces|}}}|{{{tonoenlaces}}}|{{#if:{{{tono|}}}|{{{tono}}}|azul}}}} |libro={{{nombre}}} |imagen={{{imagenlink|Nuvola_filesystems_www.png}}} |sección=Enlaces |contenido={{:{{{nombre}}}/Enlaces}} |redondeo={{{redondeo|0}}} |estilo=margin:{{#if:{{{rutacarrusel|}}}{{{sección1|}}}{{{sección5|}}}{{{sección9|}}}{{{sección13|}}}{{{sección17|}}}{{{sección21|}}}{{{sección25|}}}{{{sección29|}}}|10px 0px 0px|0px}};}} {{+SecciónA |tono={{#if:{{{tonoedición|}}}|{{{tonoedición}}}|{{#if:{{{tono|}}}|{{{tono}}}|gris}}}} |libro={{{nombre}}} |imagen={{{imagenedit|Gnome-mime-application-text.svg}}} |sección=Página de edición |contenido={{#if:{{{textoedición|}}}|{{{textoedición}}}|Este libro se encuentra en construcción, para ello dispone de una [[{{{nombre}}}/Página de edición|página de edición]], donde se coordina su construcción.}} |redondeo={{{redondeo|0}}}}} |---- | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección3|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección3}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección7|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección7}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección11|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección11}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección15|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección15}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección19|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección19}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección23|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección23}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección27|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección27}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección4|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección4}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección8|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección8}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección12|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección12}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección16|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección16}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección20|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección20}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección24|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección24}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección28|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección28}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} |} {{#ifeq:{{NAMESPACE}}|Plantilla||[[Categoría:Estante:{{{nombre}}}| ]]}} <noinclude>{{documentación|Plantilla:+Portada/uso}}</noinclude> fwhks8nojb16a475n5gvr9wn9140hrk 427949 427945 2026-07-16T05:47:16Z Mazbel 57931 Probando 427949 wikitext text/x-wiki __NOTOC__ {| {{#if:{{{ancho|}}}|{{+Tabla|{{{ancho}}}}}|{{+Tabla|80%}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}| {{#if:{{{sección2|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección2}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección6|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección6}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección10|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección10}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección14|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección14}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección18|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección18}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección22|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección22}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección26|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección26}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección30|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección30}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|relleno=10|borde={{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}| {{RGB|oliva9}}}}|fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}0}}| {{RGB|oliva0}}}}|alinear=justify|redondeo={{{redondeo|0}}}|ancho=50%|columnas=2}}|{{+Portada/encabezado |t ={{{título|{{{nombre|{{PAGENAME}}}}}}}} |s ={{{subtítulo|{{Variable|subtítulo}}}}} |at ={{Variable|alineartit}} |info={{{nombre|{{PAGENAME}}}}}/Info |img =auto |i ={{{imagen|{{Variable|imagen}}}}} |ai ={{{alinearimg|{{Variable|alinearimg|center}}}}} |ti ={{{tamañoimagen|{{Variable|tamañoimagen}}}}} }}{{+Botón |fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}5}}|{{RGB|oliva5}}}} |título=[[{{{nombre}}}/Índice|Índice]] • [[{{{nombre}}}/Introducción|Introducción]] • [[{{{nombre}}}/Texto completo|Texto completo]] |redondeo={{{redondeo|0}}} |tamaño=115% |estilo=font-weight:bolder}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}|{{#if:{{{sección1|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección1}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección5|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección5}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección9|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección9}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección13|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección13}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección17|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección17}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección21|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección21}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección25|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección25}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección29|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección29}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} {{+SecciónA |tono={{#if:{{{tonoenlaces|}}}|{{{tonoenlaces}}}|{{#if:{{{tono|}}}|{{{tono}}}|azul}}}} |libro={{{nombre}}} |imagen={{{imagenlink|Nuvola_filesystems_www.png}}} |sección=Enlaces |contenido={{:{{{nombre}}}/Enlaces}} |redondeo={{{redondeo|0}}} |estilo=margin:{{#if:{{{rutacarrusel|}}}{{{sección1|}}}{{{sección5|}}}{{{sección9|}}}{{{sección13|}}}{{{sección17|}}}{{{sección21|}}}{{{sección25|}}}{{{sección29|}}}|10px 0px 0px|0px}};}} {{+SecciónA |tono={{#if:{{{tonoedición|}}}|{{{tonoedición}}}|{{#if:{{{tono|}}}|{{{tono}}}|gris}}}} |libro={{{nombre}}} |imagen={{{imagenedit|Gnome-mime-application-text.svg}}} |sección=Página de edición |contenido={{#if:{{{textoedición|}}}|{{{textoedición}}}|Este libro se encuentra en construcción, para ello dispone de una [[{{{nombre}}}/Página de edición|página de edición]], donde se coordina su construcción.}} |redondeo={{{redondeo|0}}}}} |---- | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección3|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección3}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección7|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección7}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección11|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección11}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección15|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección15}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección19|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección19}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección23|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección23}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección27|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección27}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección4|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección4}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección8|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección8}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección12|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección12}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección16|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección16}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección20|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección20}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección24|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección24}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección28|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección28}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} |} {{#ifeq:{{NAMESPACE}}|Plantilla||[[Categoría:Estante:{{{nombre}}}| ]]}} {{#ifeq:{{NAMESPACE}}|Plantilla||[[Categoría:Libro:{{{nombre}}}| ]]}} <noinclude>{{documentación|Plantilla:+Portada/uso}}</noinclude> 5eg22liyy1iq9fxt64j88zpar5jucv9 427974 427949 2026-07-16T06:16:21Z Mazbel 57931 retoques 427974 wikitext text/x-wiki __NOTOC__ {| {{#if:{{{ancho|}}}|{{+Tabla|{{{ancho}}}}}|{{+Tabla|80%}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}| {{#if:{{{sección2|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección2}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección6|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección6}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección10|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección10}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección14|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección14}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección18|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección18}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección22|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección22}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección26|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección26}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección30|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección30}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|relleno=10|borde={{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}| {{RGB|oliva9}}}}|fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}0}}| {{RGB|oliva0}}}}|alinear=justify|redondeo={{{redondeo|0}}}|ancho=50%|columnas=2}}|{{+Portada/encabezado |t ={{{título|{{{nombre|{{PAGENAME}}}}}}}} |s ={{{subtítulo|{{Variable|subtítulo}}}}} |at ={{Variable|alineartit}} |info={{{nombre|{{PAGENAME}}}}}/Info |img =auto |i ={{{imagen|{{Variable|imagen}}}}} |ai ={{{alinearimg|{{Variable|alinearimg|center}}}}} |ti ={{{tamañoimagen|{{Variable|tamañoimagen}}}}} }}{{+Botón |fondo={{#if:{{{tono|}}}|{{RGB|{{{tono}}}5}}|{{RGB|oliva5}}}} |título=[[{{{nombre}}}/Índice|Índice]] • [[{{{nombre}}}/Introducción|Introducción]] • [[{{{nombre}}}/Texto completo|Texto completo]] |redondeo={{{redondeo|0}}} |tamaño=115% |estilo=font-weight:bolder}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}|filas=2}}|{{#if:{{{sección1|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección1}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección5|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección5}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección9|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección9}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección13|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección13}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección17|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección17}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección21|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección21}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección25|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección25}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección29|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección29}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} {{+SecciónA |tono={{#if:{{{tonoenlaces|}}}|{{{tonoenlaces}}}|{{#if:{{{tono|}}}|{{{tono}}}|azul}}}} |libro={{{nombre}}} |imagen={{{imagenlink|Nuvola_filesystems_www.png}}} |sección=Enlaces |contenido={{:{{{nombre}}}/Enlaces}} |redondeo={{{redondeo|0}}} |estilo=margin:{{#if:{{{rutacarrusel|}}}{{{sección1|}}}{{{sección5|}}}{{{sección9|}}}{{{sección13|}}}{{{sección17|}}}{{{sección21|}}}{{{sección25|}}}{{{sección29|}}}|10px 0px 0px|0px}};}} {{+SecciónA |tono={{#if:{{{tonoedición|}}}|{{{tonoedición}}}|{{#if:{{{tono|}}}|{{{tono}}}|gris}}}} |libro={{{nombre}}} |imagen={{{imagenedit|Gnome-mime-application-text.svg}}} |sección=Página de edición |contenido={{#if:{{{textoedición|}}}|{{{textoedición}}}|Este libro se encuentra en construcción, para ello dispone de una [[{{{nombre}}}/Página de edición|página de edición]], donde se coordina su construcción.}} |redondeo={{{redondeo|0}}}}} |---- | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección3|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección3}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección7|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección7}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección11|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección11}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección15|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección15}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección19|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección19}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección23|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección23}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección27|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección27}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} | {{+Celda|ancho=25%|relleno=10|borde={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}9}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}9}}|{{RGB|kaki9}}}}}}|fondo={{#if:{{{tonosección|}}}|{{RGB|{{{tonosección}}}1}}|{{#if:{{{tono|}}}|{{RGB|{{{tono}}}1}}|{{RGB|kaki1}}}}}} |alinear=justify|redondeo={{{redondeo|0}}}}}|{{#if:{{{sección4|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección4}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección8|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección8}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección12|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección12}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección16|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección16}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección20|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección20}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección24|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección24}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}}{{#if:{{{sección28|}}}|{{+SecciónA|libro={{{nombre}}}|sección={{{sección28}}}|tono={{#if:{{{tonosección|}}}|{{{tonosección}}}|{{#if:{{{tono|}}}|{{{tono}}}|kaki}}}}|redondeo={{{redondeo|0}}}}}}} |} <noinclude>{{documentación|Plantilla:+Portada/uso}}</noinclude> i2zqye7dxnb9zo8qc5ievskwnh6lgj9 Desarrollo de videojuegos para PSP con C++ y SDL/Introducción 0 32496 427865 370234 2026-07-15T18:03:36Z Antimundo 74354 Usar autocategoría 427865 wikitext text/x-wiki Me he dispuesto a escribir este tutorial tras haber estado trabajando en el port a PSP de [http://grannysbloodbath.wordpress.com Granny's Bloodbath] y encontrar algunas dificultades tanto en la instalación del Kit como en la escritura de un proyecto básico que funcione. Por internet circulan algunos tutoriales similares pero todos cuentan con algún otro error y, o yo soy muy torpe, o se hace bastante complicada la instalación. Por otro lado, la mayoría se centraban en sistemas Windows y yo quería hacer la instalación sobre Ubuntu. Espero que esta pequeña guía me sirva a mí como recordatorio para una próxima vez y, si alguien se ve beneficiado pues muchísimo mejor. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Introducción |anterior= |siguiente=Instalación }} {{AutoCategoríaLibro}} 5kjumqv44fyzvgq37k9wgf6vdcdjmcu 427899 427865 2026-07-16T03:53:41Z Mazbel 57931 reorganización 427899 wikitext text/x-wiki Me he dispuesto a escribir este tutorial tras haber estado trabajando en el port a PSP de [http://grannysbloodbath.wordpress.com Granny's Bloodbath] y encontrar algunas dificultades tanto en la instalación del Kit como en la escritura de un proyecto básico que funcione. Por internet circulan algunos tutoriales similares pero todos cuentan con algún otro error y, o yo soy muy torpe, o se hace bastante complicada la instalación. Por otro lado, la mayoría se centraban en sistemas Windows y yo quería hacer la instalación sobre Ubuntu. Espero que esta pequeña guía me sirva a mí como recordatorio para una próxima vez y, si alguien se ve beneficiado pues muchísimo mejor. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Introducción |anterior= |siguiente=Instalación }} {{AutoCat}} kk5iqd0xisv4ppbmkch6rv1cjn3lrz4 Desarrollo de videojuegos para PSP con C++ y SDL/Instalación 0 32497 427866 410956 2026-07-15T18:04:00Z Antimundo 74354 Usar autocategoría 427866 wikitext text/x-wiki __TOC__ ==Dependencias== Lo primero que debemos hacer es instalar las dependencias del kit de desarrollo de PSP. Para ello abriremos una terminal e introduciremos el siguiente comando: <syntaxhighlight lang="bash"> sudo apt-get install build-essential autoconf automake bison flex \ libncurses5-dev libreadline-dev libusb-dev texinfo libmpfr-dev \ libgmp3-dev libtool </syntaxhighlight> ==Variables de entorno== Ahora debemos establecer algunas variables de entorno para que el sistema sepa dónde encontrar las nuevas librerías de PSP a la hora de compilar. Editamos el fichero ''~/.bashrc'' y añadimos al final las siguientes líneas: <syntaxhighlight lang="bash"> export PSPDEV="/usr/local/pspdev" export PSPSDK="$PSPDEV/psp/sdk" export PATH="$PATH:$PSPDEV/bin:$PSPSDK/bin" </syntaxhighlight> Cuando reiniciemos el equipo ''~/.bashrc'' volverá a cargarse pero no es necesario hacerlo, podemos ejecutar la siguiente orden: <syntaxhighlight lang="bash"> syntaxhighlight ~/.bashrc </syntaxhighlight> ==Instalación del SDK de PSP== El siguiente paso es descargarnos una copia del directorio ''trunk'' del repositorio de [http://ps2dev.org ps2dev], el cual contiene todo lo que necesitamos (y más). El repositorio tiene un tamaño considerable y, dependiendo de cómo ande el servidor, puede tardar bastante. <syntaxhighlight lang="bash"> svn co svn://svn.ps2dev.org/psp/trunk/ pspsdk </syntaxhighlight> Bueno, si habéis tenido la paciencia suficiente de llegar hasta aquí vamos por buen camino. Ahora toca instalar el ''toolchain'', el kit básico: <syntaxhighlight lang="bash"> cd pspsdk cd toolchain sudo ./toolchain-sudo.sh </syntaxhighlight> Existe un pack de bibliotecas adicionales entre las que se encuentran las SDL llamado ''psplibraries''. Este pack contiene: bzip2, freetype, jpeg, libbulletml, libmad, libmikmod, libogg, libpng, libpspvram, libTremor, libvorbis, lua, pspgl, pspirkeyb, SDL, SDL_gfx, SDL_image, SDL_mixer, SDL_ttf, smpeg-psp, sqlite, zlib y zziplib. Muchas son dependencias de las SDL pero algunas como sqlite (bases de datos), lua (lenguaje de scripting) o pspgl (versión de Open GL para PSP) no tienen nada que ver aunque son muy interesantes también. Lo instalamos de la siguiente manera: <syntaxhighlight lang="bash"> cd .. cd psplibraries sudo ./libraries-sudo.sh </syntaxhighlight> En teoría ya deberíamos estar listos para crear nuestros proyectos en C++ que usen las SDL para PSP, ¡pero no es así! Debe haber algún error en el script anterior porque SDL_mixer no se instala como debería. Hemos de compilar e instalar sus dependencias manualmente. Comenzamos cambiando el propietario de la carpeta donde se instala el kit de desarrollo, sino las bibliotecas no pueden instalarse (al menos yo no he conseguido hacerlo): <syntaxhighlight lang="bash"> sudo chown -R username:group /usr/local/pspdev sudo chown username:group /usr/local/pspdev/* </syntaxhighlight> Donde ''group'' y ''username'' son los nombres de nuestro grupo y usuario en el sistema. Nos dirigimos a instalar libTremor manualmente, dependencia de SDL_mixer: <syntaxhighlight lang="bash"> cd .. cd libTremor LDFLAGS="-L$(psp-config --pspsdk-path)/lib" LIBS="-lc -lpspuser" ./autogen.sh \ --host psp --prefix=$(psp-config --psp-prefix) make clean make make install </syntaxhighlight> Finalmente le toca el turno a SDL_mixer y toca seguir el siguiente proceso: <syntaxhighlight lang="bash"> cd .. cd SDL_mixer ./autogen.sh LDFLAGS="-L$(psp-config --pspsdk-path)/lib" LIBS="-lc -lpspuser" \ ./configure --host psp --with-sdl-prefix=$(psp-config --psp-prefix) \ --disable-music-mp3 --prefix=$(psp-config --psp-prefix) \ --disable-music-libmikmod --enable-music-mod make clean make make install </syntaxhighlight> ==Finalizamos== Con eso debería bastar, siento el rodeo, si alguien encuentra una manera mejor de instalar el kit de desarrollo para PSP con SDL en GNU/Linux, por favor, que me lo comunique. Entre todos podemos hacer una gran guía. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Instalación |anterior=Introducción |siguiente=El makefile }} {{AutoCategoríaLibro}} oyq4gm77bntd9y35pdt0ug8varpcthz 427900 427866 2026-07-16T03:53:54Z Mazbel 57931 actualización 427900 wikitext text/x-wiki __TOC__ ==Dependencias== Lo primero que debemos hacer es instalar las dependencias del kit de desarrollo de PSP. Para ello abriremos una terminal e introduciremos el siguiente comando: <syntaxhighlight lang="bash"> sudo apt-get install build-essential autoconf automake bison flex \ libncurses5-dev libreadline-dev libusb-dev texinfo libmpfr-dev \ libgmp3-dev libtool </syntaxhighlight> ==Variables de entorno== Ahora debemos establecer algunas variables de entorno para que el sistema sepa dónde encontrar las nuevas librerías de PSP a la hora de compilar. Editamos el fichero ''~/.bashrc'' y añadimos al final las siguientes líneas: <syntaxhighlight lang="bash"> export PSPDEV="/usr/local/pspdev" export PSPSDK="$PSPDEV/psp/sdk" export PATH="$PATH:$PSPDEV/bin:$PSPSDK/bin" </syntaxhighlight> Cuando reiniciemos el equipo ''~/.bashrc'' volverá a cargarse pero no es necesario hacerlo, podemos ejecutar la siguiente orden: <syntaxhighlight lang="bash"> syntaxhighlight ~/.bashrc </syntaxhighlight> ==Instalación del SDK de PSP== El siguiente paso es descargarnos una copia del directorio ''trunk'' del repositorio de [http://ps2dev.org ps2dev], el cual contiene todo lo que necesitamos (y más). El repositorio tiene un tamaño considerable y, dependiendo de cómo ande el servidor, puede tardar bastante. <syntaxhighlight lang="bash"> svn co svn://svn.ps2dev.org/psp/trunk/ pspsdk </syntaxhighlight> Bueno, si habéis tenido la paciencia suficiente de llegar hasta aquí vamos por buen camino. Ahora toca instalar el ''toolchain'', el kit básico: <syntaxhighlight lang="bash"> cd pspsdk cd toolchain sudo ./toolchain-sudo.sh </syntaxhighlight> Existe un pack de bibliotecas adicionales entre las que se encuentran las SDL llamado ''psplibraries''. Este pack contiene: bzip2, freetype, jpeg, libbulletml, libmad, libmikmod, libogg, libpng, libpspvram, libTremor, libvorbis, lua, pspgl, pspirkeyb, SDL, SDL_gfx, SDL_image, SDL_mixer, SDL_ttf, smpeg-psp, sqlite, zlib y zziplib. Muchas son dependencias de las SDL pero algunas como sqlite (bases de datos), lua (lenguaje de scripting) o pspgl (versión de Open GL para PSP) no tienen nada que ver aunque son muy interesantes también. Lo instalamos de la siguiente manera: <syntaxhighlight lang="bash"> cd .. cd psplibraries sudo ./libraries-sudo.sh </syntaxhighlight> En teoría ya deberíamos estar listos para crear nuestros proyectos en C++ que usen las SDL para PSP, ¡pero no es así! Debe haber algún error en el script anterior porque SDL_mixer no se instala como debería. Hemos de compilar e instalar sus dependencias manualmente. Comenzamos cambiando el propietario de la carpeta donde se instala el kit de desarrollo, sino las bibliotecas no pueden instalarse (al menos yo no he conseguido hacerlo): <syntaxhighlight lang="bash"> sudo chown -R username:group /usr/local/pspdev sudo chown username:group /usr/local/pspdev/* </syntaxhighlight> Donde ''group'' y ''username'' son los nombres de nuestro grupo y usuario en el sistema. Nos dirigimos a instalar libTremor manualmente, dependencia de SDL_mixer: <syntaxhighlight lang="bash"> cd .. cd libTremor LDFLAGS="-L$(psp-config --pspsdk-path)/lib" LIBS="-lc -lpspuser" ./autogen.sh \ --host psp --prefix=$(psp-config --psp-prefix) make clean make make install </syntaxhighlight> Finalmente le toca el turno a SDL_mixer y toca seguir el siguiente proceso: <syntaxhighlight lang="bash"> cd .. cd SDL_mixer ./autogen.sh LDFLAGS="-L$(psp-config --pspsdk-path)/lib" LIBS="-lc -lpspuser" \ ./configure --host psp --with-sdl-prefix=$(psp-config --psp-prefix) \ --disable-music-mp3 --prefix=$(psp-config --psp-prefix) \ --disable-music-libmikmod --enable-music-mod make clean make make install </syntaxhighlight> ==Finalizamos== Con eso debería bastar, siento el rodeo, si alguien encuentra una manera mejor de instalar el kit de desarrollo para PSP con SDL en GNU/Linux, por favor, que me lo comunique. Entre todos podemos hacer una gran guía. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Instalación |anterior=Introducción |siguiente=El makefile }} {{AutoCat}} 3u3pfsp7x6zqb2nxkp5ho12kmlxqpjh Desarrollo de videojuegos para PSP con C++ y SDL/El makefile 0 32498 427867 385142 2026-07-15T18:04:11Z Antimundo 74354 Usar autocategoría 427867 wikitext text/x-wiki El makefile para compilar proyectos para PSP tiene ciertas particularidades dignas de mención en esta humilde guía. __TOC__ ==Jerarquía de directorios== Vamos a suponer que tenemos la siguiente jerarquía de directorios: * Proyecto ** makefile ** main.cpp ** engine *** ficheros.cpp *** ficheros.h ==El makefile== Nuestro makefile sería algo similar a lo siguiente: <syntaxhighlight lang="make"> #Proyecto TARGET = Nombre del proyecto SDL_CONFIG = $(PSPBIN)/sdl-config # Rutas MOTOR_DIR := engine # Ficheros fuente del juego SRC := main.cpp # Ficheros fuente del motor. SRC_MOTOR := ficheros.o del motor # motor_dir + fuentes SRC_DIR_MOTOR := $(foreach src, $(SRC_MOTOR),$(MOTOR_DIR)/$(src) ) # Objetos OBJS := $(SRC:%.cpp=%.o) $(SRC_DIR_MOTOR:%.cpp=%.o) INCDIR = CFLAGS = $(shell $(SDL_CONFIG) --cflags) -G0 -Wall -O2 -DPSP CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -D"TIXML_USE_STL" ASFLAGS = $(CFLAGS) LIBDIR = LDFLAGS = LIBS = -lstdc++ -lsupc++ -lSDL_gfx -lSDL_image -lSDL_mixer -lSDL_ttf -lfreetype \ -lpng -ljpeg -lvorbisidec -lz -lm $(shell $(SDL_CONFIG) --libs) EXTRA_TARGETS = EBOOT.PBP PSP_EBOOT_TITLE = Nombre del proyecto PSP_EBOOT_ICON= "icono.png" PSP_EBOOT_PIC1= "fondo.png" PSP_EBOOT_SND0= "sonido.at3" PSPSDK = $(shell psp-config --pspsdk-path) PSPBIN = $(shell psp-config --psp-prefix)/bin USE_PSPSDK_LIBC=1 include $(PSPSDK)/lib/build.mak </syntaxhighlight> ==Personalización== Podemos personalizar la apariencia de nuestro ''homebrew'' en el menú de PSP mediante las siguientes variables: * '''PSP_EBOOT_ICON:''' icono de 144x80 que identificara al juego en la sección $Juegos$ del menú. * '''PSP_EBOOT_PIC1:''' fondo que aparecerá en la consola cuando el juego esté seleccionado, debe tener 480x272. * '''PSP_EBOOT_SND0:''' fichero de sonido en formato at3 que se escuchará cuando nuestro juego esté seleccionado en el menú. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=El makefile |anterior=Instalación |siguiente=La pantalla }} {{AutoCategoríaLibro}} 5vakne3ee7h8e3v2e7tvropbr9ef7te 427901 427867 2026-07-16T03:54:10Z Mazbel 57931 actualización 427901 wikitext text/x-wiki El makefile para compilar proyectos para PSP tiene ciertas particularidades dignas de mención en esta humilde guía. __TOC__ ==Jerarquía de directorios== Vamos a suponer que tenemos la siguiente jerarquía de directorios: * Proyecto ** makefile ** main.cpp ** engine *** ficheros.cpp *** ficheros.h ==El makefile== Nuestro makefile sería algo similar a lo siguiente: <syntaxhighlight lang="make"> #Proyecto TARGET = Nombre del proyecto SDL_CONFIG = $(PSPBIN)/sdl-config # Rutas MOTOR_DIR := engine # Ficheros fuente del juego SRC := main.cpp # Ficheros fuente del motor. SRC_MOTOR := ficheros.o del motor # motor_dir + fuentes SRC_DIR_MOTOR := $(foreach src, $(SRC_MOTOR),$(MOTOR_DIR)/$(src) ) # Objetos OBJS := $(SRC:%.cpp=%.o) $(SRC_DIR_MOTOR:%.cpp=%.o) INCDIR = CFLAGS = $(shell $(SDL_CONFIG) --cflags) -G0 -Wall -O2 -DPSP CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -D"TIXML_USE_STL" ASFLAGS = $(CFLAGS) LIBDIR = LDFLAGS = LIBS = -lstdc++ -lsupc++ -lSDL_gfx -lSDL_image -lSDL_mixer -lSDL_ttf -lfreetype \ -lpng -ljpeg -lvorbisidec -lz -lm $(shell $(SDL_CONFIG) --libs) EXTRA_TARGETS = EBOOT.PBP PSP_EBOOT_TITLE = Nombre del proyecto PSP_EBOOT_ICON= "icono.png" PSP_EBOOT_PIC1= "fondo.png" PSP_EBOOT_SND0= "sonido.at3" PSPSDK = $(shell psp-config --pspsdk-path) PSPBIN = $(shell psp-config --psp-prefix)/bin USE_PSPSDK_LIBC=1 include $(PSPSDK)/lib/build.mak </syntaxhighlight> ==Personalización== Podemos personalizar la apariencia de nuestro ''homebrew'' en el menú de PSP mediante las siguientes variables: * '''PSP_EBOOT_ICON:''' icono de 144x80 que identificara al juego en la sección $Juegos$ del menú. * '''PSP_EBOOT_PIC1:''' fondo que aparecerá en la consola cuando el juego esté seleccionado, debe tener 480x272. * '''PSP_EBOOT_SND0:''' fichero de sonido en formato at3 que se escuchará cuando nuestro juego esté seleccionado en el menú. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=El makefile |anterior=Instalación |siguiente=La pantalla }} {{AutoCat}} j3fkxnib27wgmphjqi2z1ewp9xbu1pt Desarrollo de videojuegos para PSP con C++ y SDL/Callbacks de salida al SO 0 32499 427868 385164 2026-07-15T18:04:34Z Antimundo 74354 Usar autocategoría 427868 wikitext text/x-wiki Seguramente sabréis de qué hablo pero es probable que no os hayáis dado cuenta de que debe ser algo a controlar a la hora de portar la aplicación a PSP. Me refiero a la pausa del juego y a la vuelta al sistema operativo de la consola. En cualquier momento podemos pulsar el botón ''HOME'', seleccionar "salir del juego" y volver al menú principal. Si no tenemos cuidado provocaremos un cuelgue en la consola cada vez que queramos salir. Tendremos que definir ciertas funciones que actúen como ''callbacks''. Un fichero ''main.cpp'' de un port génerico podría ser el siguiente: <syntaxhighlight lang="cpp"> #include <pspkernel.h> #include "engine/application.h" #include "engine/keyboard.h" int exit_callback(int arg1, int arg2, void *common) { /* Codigo para cerrar correctamente nuestro sistema */ keyboard->set_quit(); return 0; } int CallbackThread(SceSize args, void *argp) { int cbid; cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); sceKernelRegisterExitCallback(cbid); sceKernelSleepThreadCB(); return 0; } int SetupCallbacks(void) { int thid = 0; thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); if(thid >= 0) { sceKernelStartThread(thid, 0, 0); } return thid; } /* Necesario para no tener problemas con C++ */ extern "C" int SDL_main (int argc, char* args[]); int main(int argc, char *argv[]) { /* Preparamos los callbacks */ SetupCallbacks(); /* Lanzamos nuestro sistema */ Application app("XML/configuration.xml"); app.run(); /* Volvemos al sistema operativo */ sceKernelExitGame(); return 0; } </syntaxhighlight> Es importante comprender que cuando el usuario decide salir del juego (esperemos que no sea demasiado a menudo) se llama a la función ''exit_callback'' por lo que debe ser ella la que se encargue de hacer los cambios pertinentes para romper el game-loop. En mi caso una forma podía ser llamar a la al método ''set_quit()'' de mi clase ''keyboard'' pero en el vuestro puede ser cualquier otro. {{AutoCategoríaLibro}} s54prkph8baxjq5lxfxn7shm6rjiz45 427902 427868 2026-07-16T03:54:22Z Mazbel 57931 actualización 427902 wikitext text/x-wiki Seguramente sabréis de qué hablo pero es probable que no os hayáis dado cuenta de que debe ser algo a controlar a la hora de portar la aplicación a PSP. Me refiero a la pausa del juego y a la vuelta al sistema operativo de la consola. En cualquier momento podemos pulsar el botón ''HOME'', seleccionar "salir del juego" y volver al menú principal. Si no tenemos cuidado provocaremos un cuelgue en la consola cada vez que queramos salir. Tendremos que definir ciertas funciones que actúen como ''callbacks''. Un fichero ''main.cpp'' de un port génerico podría ser el siguiente: <syntaxhighlight lang="cpp"> #include <pspkernel.h> #include "engine/application.h" #include "engine/keyboard.h" int exit_callback(int arg1, int arg2, void *common) { /* Codigo para cerrar correctamente nuestro sistema */ keyboard->set_quit(); return 0; } int CallbackThread(SceSize args, void *argp) { int cbid; cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); sceKernelRegisterExitCallback(cbid); sceKernelSleepThreadCB(); return 0; } int SetupCallbacks(void) { int thid = 0; thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); if(thid >= 0) { sceKernelStartThread(thid, 0, 0); } return thid; } /* Necesario para no tener problemas con C++ */ extern "C" int SDL_main (int argc, char* args[]); int main(int argc, char *argv[]) { /* Preparamos los callbacks */ SetupCallbacks(); /* Lanzamos nuestro sistema */ Application app("XML/configuration.xml"); app.run(); /* Volvemos al sistema operativo */ sceKernelExitGame(); return 0; } </syntaxhighlight> Es importante comprender que cuando el usuario decide salir del juego (esperemos que no sea demasiado a menudo) se llama a la función ''exit_callback'' por lo que debe ser ella la que se encargue de hacer los cambios pertinentes para romper el game-loop. En mi caso una forma podía ser llamar a la al método ''set_quit()'' de mi clase ''keyboard'' pero en el vuestro puede ser cualquier otro. {{AutoCat}} kiocik7prs5ef2deprffqynv4bhk8nd Desarrollo de videojuegos para PSP con C++ y SDL/La pantalla 0 32500 427869 385162 2026-07-15T18:04:46Z Antimundo 74354 Usar autocategoría 427869 wikitext text/x-wiki Las dimensiones de la pantalla de la PSP son de 480x272 píxeles por lo que la superficie principal de SDL a crear debe ser exactamente de dichas dimensiones. Por otro lado está la profundidad de color, inicialmente pensé que sería más eficiente bajar dichos niveles de 32bpp a 16bpp o incluso 8bpp si fuera necesario por cuestiones de rendimiento. No obstante, el port de SDL para PSP parece no funcionar correctamente en los dos últimos modos. Finalmente acabé usando 32bpp aunque el rendimiento final es bastante bueno. La llamada para inicializar SDL en PSP puede ser algo similar a esto: <syntaxhighlight lang="cpp"> SDL_Surface *screen = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); </syntaxhighlight> Con las correspondientes comprobaciones posteriores. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=La pantalla |anterior=El makefile |siguiente=Leyendo la entrada de PSP }} {{AutoCategoríaLibro}} ldnrdy28x71i176eboqq1p9lfjp3z9l 427903 427869 2026-07-16T03:54:32Z Mazbel 57931 actualización 427903 wikitext text/x-wiki Las dimensiones de la pantalla de la PSP son de 480x272 píxeles por lo que la superficie principal de SDL a crear debe ser exactamente de dichas dimensiones. Por otro lado está la profundidad de color, inicialmente pensé que sería más eficiente bajar dichos niveles de 32bpp a 16bpp o incluso 8bpp si fuera necesario por cuestiones de rendimiento. No obstante, el port de SDL para PSP parece no funcionar correctamente en los dos últimos modos. Finalmente acabé usando 32bpp aunque el rendimiento final es bastante bueno. La llamada para inicializar SDL en PSP puede ser algo similar a esto: <syntaxhighlight lang="cpp"> SDL_Surface *screen = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); </syntaxhighlight> Con las correspondientes comprobaciones posteriores. {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=La pantalla |anterior=El makefile |siguiente=Leyendo la entrada de PSP }} {{AutoCat}} smds47nxjqzq5v698e76lgcxgxmak4z Desarrollo de videojuegos para PSP con C++ y SDL/Leyendo la entrada de PSP 0 32501 427870 403999 2026-07-15T18:05:04Z Antimundo 74354 Usar autocategoría 427870 wikitext text/x-wiki __TOC__ ==El problema de SDL_Joystick== Teóricamente, como la mayoría de tutoriales apuntan, podemos usar ''SDL_Joystick'' para manejar la entrada del jugador. Se nos presenta una equivalencia entre botones de joystick y de PSP para que podamos manejarla pero lo cierto es que, o soy tremendamente torpe, o este sistema no funciona del todo bien. ==Alternativa== Finalmente, para $Granny's bloodbath$ decidí cambiar la implementación de la clase que manejaba la entrada del jugador (utilizando la API de las librerías de PSP) sin cambiar su interfaz, de ese modo me adaptaba a las circunstancias de PSP sin afectar al resto del sistema. Las clases que utilicé son las siguientes y funcionan bastante bien: '''keyboard.h''': <syntaxhighlight lang="cpp"> /* This file is part of Granny's Bloodbath. Granny's Bloodbath is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Granny's Bloodbath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Granny's Bloodbath. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _KEYBOARD_ #define _KEYBOARD_ #include <pspkernel.h> #include <pspctrl.h> #include <valarray> #include <map> //! Gestiona el teclado, consultamos teclas pulsadas /** @author David Saltares Marquez @version 1.0 Clase que sigue el patron de diseno Singleton (una sola instancia accesible desde todo el sistema). Lleva el control de que teclas estan pulsadas en un momento determinado, cuales se sueltan y cuales se vuelven a presionar. Ejemplo de uso \code // Game loop while(!quit){ keyboard->update() // Equivalente a Keyboard::get_instance()->update(); if(keyboard->pressed(Keyboard::KEY_UP)) // Si pulsamos arriba ... if(keyboard->released(Keyboard::KEY_HIT)) // Si dejamos de pulsar golpear ... if(keyboard->newpressed(Keyboard:KEY_SHOOT)) // Si antes soltamos y // ahora pulsamos disparar } \endcode */ class Keyboard{ public: /** Controles del teclado utilizados en el juego */ enum keys{ KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT, KEY_SHOOT, KEY_HIT, KEY_KNEEL, KEY_EXIT, KEY_ENTER }; /** @return Si es la primera vez que se usa Keyboard crea su instancia y la devuelve. Sino simplemente la devuelve. */ static Keyboard* get_instance(){ /* Si es la primera vez que necesitamos Keyboard, lo creamos */ if(_instance == 0) _instance = new Keyboard; return _instance; } /** Actualiza el estado del teclado. Debe llamarse una vez al comienzo del game loop. */ void update(); /** @param key Tecla a consultar @return true si la tecla esta pulsada, false en caso contrario. */ bool pressed(keys key); /** @param key Tecla a consultar @return true si la tecla estaba antes pulsada en la ultima actualizacion y ahora no lo esta, false en caso contrario. */ bool released(keys key); /** @param key Tecla a consultar @return true si la tecla no estaba pulsada en la ultima actualizacion y ahora lo esta, false en caso contrario. */ bool newpressed(keys key); /** @return true si se ha producido algun evento de salida, false en caso contrario */ bool quit(); void set_quit() {_quit = true;} protected: Keyboard(); ~Keyboard(); Keyboard(const Keyboard& k); Keyboard& operator = (const Keyboard& k); private: static Keyboard* _instance; std::weeee<bool> actual_keyboard; std::valarray<bool> old_keyboard; bool _quit; std::map<keys, PspCtrlButtons> configured_keys; SceCtrlData buttonInput; int n_keys; }; #define keyboard Keyboard::get_instance() #endif </syntaxhighlight> '''keyboard.cpp''': <syntaxhighlight lang="cpp"> #include <iostream> #include <algorithm> #include "keyboard.h" using namespace std; Keyboard* Keyboard::_instance = 0; Keyboard::Keyboard() { /* Configuracion predeterminada */ configured_keys[KEY_UP] = PSP_CTRL_UP; configured_keys[KEY_DOWN] = PSP_CTRL_DOWN; configured_keys[KEY_LEFT] = PSP_CTRL_LEFT; configured_keys[KEY_RIGHT] = PSP_CTRL_RIGHT; configured_keys[KEY_HIT] = PSP_CTRL_CROSS; configured_keys[KEY_SHOOT] = PSP_CTRL_CIRCLE; configured_keys[KEY_EXIT] = PSP_CTRL_SELECT; configured_keys[KEY_ENTER] = PSP_CTRL_START; /* Inicializamos el estado del teclado */ n_keys = configured_keys.size(); actual_keyboard.resize(n_keys); old_keyboard.resize(n_keys); for(int i = 0; i < n_keys; ++i){ actual_keyboard[false]; old_keyboard[false]; } _quit = false; sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); } Keyboard::~Keyboard() { } void Keyboard::update() { /* Ahora el teclado nuevo es el viejo */ old_keyboard = actual_keyboard; /* Actualizamos el estado de la entrada PSP */ sceCtrlPeekBufferPositive(&buttonInput, 1); /* Actualizamos el estado del teclado */ for(map<keys, PspCtrlButtons>::iterator i = configured_keys.begin(); i != configured_keys.end(); ++i) actual_keyboard[i->first] = (buttonInput.Buttons & i->second)? actual_keyboard[i->first] = true : actual_keyboard[i->first] = false; } bool Keyboard::pressed(keys key) { /* Devolvemos si la tecla indicada esta pulsada */ return actual_keyboard[key]; } bool Keyboard::released(keys key) { /* Comprobamos si la tecla indicada no esta pulsada y antes si */ return (!actual_keyboard[key] && old_keyboard[key]); } bool Keyboard::newpressed(keys key) { /* Comprobamos si la tecla indicada esta pulsada y antes no */ return (actual_keyboard[key] && !old_keyboard[key]); } bool Keyboard::quit() { return _quit; } </syntaxhighlight> {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Leyendo la entrada de PSP |anterior=La pantalla |siguiente=Conclusiones }} {{AutoCategoríaLibro}} gejkqjwrzbjjes5i6fm5qagkutk55xz 427904 427870 2026-07-16T03:54:46Z Mazbel 57931 actualización 427904 wikitext text/x-wiki __TOC__ ==El problema de SDL_Joystick== Teóricamente, como la mayoría de tutoriales apuntan, podemos usar ''SDL_Joystick'' para manejar la entrada del jugador. Se nos presenta una equivalencia entre botones de joystick y de PSP para que podamos manejarla pero lo cierto es que, o soy tremendamente torpe, o este sistema no funciona del todo bien. ==Alternativa== Finalmente, para $Granny's bloodbath$ decidí cambiar la implementación de la clase que manejaba la entrada del jugador (utilizando la API de las librerías de PSP) sin cambiar su interfaz, de ese modo me adaptaba a las circunstancias de PSP sin afectar al resto del sistema. Las clases que utilicé son las siguientes y funcionan bastante bien: '''keyboard.h''': <syntaxhighlight lang="cpp"> /* This file is part of Granny's Bloodbath. Granny's Bloodbath is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Granny's Bloodbath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Granny's Bloodbath. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _KEYBOARD_ #define _KEYBOARD_ #include <pspkernel.h> #include <pspctrl.h> #include <valarray> #include <map> //! Gestiona el teclado, consultamos teclas pulsadas /** @author David Saltares Marquez @version 1.0 Clase que sigue el patron de diseno Singleton (una sola instancia accesible desde todo el sistema). Lleva el control de que teclas estan pulsadas en un momento determinado, cuales se sueltan y cuales se vuelven a presionar. Ejemplo de uso \code // Game loop while(!quit){ keyboard->update() // Equivalente a Keyboard::get_instance()->update(); if(keyboard->pressed(Keyboard::KEY_UP)) // Si pulsamos arriba ... if(keyboard->released(Keyboard::KEY_HIT)) // Si dejamos de pulsar golpear ... if(keyboard->newpressed(Keyboard:KEY_SHOOT)) // Si antes soltamos y // ahora pulsamos disparar } \endcode */ class Keyboard{ public: /** Controles del teclado utilizados en el juego */ enum keys{ KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT, KEY_SHOOT, KEY_HIT, KEY_KNEEL, KEY_EXIT, KEY_ENTER }; /** @return Si es la primera vez que se usa Keyboard crea su instancia y la devuelve. Sino simplemente la devuelve. */ static Keyboard* get_instance(){ /* Si es la primera vez que necesitamos Keyboard, lo creamos */ if(_instance == 0) _instance = new Keyboard; return _instance; } /** Actualiza el estado del teclado. Debe llamarse una vez al comienzo del game loop. */ void update(); /** @param key Tecla a consultar @return true si la tecla esta pulsada, false en caso contrario. */ bool pressed(keys key); /** @param key Tecla a consultar @return true si la tecla estaba antes pulsada en la ultima actualizacion y ahora no lo esta, false en caso contrario. */ bool released(keys key); /** @param key Tecla a consultar @return true si la tecla no estaba pulsada en la ultima actualizacion y ahora lo esta, false en caso contrario. */ bool newpressed(keys key); /** @return true si se ha producido algun evento de salida, false en caso contrario */ bool quit(); void set_quit() {_quit = true;} protected: Keyboard(); ~Keyboard(); Keyboard(const Keyboard& k); Keyboard& operator = (const Keyboard& k); private: static Keyboard* _instance; std::weeee<bool> actual_keyboard; std::valarray<bool> old_keyboard; bool _quit; std::map<keys, PspCtrlButtons> configured_keys; SceCtrlData buttonInput; int n_keys; }; #define keyboard Keyboard::get_instance() #endif </syntaxhighlight> '''keyboard.cpp''': <syntaxhighlight lang="cpp"> #include <iostream> #include <algorithm> #include "keyboard.h" using namespace std; Keyboard* Keyboard::_instance = 0; Keyboard::Keyboard() { /* Configuracion predeterminada */ configured_keys[KEY_UP] = PSP_CTRL_UP; configured_keys[KEY_DOWN] = PSP_CTRL_DOWN; configured_keys[KEY_LEFT] = PSP_CTRL_LEFT; configured_keys[KEY_RIGHT] = PSP_CTRL_RIGHT; configured_keys[KEY_HIT] = PSP_CTRL_CROSS; configured_keys[KEY_SHOOT] = PSP_CTRL_CIRCLE; configured_keys[KEY_EXIT] = PSP_CTRL_SELECT; configured_keys[KEY_ENTER] = PSP_CTRL_START; /* Inicializamos el estado del teclado */ n_keys = configured_keys.size(); actual_keyboard.resize(n_keys); old_keyboard.resize(n_keys); for(int i = 0; i < n_keys; ++i){ actual_keyboard[false]; old_keyboard[false]; } _quit = false; sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); } Keyboard::~Keyboard() { } void Keyboard::update() { /* Ahora el teclado nuevo es el viejo */ old_keyboard = actual_keyboard; /* Actualizamos el estado de la entrada PSP */ sceCtrlPeekBufferPositive(&buttonInput, 1); /* Actualizamos el estado del teclado */ for(map<keys, PspCtrlButtons>::iterator i = configured_keys.begin(); i != configured_keys.end(); ++i) actual_keyboard[i->first] = (buttonInput.Buttons & i->second)? actual_keyboard[i->first] = true : actual_keyboard[i->first] = false; } bool Keyboard::pressed(keys key) { /* Devolvemos si la tecla indicada esta pulsada */ return actual_keyboard[key]; } bool Keyboard::released(keys key) { /* Comprobamos si la tecla indicada no esta pulsada y antes si */ return (!actual_keyboard[key] && old_keyboard[key]); } bool Keyboard::newpressed(keys key) { /* Comprobamos si la tecla indicada esta pulsada y antes no */ return (actual_keyboard[key] && !old_keyboard[key]); } bool Keyboard::quit() { return _quit; } </syntaxhighlight> {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Leyendo la entrada de PSP |anterior=La pantalla |siguiente=Conclusiones }} {{AutoCat}} ivuq820zjswqb4gsna4nu5witqsx7z2 Desarrollo de videojuegos para PSP con C++ y SDL/Conclusiones 0 32502 427871 247373 2026-07-15T18:05:14Z Antimundo 74354 Usar autocategoría 427871 wikitext text/x-wiki Con todos los detalles anteriormente mencionados creo que es suficiente para poder comenzar a portar los juegos que se creen en PC a PSP (siempre que la potencia, control y detalles similares lo permitan). {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Conclusiones |anterior=Leyendo la entrada de PSP |siguiente= }} {{AutoCategoríaLibro}} 7678dbm9rmw1blflseitoal8tysjvbn 427905 427871 2026-07-16T03:55:00Z Mazbel 57931 actualización 427905 wikitext text/x-wiki Con todos los detalles anteriormente mencionados creo que es suficiente para poder comenzar a portar los juegos que se creen en PC a PSP (siempre que la potencia, control y detalles similares lo permitan). {{navegar |libro=Desarrollo de videojuegos para PSP con C++ y SDL |reducido=Cualquier valor |actual=Conclusiones |anterior=Leyendo la entrada de PSP |siguiente= }} {{AutoCat}} 8o9ko2c6oseroe0m4gmzdujsdb7n6c5 Desarrollo de videojuegos para PSP con C++ y SDL 0 32504 427863 427801 2026-07-15T18:02:29Z Antimundo 74354 Categorizar 427863 wikitext text/x-wiki ==Contenido== * [[Desarrollo de videojuegos para PSP con C++ y SDL/Introducción|Introducción]] * [[Desarrollo de videojuegos para PSP con C++ y SDL/Instalación|Instalación]] * [[Desarrollo de videojuegos para PSP con C++ y SDL/El makefile|El makefile]] * [[Desarrollo de videojuegos para PSP con C++ y SDL/Callbacks de salida al SO|Callbacks de salida al SO]] * [[Desarrollo de videojuegos para PSP con C++ y SDL/La pantalla|La pantalla]] * [[Desarrollo de videojuegos para PSP con C++ y SDL/Leyendo la entrada de PSP|Leyendo la entrada de PSP]] * [[Desarrollo de videojuegos para PSP con C++ y SDL/Conclusiones|Conclusiones]] ---- * [[Desarrollo de videojuegos para PSP con C++ y SDL/Texto completo|'''Texto completo del libro''']] <noinclude> {{Estantes|Desarrollo de videojuegos}} [[Categoría:Libros|Desarrollo de videojuegos para PSP con C++ y SDL]] [[Categoría:Creación de videojuegos]] [[Categoría:Programación en C++]] [[Categoría:Programación con SDL]] [[Categoría:Programación para PSP]] </noinclude> cvkugtlzk245enw3tjl1ylzid6r4j8h Categoría:Categorías 14 36584 427879 244683 2026-07-15T18:49:29Z Antimundo 74354 Retirar plantilla heredada de enWikibooks que solo consiste en enlaces rotos 427879 wikitext text/x-wiki {{shortcut|CAT:CATS}} Esta es la '''categoría raíz''' de nuestro sistemas de categorías. Para una explicación del sistema de categorías de Wikibooks, véase {{en}}: * [[:en:Wikibooks:CCO Resources|Wikibooks:CCO Resources]] * [[:en:Wikibooks:Categories|Wikibooks:Categories]] * [[:en:Help:Category|Help:Category]] oum80yuydvb30qokqjxlkkr73h05olb 427882 427879 2026-07-15T21:12:24Z Antimundo 74354 Mejorar explicación 427882 wikitext text/x-wiki {{shortcut|CAT:CATS}} [[Archivo:Gnome-colors-applications-office.svg|derecha|sinmarco|100x100px]] Esta es la '''categoría raíz''' del sistemas de categorías de Wikilibros en español. Para una explicación del sistema de categorías de Wikibooks en inglés, véase {{en}}: * [[:en:Wikibooks:CCO Resources|Wikibooks:CCO Resources]] * [[:en:Wikibooks:Categories|Wikibooks:Categories]] * [[:en:Help:Category|Help:Category]] 1ne5e5wessmssdiufxau64my8izlbn1 Plantilla:AutoCat 10 38116 427894 304829 2026-07-16T03:40:17Z Mazbel 57931 actualización 427894 wikitext text/x-wiki <includeonly>{{#switch:{{NAMESPACE}} |{{TALKSPACE}}= |Template={{#ifeq:{{{template-filing|}}}|deep |[[Category:Libro:{{BOOKNAME}}{{#if:{{#titleparts:{{PAGENAME}}||3}}|/{{#titleparts:{{PAGENAME}}|-1|2}}}}|{{{1|{{#if:{{CHAPTERNAME}}|{{#titleparts:{{PAGENAME}}||-1}}}}}}}]][[Category:Pages with deep filing]] |[[Category:Libro:{{BOOKNAME}}|{{{1|{{#titleparts:{{FULLPAGENAME}}||2}}}}}]] }} |Category={{#ifeq:{{FULLCHAPTERNAME}}|{{FULLBOOKNAME}} | |[[Category:{{#titleparts:{{PAGENAME}}|-1}}|{{{1|{{#titleparts:{{PAGENAME}}||-1}}}}}]] {{#ifeq:{{FULLCHAPTERNAME}}|Templates |[[Category:Book-specific templates|{{{1|{{PAGENAME}}}}}]] }} }} |#default={{#ifeq:{{{filing|}}}|deep |[[Category:{{#if:{{CHAPTERNAME}}|{{#titleparts:{{FULLPAGENAME}}|-1}}|{{FULLPAGENAME}}}}|{{{1|{{#if:{{CHAPTERNAME}}|{{#titleparts:{{PAGENAME}}||-1}}}}}}}]][[Category:Pages with deep filing]] |[[Category:{{FULLBOOKNAME}}|{{{1|{{#titleparts:{{FULLPAGENAME}}||2}}}}}]] }} }}</includeonly><noinclude> {{documentation}} </noinclude> a1avrwaot39sppsvpc1ertc2z9goxvl 427895 427894 2026-07-16T03:45:10Z Mazbel 57931 427895 wikitext text/x-wiki <includeonly>{{#switch:{{NAMESPACE}} |{{TALKSPACE}}= |Template={{#ifeq:{{{template-filing|}}}|deep |[[Category:Libro:{{BOOKNAME}}/Templates{{#if:{{#titleparts:{{PAGENAME}}||3}}|/{{#titleparts:{{PAGENAME}}|-1|2}}}}|{{{1|{{#if:{{CHAPTERNAME}}|{{#titleparts:{{PAGENAME}}||-1}}}}}}}]][[Category:Pages with deep filing]] |[[Category:Libro:{{BOOKNAME}}/Templates|{{{1|{{#titleparts:{{FULLPAGENAME}}||2}}}}}]] }} |Category={{#ifeq:{{FULLCHAPTERNAME}}|{{FULLBOOKNAME}} | |[[Category:{{#titleparts:{{PAGENAME}}|-1}}|{{{1|{{#titleparts:{{PAGENAME}}||-1}}}}}]] {{#ifeq:{{FULLCHAPTERNAME}}|Templates |[[Category:Book-specific templates|{{{1|{{PAGENAME}}}}}]] }} }} |#default={{#ifeq:{{{filing|}}}|deep |[[Category:Libro:{{#if:{{CHAPTERNAME}}|{{#titleparts:{{FULLPAGENAME}}|-1}}|{{FULLPAGENAME}}}}|{{{1|{{#if:{{CHAPTERNAME}}|{{#titleparts:{{PAGENAME}}||-1}}}}}}}]][[Category:Pages with deep filing]] |[[Category:Libro:{{FULLBOOKNAME}}|{{{1|{{#titleparts:{{FULLPAGENAME}}||2}}}}}]] }} }}</includeonly><noinclude> {{documentation}} </noinclude> f4zwy869v3pxgkwgwovziqkjvf89p2i Programación Orientada a Objetos 0 38251 427851 427840 2026-07-15T14:52:36Z Antimundo 74354 Actualizar etiquetas a HTML5 427851 wikitext text/x-wiki [[File:Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png|thumb|125px|Un ejemplo de código fuente que muestra las clases, métodos y herencia.]] <span style="font-size:120%;">La '''programación orientada a objetos''' o '''POO''' ('''OOP''' según sus siglas en inglés) es un paradigma de '''programación''' que usa los objetos en sus interacciones, para diseñar aplicaciones y programas informáticos.</span> Está basado en varias técnicas, incluyendo herencia, cohesión, abstracción, polimorfismo, acoplamiento y encapsulamiento. Su uso se popularizó a principios de la década de los años 1990. En la actualidad, existe variedad de lenguajes de programación que soportan la orientación a objetos. ==Contenido== {| class="wikitable" align="right" |- ! <span style="font-size: 120%;">[[Programación Orientada a Objetos/Texto completo|Versión para imprimir]]</span> |} <div style="font-size: 120%;"> * [[Programación Orientada a Objetos/Introducción|Capítulo 1: Introducción]] * [[Programación Orientada a Objetos/Origen|Capítulo 2: Origen]] * [[Programación Orientada a Objetos/Conceptos Fundamentales|Capítulo 3: Conceptos Fundamentales]] * [[Programación Orientada a Objetos/Características de la POO|Capítulo 4: Características de la POO]] * [[Programación Orientada a Objetos/Resumen|Capítulo 5: Resumen]] * [[Programación Orientada a Objetos/Lenguajes orientados a objetos|Capítulo 6: Lenguajes orientados a objetos]] </div> [[Categoría:Programación]] {{Estantes|Programación informática}} b0mezik68on7oijt4itr62vnth1a7cb 427857 427851 2026-07-15T17:32:54Z Antimundo 74354 Añadir noinclude para que no se transcluyan las categorías 427857 wikitext text/x-wiki [[File:Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png|thumb|125px|Un ejemplo de código fuente que muestra las clases, métodos y herencia.]] <span style="font-size:120%;">La '''programación orientada a objetos''' o '''POO''' ('''OOP''' según sus siglas en inglés) es un paradigma de '''programación''' que usa los objetos en sus interacciones, para diseñar aplicaciones y programas informáticos.</span> Está basado en varias técnicas, incluyendo herencia, cohesión, abstracción, polimorfismo, acoplamiento y encapsulamiento. Su uso se popularizó a principios de la década de los años 1990. En la actualidad, existe variedad de lenguajes de programación que soportan la orientación a objetos. ==Contenido== {| class="wikitable" align="right" |- ! <span style="font-size: 120%;">[[Programación Orientada a Objetos/Texto completo|Versión para imprimir]]</span> |} <div style="font-size: 120%;"> * [[Programación Orientada a Objetos/Introducción|Capítulo 1: Introducción]] * [[Programación Orientada a Objetos/Origen|Capítulo 2: Origen]] * [[Programación Orientada a Objetos/Conceptos Fundamentales|Capítulo 3: Conceptos Fundamentales]] * [[Programación Orientada a Objetos/Características de la POO|Capítulo 4: Características de la POO]] * [[Programación Orientada a Objetos/Resumen|Capítulo 5: Resumen]] * [[Programación Orientada a Objetos/Lenguajes orientados a objetos|Capítulo 6: Lenguajes orientados a objetos]] </div> <noinclude> [[Categoría:Programación]] {{Estantes|Programación informática}} </noinclude> elk2edopsjlxld3pvboz6xbwxxic28z Programación Orientada a Objetos/Introducción 0 38252 427906 427841 2026-07-16T03:55:10Z Mazbel 57931 actualización 427906 wikitext text/x-wiki Los '''objetos''' son entidades que tienen un determinado estado, comportamiento ('''método''') e identidad: *El estado está compuesto de datos o informaciones; serán uno o varios atributos a los que se habrán asignado unos valores concretos ('''datos'''). *El comportamiento está definido por los métodos o '''mensajes''' a los que sabe responder dicho '''objeto''', es decir, qué '''operaciones''' se pueden realizar con él. *La '''identidad''' es una propiedad de un objeto que lo diferencia del resto; dicho con otras palabras, es su identificador (concepto análogo al de identificador de una '''variable''' o una '''constante'''). Un objeto contiene toda la información que permite definirlo e identificarlo frente a otros objetos pertenecientes a otras '''clases''' e incluso frente a objetos de una misma clase, al poder tener valores bien diferenciados en sus atributos. A su vez, los objetos disponen de mecanismos de interacción llamados '''métodos''', que favorecen la comunicación entre ellos. Esta comunicación favorece a su vez el cambio de estado en los propios objetos. Esta característica lleva a tratarlos como unidades indivisibles, en las que no se separa el estado y el comportamiento. Los métodos (comportamiento) y atributos (estado) están estrechamente relacionados por la propiedad de conjunto. Esta propiedad destaca que una clase requiere de métodos para poder tratar los atributos con los que cuenta. El programador debe pensar indistintamente en ambos conceptos, sin separar ni darle mayor importancia a alguno de ellos. Hacerlo podría producir el hábito erróneo de crear clases contenedoras de información por un lado y clases con métodos que manejen a las primeras por el otro. De esta manera se estaría realizando una '''programación estructurada''' camuflada en un lenguaje de programación orientado a objetos. La '''POO''' difiere de la programación estructurada tradicional, en que en esta últimalos datos y los procedimientos están separados y sin relación, ya que lo único que se busca es el procesamiento de unos datos de entrada para obtener otros de salida. La programación estructurada anima al programador a pensar sobre todo en términos de procedimientos o funciones, y en segundo lugar en las estructuras de datos que esos procedimientos manejan. En la programación estructurada solo se escriben '''funciones''' que procesan datos. Los programadores que emplean POO, en cambio, '''primero definen objetos''' para luego enviarles mensajes solicitándoles que realicen sus '''métodos''' por sí mismos. {{AutoCat}} 46ath59dvyi0p0gheic4zaxtn7irb3u Programación Orientada a Objetos/Origen 0 38253 427907 427842 2026-07-16T03:55:21Z Mazbel 57931 actualización 427907 wikitext text/x-wiki Los conceptos de la '''programación orientada a objetos''' tienen origen en '''Simula 67''', un lenguaje diseñado para hacer simulaciones, creado por Ole-Johan Dahl y Kristen Nygaard, del '''Centro de Cómputo Noruego en Oslo'''. En este centro se trabajaba en simulaciones de naves, que fueron confundidas por la explosión combinatoria de cómo las diversas cualidades de diferentes naves podían afectar unas a las otras. La idea surgió al agrupar los diversos tipos de naves en diversas clases de objetos, siendo responsable cada clase de objetos de definir sus propios datos y comportamientos. Fueron refinados más tarde en Smalltalk, desarrollado en Simula en Xerox PARC (cuya primera versión fue escrita sobre '''Basic''') pero diseñado para ser un sistema completamente dinámico en el cual los objetos se podrían crear y modificar "sobre la marcha" (en tiempo de ejecución) en lugar de tener un sistema basado en programas estáticos. La programación orientada a objetos se fue convirtiendo en el estilo de programación dominante a mediados de los '''años ochenta''', en gran parte debido a la influencia de '''C++''', una extensión del lenguaje de '''programación C'''. Su dominación fue consolidada gracias al auge de las '''Interfaces gráficas de usuario''', para las cuales la programación orientada a objetos está particularmente bien adaptada. En este caso, se habla también de programación dirigida por eventos. Las características de orientación a objetos fueron agregadas a muchos lenguajes existentes durante ese tiempo, incluyendo '''[[Programación en Ada|Ada]]''', '''[[Visual Basic|BASIC]]''', '''[[Programación en LISP|Lisp]]''' y '''[[Programación en Pascal|Pascal]]''', entre otros. La adición de estas características a los lenguajes que no fueron diseñados inicialmente para ellas condujo a menudo a problemas de compatibilidad y en la capacidad de mantenimiento del código. Los lenguajes orientados a objetos "puros", por su parte, carecían de las características de las cuales muchos programadores habían venido a depender. Para saltar este obstáculo, se hicieron muchas tentativas para crear nuevos lenguajes basados en métodos orientados a objetos, pero permitiendo algunas características imperativas de maneras "seguras". El '''Eiffel''' de Bertrand Meyer fue un temprano y moderadamente acertado lenguaje con esos objetivos, pero ahora ha sido esencialmente reemplazado por '''[[Programación en Java|Java]]''', en gran parte debido a la aparición de '''[[Tecnologías de Internet|Internet]]''' y a la implementación de la '''[[w:Máquina virtual de Java|Máquina virtual de Java]]''' en la mayoría de '''navegadores'''. '''[[Programación en PHP|PHP]] en su versión 5''' se ha modificado; soporta una orientación completa a objetos, cumpliendo todas las características propias de la orientación a objetos. {{AutoCat}} jl12bic3mhn157un42ukcgpplvgoxoh Programación Orientada a Objetos/Conceptos Fundamentales 0 38254 427908 427843 2026-07-16T03:55:31Z Mazbel 57931 actualización 427908 wikitext text/x-wiki La '''programación orientada a objetos''' es una forma de programar que trata de encontrar una solución a estos problemas. Introduce nuevos conceptos, que superan y amplían conceptos antiguos ya conocidos. Entre ellos destacan los siguientes: * '''Clase''': definiciones de las propiedades y comportamiento de un tipo de objeto concreto. La '''instanciación''' es la lectura de estas definiciones y la creación de un objeto a partir de ellas. * '''Herencia''': (por ejemplo, herencia de la clase C a la clase D) es la facilidad mediante la cual la clase D hereda en ella cada uno de los atributos y operaciones de C, como si esos atributos y operaciones hubiesen sido definidos por la misma D. Por lo tanto, puede usar los mismos métodos y variables publicas declaradas en C. Los componentes registrados como "privados" (private) también se heredan, pero como no pertenecen a la clase, se mantienen escondidos al programador y sólo pueden ser accedidos a través de otros métodos públicos. Esto es así para mantener hegemónico el ideal de POO. * '''Objeto''': Instancia de una clase. Entidad provista de un conjunto de propiedades o atributos (datos) y de comportamiento o funcionalidad (métodos), los mismos que consecuentemente reaccionan a eventos. Se corresponden con los '''objetos reales del mundo que nos rodea''', o con objetos internos del sistema (del programa). Es una instancia a una clase. * '''Método''': algoritmo asociado a un objeto (o a una clase de objetos), cuya ejecución se desencadena tras la recepción de un "mensaje". Desde el punto de vista del comportamiento, es lo que el objeto puede hacer. Un método puede producir un cambio en las propiedades del objeto, o la generación de un "evento" con un nuevo mensaje para otro objeto del sistema. * '''Evento''': es un suceso en el sistema (tal como una interacción del usuario con la máquina, o un mensaje enviado por un objeto). El sistema maneja el evento enviando el mensaje adecuado al objeto pertinente. También se puede definir como evento la reacción que puede desencadenar un objeto; es decir, la acción que genera. * '''Atributos''': características que tiene la clase. * '''Mensaje''': una comunicación dirigida a un objeto, que le ordena que ejecute uno de sus métodos con ciertos parámetros asociados al evento que lo generó. * '''Propiedad o atributo''': contenedor de un tipo de datos asociados a un objeto (o a una clase de objetos), que hace los datos visibles desde fuera del objeto y esto se define como sus características predeterminadas, y cuyo valor puede ser alterado por la ejecución de algún método. * '''Estado interno''': es una variable que se declara privada, que puede ser únicamente accedida y alterada por un método del objeto, y que se utiliza para indicar distintas situaciones posibles para el objeto (o clase de objetos). No es visible al programador que maneja una instancia de la clase. '''Componentes de un objeto:''' atributos, identidad, relaciones y métodos. '''Identificación de un objeto:''' un objeto se representa por medio de una tabla o entidad que esté compuesta por sus atributos y funciones correspondientes. En comparación con un lenguaje imperativo, una "variable" no es más que un contenedor interno del atributo del objeto o de un estado interno, así como la "función" es un procedimiento interno del método del objeto. {{AutoCat}} s2iy6rpwcr3df6ef2v7vyhbeq8wopb5 Programación Orientada a Objetos/Características de la POO 0 38255 427909 427844 2026-07-16T03:55:41Z Mazbel 57931 actualización 427909 wikitext text/x-wiki '''Texto en negrita'''Existe un acuerdo acerca de qué características contempla la "orientación a objetos". Las características siguientes son las más importantes: '''como las cosas que se generan para realizar algun cambio en la vida cotidiana''' *'''Abstracción''': denota las características esenciales de un objeto, donde se capturan sus comportamientos. Cada objeto en el sistema sirve como modelo de un "agente" abstracto que puede realizar trabajo, informar y cambiar su estado, y "comunicarse" con otros objetos en el sistema sin revelar cómo se implementan estas características. Los procesos, las funciones o los métodos pueden también ser abstraídos, y, cuando lo están, una variedad de técnicas son requeridas para ampliar una abstracción. El proceso de abstracción permite seleccionar las características relevantes dentro de un conjunto e identificar comportamientos comunes para definir nuevos tipos de entidades en el mundo real. La abstracción es clave en el proceso de análisis y diseño orientado a objetos, ya que mediante ella podemos llegar a armar un conjunto de clases que permitan modelar la realidad o el problema que se quiere atacar. *'''Encapsulamiento''': significa reunir todos los elementos que pueden considerarse pertenecientes a una misma entidad, al mismo nivel de abstracción. Esto permite aumentar la cohesión de los componentes del sistema. Algunos autores confunden este concepto con el principio de ocultación, principalmente porque se suelen emplear conjuntamente. *'''Modularidad''': se denomina modularidad a la propiedad que permite subdividir una aplicación en partes más pequeñas (llamadas módulos), cada una de las cuales debe ser tan independiente como sea posible de la aplicación en sí y de las restantes partes. Estos módulos se pueden compilar por separado, pero tienen conexiones con otros módulos. Al igual que la encapsulación, los lenguajes soportan la modularidad de diversas formas. *'''Principio de ocultación''': cada objeto está aislado del exterior, es un módulo natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las propiedades de un objeto contra su modificación por quien no tenga derecho a acceder a ellas; solamente los propios métodos internos del objeto pueden acceder a su estado. Esto asegura que otros objetos no puedan cambiar el estado interno de un objeto de manera inesperada, eliminando efectos secundarios e interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso directo a los datos internos del objeto de una manera controlada y limitando el grado de abstracción. La aplicación entera se reduce a un agregado o rompecabezas de objetos. *'''Polimorfismo''': comportamientos diferentes, asociados a objetos distintos, pueden compartir el mismo nombre; al llamarlos por ese nombre se utilizará el comportamiento correspondiente al objeto que se esté usando. O, dicho de otro modo, las referencias y las colecciones de objetos pueden contener objetos de diferentes tipos, y la invocación de un comportamiento en una referencia producirá el comportamiento correcto para el tipo real del objeto referenciado. Cuando esto ocurre en "tiempo de ejecución", esta última característica se llama asignación tardía o asignación dinámica. Algunos lenguajes proporcionan medios más estáticos (en "tiempo de compilación") de polimorfismo, tales como las plantillas y la sobrecarga de operadores de C++. *'''Herencia''': las clases no están aisladas, sino que se relacionan entre sí, formando una jerarquía de clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases a las que pertenecen. La herencia organiza y facilita el polimorfismo y el encapsulamiento, permitiendo a los objetos ser definidos y creados como tipos especializados de objetos preexistentes. Estos pueden compartir (y extender) su comportamiento sin tener que volver a implementarlo. Esto suele hacerse habitualmente agrupando los objetos en clases y estas en árboles o enrejados que reflejan un comportamiento común. Cuando un objeto hereda de más de una clase se dice que hay herencia múltiple. *'''Recolección de basura''': la recolección de basura o ''garbage collector'' es la técnica por la cual el entorno de objetos se encarga de destruir automáticamente, y por tanto desvincular la memoria asociada, los objetos que hayan quedado sin ninguna referencia a ellos. Esto significa que el programador no debe preocuparse por la asignación o liberación de memoria, ya que el entorno la asignará al crear un nuevo objeto y la liberará cuando nadie lo esté usando.<br>En la mayoría de los lenguajes híbridos que se extendieron para soportar el Paradigma de Programación Orientada a Objetos como C++ u Object Pascal, esta característica no existe y la memoria debe desasignarse expresamente. {{AutoCat}} nrlf5xx16mdx4uffdkvm2zwvpl11j5p Programación Orientada a Objetos/Resumen 0 38256 427910 427845 2026-07-16T03:55:52Z Mazbel 57931 actualización 427910 wikitext text/x-wiki La '''programación orientada a objetos''' es un paradigma que utiliza objetos como elementos fundamentales en la construcción de la solución. Surge en los años 70. Un objeto es una abstracción de algún hecho o ente del mundo real que tiene atributos que representan sus características o propiedades y métodos que representan su comportamiento o acciones que realizan. Todas las propiedades y métodos comunes a los objetos se encapsulan o se agrupan en clases. Una clase es una plantilla o un prototipo para crear objetos; por eso se dice que los objetos son instancias de clases. {{AutoCat}} ho003wve8viji7nb59lflzfktx47irb Programación Orientada a Objetos/Lenguajes orientados a objetos 0 38257 427911 427846 2026-07-16T03:56:05Z Mazbel 57931 actualización 427911 wikitext text/x-wiki '''Simula''' (1967) es aceptado como el primer lenguaje que posee las características principales de un lenguaje orientado a objetos. Fue creado para hacer programas de simulación, en donde los "objetos" son la representación de la información más importante. '''Smalltalk''' (1972 a 1980) es posiblemente el ejemplo canónico, y con el que gran parte de la teoría de la programación orientada a objetos se ha desarrollado. Entre los lenguajes orientados a objetos se destacan los siguientes: *ABAP -> SAP Lenguaje orientado a eventos *ABL Lenguaje de programación de OpenEdge de Progress Software *ActionScript *ActionScript 3 *Ada *C++ *C# *Clarion *Clipper (lenguaje de programación) (Versión 5.x con librería de objetos Class(y)) *D *Object Pascal (Embarcadero Delphi) *Gambas *Genie *Harbour *Eiffel *Fortran 90/95 *Java *JavaScript (la herencia se realiza por medio de la programación basada en prototipos) *Lexico (en castellano) *Objective-C *Ocaml *Oz *R *Perl (soporta herencia múltiple. La resolución se realiza en preorden, pero puede modificarse al algoritmo linearization C3 por medio del módulo Class::C3 en CPAN) *PHP (a partir de su versión 5) *PowerBuilder *Python *Ruby *Self *Smalltalk (Entorno de objetos puro) *Magik (SmallWorld) *Vala *VB.NET *Visual FoxPro (en su versión 6) *Visual Basic 6.0 *Visual DataFlex *Visual Objects *XBase++ *Lenguaje DRP *Lenguaje de programación Scala (lenguaje usado por Twitter) Muchos de estos lenguajes de programación no son puramente orientados a objetos, sino que son híbridos que combinan la POO con otros paradigmas. Al igual que C++, otros lenguajes, como '''OOCOBOL''', '''OOLISP''', '''OOPROLOG''' y '''Object REXX''', han sido creados añadiendo extensiones orientadas a objetos a un lenguaje de programación clásico. Un nuevo paso en la abstracción de paradigmas de programación es la '''Programación Orientada a Aspectos''' ('''POA'''). Aunque es todavía una metodología en estado de maduración, cada vez atrae a más investigadores e incluso proyectos comerciales en todo el mundo. {{AutoCat}} l6u2aplv9wqivmj2hur1j8aza4br2ur Física/Dinámica de rotación/Rotación alrededor de un eje fijo 0 39322 427964 410440 2026-07-16T05:58:56Z Mazbel 57931 categorización 427964 wikitext text/x-wiki '''Rotación alrededor de un eje fijo''' es un caso especial del [[movimiento rotacional]]. La hipótesis del eje fijo excluye la posibilidad de un eje en movimiento, y no puede describir fenómenos como el “bamboleo”. De acuerdo al [[teorema de la rotación de Euler]], la rotación alrededor de más de un eje al mismo tiempo es imposible, así pues, si dos rotaciones son forzadas al mismo tiempo en diferente eje, aparecerá un nuevo eje de rotación. Las siguientes fórmulas y conceptos son útiles para comprender más a fondo la rotación sobre un eje fijo. == Relación entre el movimiento de rotación y el lineal == El movimiento de rotación tiene una estrecha relación con el movimiento lineal. El desplazamiento lineal es el producto del desplazamiento angular por el radio del círculo descrito por el movimiento. :s=θR La velocidad lineal es el producto de la velocidad angular por el radio del círculo descrito por el movimiento. :v=ωR La aceleración tangencial es el producto de la aceleración angular por el radio del círculo descrito por el movimiento. :a=αR Así mismo, tomando en cuenta lo anterior, las fórmulas de la cinemática mantienen esta misma relación. Mientras que las fórmulas de la cinemática del movimiento lineal son: <math>v_f^2=v_o^2+2ad</math> <math>v_f=v_o+at</math> <math>d=v_o t+1/2 at^2</math> Para la cinemática del movimiento rotacional utilizaremos las siguientes: :ω_f ^2 = ω_o ^2 + 2αθ :ω_f=ω_o+αt :θ=ω_o t+1/2 αt^2 == Desplazamiento angular θ == El desplazamiento angular de un objeto determina la cantidad de rotación del mismo y es descrito por la siguiente fórmula: :∆θ=θ_2-θ_1 El desplazamiento angular se mide en radianes (rad), aunque también se puede medir en revoluciones (rev). A continuación se presentan la comparación entre unidades. :1 rad = 57.3° 1 rev = 360° = 2π rad == Velocidad angular ω == La velocidad angular es el cambio del desplazamiento angular con respecto al tiempo, como se presenta en la siguiente fórmula: :ω= ∆θ/∆t =(θ_2-θ_1)/(t_2-t_1 ) La velocidad angular, es siempre la misma sin importar la distancia que haya entre una partícula y el eje de rotación. Las unidades en que se expresa comúnmente la velocidad angular es en radianes por segundo (rad/s), pero también puede expresarse en revoluciones por minuto (rpm o rev/min) y en revoluciones por segundo (rev/s). == Aceleración angular α == Al igual que en el movimiento lineal, el movimiento rotacional puede tener aceleración. La velocidad angular puede alterarse por la influencia de un momento de torsión resultante. La fórmula para calcular la aceleración angular es la siguiente: : <math> \alpha= \cfrac{\Delta \omega}{\Delta t}= \cfrac{\omega_2 - \omega_1}{t_2 - t_1} </math> Momento de torsión (torque) En la ley del movimiento rotacional, Newton menciona lo siguiente: {{cita|Un momento de torsión resultante aplicado a un cuerpo rígido siempre genera una aceleración angular que es directamente proporcional al momento de torsión aplicado e inversamente proporcional al momento de inercia del cuerpo. <ref>{{cita libro |apellido=Tippens |nombre=Paul |título=FÍSICA CONCEPTOS Y APLICACIONES |fechaacceso=7 de mayo de 2011 |idioma=español |edición=sexta|año=2001|editorial=McGraw-Hill |capítulo=11 |páginas=253}}</ref>}} : <math> \tau = I \, \alpha </math> == Energía cinética rotacional. == Tomando en cuenta que la energía cinética lineal está dada por la siguiente fórmula: :K=1/2 mv^2 Y manteniendo la misma relación que ya se expresó más arriba, la energía cinética rotacional está dada por la fórmula: :K=1/2 mω^2 R^2 Pero, si consideramos que un cuerpo está formado por diversas partículas de masas diferentes y localizadas a diferentes distancias del eje de rotación, la energía cinética total del cuerpo sería la sumatoria de las energías cinéticas de todas las partículas del cuerpo. :K_T=∑▒〖1/2 mω^2 R^2 〗 Y tomando en cuenta que la velocidad angular es la misma para todas las partículas, la fórmula podríamos ordenarla de la siguiente manera: :K_T=1/2 ω^2 (∑▒〖mR^2 〗) Viendo que la cantidad en paréntesis no considera si la partícula está en movimiento o en reposo, definiremos a esa cantidad como momento de inercia. == Momento de inercia == La inercia es una propiedad de la materia para resistirse a cualquier cambio en su estado, ya sea de reposo o de movimiento como lo describe la Primera Ley de Newton: {{cita|Un cuerpo permanece en estado de reposo o de movimiento rectilíneo uniforme, a menos que una fuerza externa no equilibrada actúe sobre él.|Primera Ley de Newton<ref>{{cita libro |apellido=Tippens |nombre=Paul |título=FÍSICA CONCEPTOS Y APLICACIONES |fechaacceso=7 de mayo de 2011 |idioma=español |edición=sexta|año=2001|editorial=McGraw-Hill |capítulo=4 |páginas=74 }}</ref>}} Todos los cuerpos que giran alrededor de un eje desarrollan una inercia a la rotación (se resisten a cambiar su velocidad de rotación y la dirección de su giro. La inercia de un cuerpo a la rotación está determinada por su momento de inercia, que es la resistencia que opone un cuerpo en rotación al cambio de su velocidad de rotación. La fórmula para calcular el momento de inercia de un cuerpo compuesto por partículas de masas dispersas es la siguiente: :I=∑▒〖mR^2〗 Para calcular el momento de inercia de cuerpos con distribuciones parejas de masa, se utilizan fórmulas específicas para cada cuerpo. Algunos de los más comunes son los siguientes: * Aro delgado: <math>I=mR^2</math> * Aro delgado alrededor de uno de sus diámetros : <math>I= 1/2 mR^2</math> * Disco sólido: <math>I= 1/2 mR^2</math> * Cilindro sólido: <math>I= 1/2 mR^2</math> * Cilindro hueco: <math>I= 1/2 m(R_1^2+R_2^2 )</math> * Barra delgada con eje a través de su centro : <math>I= 1/12 ml^2</math> * Barra delgada con eje en uno de sus extremos: <math>I= 1/3 ml^2</math> * Esfera sólida con eje en su diámetro: <math>I= 2/5 mR^2</math> * Esfera hueca de pared delgada: <math>I= 2/3 mR^2</math> Dada la fórmula del momento de inercia, podemos darnos cuenta de que la unidad en que se mide la inercia es en kilogramo-metro al cuadrado (kg m²).<ref>{{cita libro |apellido=Tippens |nombre=Paul |título=FÍSICA CONCEPTOS Y APLICACIONES |fechaacceso=7 de mayo de 2011 |idioma=español |edición=sexta|año=2001|editorial=McGraw-Hill |capítulo=11 |páginas=241-259 }}</ref> == Referencias == {{listaref}} {{AutoCat}} [[Categoría:Mecánica]] rc81utiuik8izq15zmprpoop4t36or5 Programación Orientada a Objetos/Texto completo 0 41777 427855 234402 2026-07-15T17:24:07Z Antimundo 74354 Mantenimiento: Retirar etiqueta no cerrada 427855 wikitext text/x-wiki {{Versión para imprimir|Programación Orientada a Objetos}} {{Portada libro|Programación Orientada a Objetos}} <div style="text-align:center">''por es.wikibooks.org''</div> __TOC__ __NOEDITSECTION__ {{:Programación Orientada a Objetos}} ==Capítulo 1: Introducción== {{:Programación Orientada a Objetos/Introducción|Capítulo 1: Introducción}} == Capítulo 2: Origen == {{:Programación Orientada a Objetos/Origen|Capítulo 2: Origen}} == Capítulo 3: Conceptos Fundamentales == {{:Programación Orientada a Objetos/Conceptos Fundamentales|Capítulo 3: Conceptos Fundamentales}} == Capítulo 4: Características de la POO == {{:Programación Orientada a Objetos/Características de la POO|Capítulo 4: Características de la POO}} == Capítulo 5: Resumen == {{:Programación Orientada a Objetos/Resumen|Capítulo 5: Resumen}} == Capítulo 5: Lenguajes orientados a objetos == {{:Programación Orientada a Objetos/Lenguajes orientados a objetos|Capítulo 6: Lenguajes orientados a objetos}} l5z5j7s30vy9ll0z78p4wi9iatlbums Física/Análisis dimensional 0 42211 427956 415501 2026-07-16T05:56:35Z Mazbel 57931 categorización 427956 wikitext text/x-wiki El análisis dimensional es una herramienta que nos permite averiguar de forma rápida si estamos cometiendo algún fallo en nuestro cálculo. La forma más fácil de explicarlo es con un ejemplo. Supongamos que queremos hallar la rapidez de un móvil pero en nuestro calculo hemos cometido errores. Lo primero que debemos hacer es reemplazar cada variable y constante por sus unidades (si las tiene) entre corchetes. Recordemos que a una magnitud sin unidades se le llama adimensional. La rapidez viene dada por: <math> v = {x \over t} </math> Reemplazando por sus magnitudes: <math> [rapidez] = {[L] \over [T]} </math> Donde L es longitud y T es tiempo. Si en mi cálculo obtengo como resultado algo del tipo: <math> v = {x_1 x_2 \over t} </math> Utilizando análisis dimensional me doy cuenta de que: <math> [rapidez] = {[L]^2 \over [T]} </math> Las unidades no corresponden a las de la rapidez y por tanto esa cantidad carece de significado en este caso. ==Averiguando las unidades de una magnitud== Supongamos que queremos averiguar las unidades de la constante gravitatoria G. Sabemos que la formula de Newton para la fuerza de gravedad viene dada por: <math>\mathbf{F} = -G \frac {m_{1}m_{2}} {|\mathbf{r}|^2}\mathbf{\hat{u}}_{r}</math> Despejando la constante G y tomando valores absolutos queda: <math> |G| = \frac {{|\mathbf{F}|} |\mathbf{r}|^2 } {m_{1}m_{2}} </math> Donde <math>G</math> = [[w:Constante_de_gravitación_universal|constante de gravitación universal]], <math>r</math> = la distancia entre los centros de las masas, y <math>m_1</math> y <math>m_2</math> = las masas de los objetos que interactúan. Utilizando análisis dimensional: <math> [G] = \frac {[N] [m]^2 } {[Kg]^2} = \frac {[Kg {m \over s^2}] [m]^2} {[Kg]^2} = \frac {[m]^3} {[Kg] [s]^2} </math> Donde <math>N</math> = [[w:Newton|Newtons]]; <math>m</math> = metros; <math>Kg</math> = kilogramos y <math>s</math> = segundos Como se puede ver, el análisis dimensional es una herramienta básica que nos ahorrará muchos problemas y nos guiará en la resolución de problemas en física. {{AutoCat}} dw3l6s8pqv9movuyrigiglhv730fj3n Haskell 0 42615 427878 427830 2026-07-15T18:47:25Z Antimundo 74354 Usar logotipo actual de Haskell al igual que en Wikipedia y en enWikibooks 427878 wikitext text/x-wiki __NOTOC__ {{traduciendo|en|Haskell}} [[Archivo:Haskell-Logo.svg|derecha|sinmarco]] {{Versión imprimible}} {{Colección}} {{Versión en PDF}} {{Book search|float=right}} '''Haskell''' es un lenguaje de programación puramente funcional. Se diferencia de varias formas: * Haskell es un lenguaje de programación funcional ''puro''. Cuando se invoca una función usando los mismos argumentos devolverá el mismo resultado cada vez. * Haskell es ''perezoso''. Las evaluaciones se realizan solo cuando es necesario. * Haskell proporciona un sistema de tipado moderno con características sofisticadas, como clases de tipos y tipos de datos algebraicos generalizados (muy pronto, términos como estos van a sonar bien fuera del lenguaje). * Haskell provee un sistema tipográfico moderno con funciones de última generación, como clases tipográficas y tipos de datos algebraicos generalizados (muy pronto, términos como esos saldrán fácilmente de su boca). Haskell es divertido de usar porque tratar con funciones puras hace que el código sea mucho más fácil de razonar, y el sistema de tipo avanzado ayuda a detectar errores tontos y profundos. El objetivo de este libro es introducir al lector, sea este un estudiante o persona interesada en aprender el lenguaje Haskell, en dos aspectos; en primer lugar, al lenguaje Haskell desde las características más básicas a las avanzadas y en segundo lugar a la programación en general. Se insta que los programadores avanzados sean particularmente pacientes con este proceso. Es muy probable que los lenguajes con los que están familiarizados difieran mucho de Haskell, y los hábitos que provienen de esos lenguajes pueden dificultar el proceso de entendimiento de cómo se maneja la sintaxis; Haskell es simple, pero diferente. Aprender a ver el mundo a través de la perspectiva matemática de un programador funcional es una aventura en un mundo nuevo y desafiante, que trae conocimiento valioso más allá de los límites de cualquier lenguaje. Teniendo en cuenta todos estos aspectos, este libro también pretende ser una herramienta y ayuda a la hora de programar en Haskell. == Descripción general == El libro está dividido en tres secciones: una unidad para principiantes, una unidad avanzada y una sección llamada Haskell en la práctica. La última sección, que cubre casos prácticos de uso, depende únicamente de la unidad para principiantes. Los programadores experimentados pueden leer la descripción general para evaluar rápidamente qué hace que Haskell sea único y diferente de otros lenguajes. {{Información|¡Por favor contribuya! Cualquiera, independientemente de la competencia de Haskell, puede ayudar. Dedique cinco minutos a mejorar un módulo y ahorre horas de tiempo a otra persona. Revisar la [[/Notas para contribuyentes|notas para las contribuyentes]]. Incluso si te confundes con una página, cuéntanoslo en la página de discusión (Por supuesto, cortesmente).}} == Unidad para principiantes == Esta sección le presenta los conceptos básicos de Haskell y algunas bibliotecas de uso común. Al final de esta unidad, debería poder escribir programas simples de Haskell. La mayoría de los capítulos incluyen ejercicios, con soluciones, para su práctica. {|width="100%" cellspacing="0" cellpadding="15" valign="top" style="margin:0.8em 0;border:1px solid MediumAquamarine;background:honeydew" |valign="top" style="border-right: 1px dashed MediumAquamarine"| === Principios básicos de Haskell === *{{Capítulo de Haskell/Principios básicos de Haskell|sep= *}} |valign="top" style="border-right: 1px dashed MediumAquamarine"| === Haskell nivel elemental === *{{Capítulo de Haskell/Haskell elemental|sep= *}} |valign="top" style="border-right: 1px dashed MediumAquamarine"| === Haskell nivel intermedio === *{{Capítulo de Haskell/Haskell intermedio|sep= *}} |valign="top"| === Mónadas === *{{Capítulo de Haskell/Mónadas|sep=*|subsep=&nbsp;-&nbsp;|breaksep= **|firstsep= *}} |} == Unidades avanzadas == Esta sección presenta conceptos de programación funcional más amplios, como diferentes estructuras de datos y teoría de tipos. También cubrirá temas más prácticos como la concurrencia. {|width="100%" cellspacing="0" cellpadding="15" valign="top" style="margin:0.8em 0; border: 1px solid SlateBlue; background:#F7F7FF" |valign="top" style="border-right: 1px dashed SlateBlue"| === Haskell avanzado === *{{Capítulo de Haskell/Haskell avanzado|sep= *}} |valign="top" style="border-right:1px dashed SlateBlue"| === Diversión con tipos === *{{Capítulo de Haskell/Diversión con tipos|sep= *}} |valign="top" style="border-right:1px dashed SlateBlue"| === Teoría ampliada === *{{Capítulo de Haskell/Teoría ampliada|sep= *}} |valign="top"| === Rendimiento de Haskell === *{{Capítulo de Haskell/Rendimiento de Haskell|sep= *}} |} == Haskell en la práctica == Los problemas cotidianos de trabajar con Haskell incluyen elementos como conocer las bibliotecas estándar, crear interfaces gráficas y trabajar con bases de datos. Debería poder saltar directamente a esta sección desde la unidad para principiantes. {|width="100%" cellspacing="0" cellpadding="15" style="margin-top:0.8em;margin-bottom:0.8em;border:1px solid gold;background:cornsilk" |valign="top" style="border-right: 1px dashed gold"| === Bibliotecas de referencia === *{{Capítulo de Haskell/Bibliotecas de referencia|sep=*|subsep=&nbsp;-&nbsp;|breaksep= **|firstsep= *}} |valign="top" style="border-right: 1px dashed gold"| === Prácticas generales === *{{Capítulo de Haskell/Prácticas generales|sep= *}} |valign="top"| === Tareas especializadas === *{{Capítulo de Haskell/Tareas especializadas|sep= *}} |} == Apéndices == * [[/Azúcar sintáctico/]] * [[/Soluciones|Respuestas a ejercicios]] * [[/Historia de Haskell/]] * [[/Implementaciones de Haskell/]] * [[/Autores/|Autores y agradecimientos]] (original en inglés) == Acerca del libro == * [[/Notas para los contribuyentes/]] * [[/Convenciones de estilo/]] * [[/To do/]] * [[:Categoría:Haskell/Plantillas|Plantillas para el wikilibro de Haskell]] * [[/Módulos experimentales/|Módulos experimentales]] * [[/Lista de tópicos/|Lista de tópicos]] == Otros tutoriales de Haskell == * [http://www.haskell.org/haskellwiki/Meta-tutorial Haskell Meta-tutorial] - the tutorial to find other tutorials * [http://www.learnyouahaskell.com/Chapters Learn You a Haskell for Great Good] - Tutorial aimed at beginners who may have experience in imperative programming languages but haven't programmed in a functional language before. Freely available online under a CC-BY-NC-SA license; also released as a conventional book. * [http://book.realworldhaskell.org/ Real World Haskell] - an O'Reilly book, available online at no charge (CC-BY-NC license). Built around case studies of practical applications. * [[Write Yourself a Scheme in 48 Hours]] - (imported here) An alternate approach to teaching Haskell (and perhaps Scheme), aimed at a more advanced audience (though not necessarily one that knows how to program!) * [[/YAHT|Yet Another Haskell Tutorial]] - (imported here) is aimed at beginners and takes a practical approach to things. == Recursos adicionales == * [http://www.haskell.org/haskellwiki/Learning_Haskell Learning Haskell] en haskell.org * [http://dev.stephendiehl.com/hask/ What I Wish I Knew When Learning Haskell] - A wide-ranging collection of concise summaries of many intermediate and advanced Haskell topics. Released in the public domain. {{Estantes|Lenguajes de programación}} bx2s2wkdnd8ex100a66wb5votb24sgu Física/Electromagnetismo/Magnetismo 0 53038 427967 379364 2026-07-16T06:04:01Z Mazbel 57931 categorización 427967 wikitext text/x-wiki El magnetismo es un fenómeno físico por el que los objetos ejercen fuerzas de atracción o repulsión sobre otros materiales. Hay materiales que presentan propiedades magnéticas detectables fácilmente, como el níquel, el hierro o el cobalto, que pueden llegar a convertirse en un ''imán''. Existe un mineral llamado ''magnetita'' que es conocido como el único imán natural. De hecho de este mineral proviene el término de magnetismo. Sin embargo, todos los materiales son influidos, de mayor o menor forma, por la presencia de un campo magnético. El magnetismo es la propiedad algunos objetos que consiste en atraer otros objetos hacia ellos, el imán puede atraer ciertos metales Fuente: Libro de la SEP ciencias y tecnología (Física secundaria) http://www.endesaeduca.com/Endesa_educa/recursos-interactivos/conceptos-basicos/magnetismo {{AutoCat}} tod3ecp50cd8y4bl3ift17njelqtp30 Física/Electromagnetismo/Imanes naturales 0 53039 427973 297108 2026-07-16T06:14:44Z Mazbel 57931 categorización 427973 wikitext text/x-wiki Tienen la propiedad de atraer todas las sustancias magneticas. Su característica de atraer hierros es natural & no es influida por los seres humanos. Estan compuestos por el oxido de hierro,son aquellos que se encuentran en la Tierra y que atraen al hierro. Denominados magnetita , hoy sabemos que es hierro cristalino Fe3O4. Pero también la Tierra es un imán natural. {{AutoCat}} rwmzzgvwwg5swzt4kzggf93hejopzly Física/Conversión de unidades 0 53041 427963 298010 2026-07-16T05:58:41Z Mazbel 57931 categorización 427963 wikitext text/x-wiki ==Longitud== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |pulgada |milímetro (mm) |25.4 |- |pulgada |metro (m) |0.0254 |- |pie (ft) |metro (m) |0.3047 |- |yarda (yd) |metro (m) |0.9144 |} ==Área== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |pie cuadrado (ft 2) |metro cuadrado |0.09290 |- |pulgada cuadrado |milímetro cuadrado |645.2 |- |pulgada cuadrado |metro cuadrado |0.0000006452 |- |yarda cuadrada |metro cuadrado |0.08361 |} ==Volumen== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |pulgada cubica |metro cubico |0.00001639 |- |pie cubico |metro cubico |0.02832 |- |yarda cubica |metro cubico |0.7646 |- |galòn (Canada) |metro cubico |4.546 |- |galòn (Canada) |litro |0.004546 |- |galòn (EUA) |metro cubico |3.785 |- |galòn (EUA) |litro |0.003785 |- |} ==Masa== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |pulgada |milímetro (mm) |25.4 |- |pulgada |metro (m) |0.0254 |- |pie (ft) |metro (m) |0.3047 |- |yarda (yd) |metro (m) |0.9144 |} ==Fuerza== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |kilopontio |kilogramo |453.6 |- |kilopontio |Newton |4448 |- |libra |kilogramo |0.4536 |- |libra |Newton |4.448 |} ==Energía== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |Unidad Termica Britanica |joule |1056 |- |Kilowatt Hora |joule |3,600,000 |- |} ==Temperatura== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |pulgada | | |- |pulgada | | |- |pie (ft) | | |- |yarda (yd) | | |} ==Presión o Tensión== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |pulgada | | |- |pulgada | | |- |pie (ft) | | |- |yarda (yd) | | |} ==Momento Flexor o Tensor== {| class="wikitable" !Imperial !Internacional !Equivalencia |- |pulgada | | |- |pulgada | | |- |pie (ft) | | |- |yarda (yd) | | |} == Fuente == http://www.inti.gob.ar/cirsoc/pdf/tabla_conversion.pdf {{AutoCat}} 800j5pnfsrxg5hdhzvme19w74ss76xa Plantilla:AutoCat/uso 10 53734 427915 304831 2026-07-16T04:00:08Z Mazbel 57931 actualización 427915 wikitext text/x-wiki {{subpágina de documentación}} === Uso === Añade esta plantilla a las distintas páginas que forman parte de un libro. Esta plantilla se encargará de categorizarla automáticamente dentro de la categoría de su libro. === Sintaxis === <syntaxhighlight lang="wikitext"> {{AutoCat}} </syntaxhighlight> No necesita parámetros. === Ejemplo === En la página: <syntaxhighlight lang="text"> Haskell/Bucles </syntaxhighlight> añadiendo: <syntaxhighlight lang="wikitext"> {{AutoCat}} </syntaxhighlight> la página se incluirá automáticamente en: <syntaxhighlight lang="text"> Categoría:Libro:Haskell </syntaxhighlight> <includeonly> [[Categoría:Wikilibros:Plantillas de organización interna]] </includeonly> sskwyw5j9a6jhusbfz1h4hmufndf1p6 Física/Electromagnetismo/Campo Magnético 0 54927 427971 323271 2026-07-16T06:13:11Z Mazbel 57931 categorización 427971 wikitext text/x-wiki ==Fuerza de Lorentz== Entre las definiciones de '''campo magnético''' se encuentra la dada por la fuerza de Lorentz. Esto sería el efecto generado por una [[corriente eléctrica]] o un [[imán (física)|imán]], sobre una región del espacio en la que una [[carga eléctrica]] puntual de valor '''(q)''', que se desplaza a una [[velocidad]] <math>\mathbf{(v)}</math>, experimenta los efectos de una [[fuerza]] que es [[secante]] y proporcional tanto a la velocidad '''(v)''' como al campo '''(B)'''. Así, dicha carga percibirá una fuerza descrita con la siguiente ecuación. {{ecuación| <math>\mathbf{F} = q\mathbf{v} \times \mathbf{B}</math> ||left}} donde '''F''' es la [[fuerza magnética]], '''v''' es la velocidad y '''B''' el campo magnético, también llamado '''inducción magnética''' y '''densidad de flujo magnético'''. (Nótese que tanto '''F''' como '''v''' y '''B''' son magnitudes vectoriales y el ''producto vectorial'' tiene como resultante un vector perpendicular tanto a ''v'' como a ''B''). El módulo de la fuerza resultante será: {{ecuación| <math>|\mathbf{F}| = |q||\mathbf{v}||\mathbf{B}|\cdot \mathop{\sen} (\theta)</math> ||left}} La existencia de un campo magnético se pone de relieve gracias a la propiedad (la cual la podemos localizar en el espacio) de orientar un [[magnetómetro]] (laminilla de acero imantado que puede girar libremente). La aguja de una [[brújula]], que evidencia la existencia del [[campo magnético terrestre]], puede ser considerada un magnetómetro. == Fuentes del campo magnético == Un campo magnético tiene dos fuentes que lo originan. Una de ellas es una [[corriente eléctrica]] de conducción, que da lugar a un campo magnético estático, si es constante. Por otro lado una [[corriente de desplazamiento]] origina un campo magnético variante en el tiempo, incluso aunque aquella sea estacionaria. La relación entre el campo magnético y una corriente eléctrica está dada por la [[ley de Ampère]]. El caso más general, que incluye a la corriente de desplazamiento, lo da la [[ley de Ampère-Maxwell]]. === Campo magnético producido por una carga puntual === El campo magnético generado por una única carga en movimiento (no por una corriente eléctrica) se calcula a partir de la siguiente expresión: {{Ecuación|<math>\mathbf{B}=\frac{\mu_0}{4\pi}\frac{(q\mathbf{v})\times \hat{\mathbf{u}}_r}{r^2}</math>||left}} Donde <math>\mu_0=4 \pi \cdot 10^{-7}\frac{\mbox{N}}{\mbox{A}^2}</math>. Esta última expresión define un [[campo solenoidal|campo vectorial solenoidal]], para distribuciones de cargas en movimiento la expresión es diferente, pero puede probarse que el campo magnético sigue siendo un campo solenoidal. === Campo magnético producido por una distribución de cargas === * La inexistencia de cargas magnéticas lleva a que el campo magnético es un [[campo solenoidal]] lo que lleva a que localmente puede ser derivado de un [[Potencial vector magnético|potencial vector]] <math>\mathbf{A}</math>, es decir: {{Ecuación| <math>\mathbf{B} = \nabla \times \mathbf{A}</math> ||left}} A su vez este potencial vector puede ser relacionado con el vector [[densidad de corriente]] mediante la relación: {{Ecuación| <math>\Delta \mathbf{A} = \mu_0 \mathbf{j}</math> ||left}} La ecuación anterior planteada sobre <math>\scriptstyle \R^3</math>, con una distribución de cargas contenida en un conjunto compacto, la solución es expresable en forma de integral. Y el campo magnético de una distribución de carga viene dado por: {{Ecuación| <math>\mathbf{B}(\mathbf{r}) =\frac{\mu_0}{4\pi} \int_{V_1} \frac{\mathbf{j}_1 \times \mathbf{\hat{u}}_r} {\|\mathbf{r}-\mathbf{r}_1\|^2}\ \mathrm{d}V_1</math> ||left}} === Inexistencia de cargas magnéticas aisladas === Cabe destacar que, a diferencia del [[campo eléctrico]], en el campo magnético no se ha comprobado la existencia de [[Monopolo magnético|monopolos magnéticos]], sólo [[Dipolo magnético|dipolos magnéticos]], lo que significa que las líneas de campo magnético son cerradas, esto es, el número neto de líneas de campo que entran en una superficie es igual al número de líneas de campo que salen de la misma superficie. Un claro ejemplo de esta propiedad viene representado por las líneas de campo de un [[Imán (física)|imán]], donde se puede ver que el mismo número de líneas de campo que salen del polo norte vuelve a entrar por el polo sur, desde donde vuelven por el interior del imán hasta el norte. [[Archivo:Electromagnetism.svg|thumb|250px|Ilustración de un campo magnético alrededor de un alambre a través del cual fluye [[corriente eléctrica]].]] Como se puede ver en el dibujo, independientemente de que la carga en movimiento sea positiva o negativa, en el punto A nunca aparece campo magnético; sin embargo, en los puntos B y C el campo magnético invierte su dirección dependiendo de si la carga es positiva o negativa. La dirección del campo magnético viene dado por la [[regla de la mano derecha]], siendo las pautas las siguientes: * en primer lugar se imagina un vector qv, en la misma dirección de la trayectoria de la carga en movimiento. La dirección de este vector depende del signo de la carga, esto es, si la carga es positiva y se mueve hacia la derecha, el vector +qv estará orientado hacia la derecha. No obstante, si la carga es negativa y se mueve hacia la derecha, el vector es -qv va hacia la izquierda; * a continuación, vamos ''señalando'' con los cuatro dedos de la ''mano derecha'' (índice, medio, anular y meñique), desde el primer vector qv hasta el segundo vector Ur, por el camino más corto o, lo que es lo mismo, el camino que forme el ángulo menor entre los dos vectores. El pulgar extendido indicará en ese punto la dirección del campo magnético. ===Energía almacenada en campos magnéticos=== La energía es necesaria para generar un campo magnético, para trabajar contra el campo eléctrico que un campo magnético crea y para cambiar la magnetización de cualquier material dentro del campo magnético. Para los materiales no-dispersivos, se libera esta misma energía tanto cuando se destruye el campo magnético para poder modelar esta energía, como siendo almacenado en el campo magnético. Para materiales lineales y no dispersivos (tales que <math>\scriptstyle B = \mu H</math> donde μ es independiente de la frecuencia), la densidad de energía es: {{ecuación| <math>\mathcal{E}_M = \frac{B^2}{2\mu} = \frac{\mu H^2}{2}</math> }} Si no hay materiales magnéticos alrededor, entonces el μ se puede substituir por μ<sub>0</sub>. La ecuación antedicha no se puede utilizar para los materiales no lineales, se utiliza una expresión más general dada abajo. Generalmente la cantidad incremental de trabajo por el δW del volumen de unidad necesitado para causar un cambio pequeño del δB del campo magnético es: δW= H*δB Una vez que la relación entre H y B se obtenga, esta ecuación se utiliza para determinar el trabajo necesitado para alcanzar un estado magnético dado. Para los materiales como los ferromagnéticos y superconductores el trabajo necesitado también dependerá de cómo se crea el campo magnético. {{AutoCat}} 5mjqw4dgb95n1w2ufirbrzrzw9ch4e5 Física/Electromagnetismo/Flujo Magnético 0 54928 427968 416694 2026-07-16T06:04:27Z Mazbel 57931 categorización 427968 wikitext text/x-wiki El '''flujo magnético''' (representado por la letra griega fi '''''{{w|Φ}}'''''), es una medida de la cantidad de [[Física/Electromagnetismo/Magnetismo|magnetismo]], y se calcula a partir del [[Física/Electromagnetismo/Campo Magnético|campo magnético]], la superficie sobre la cual actúa y el ángulo de incidencia formado entre las [[w:línea de fuerza|líneas de campo]] magnético y los diferentes elementos de dicha superficie. La unidad de flujo magnético en el [[Física/Sistema Internacional de Unidades (SI)|Sistema Internacional de Unidades]] es el [[w:Weber (unidad)|weber]] y se designa por ''Wb'' (motivo por el cual se conocen como ''weberímetros'' los aparatos empleados para medir el flujo magnético). En el [[Física/Sistema Cegesimal o CGS|sistema cegesimal]] se utiliza el [[w:Maxwell (unidad)|maxwell]] (1 weber =10<sup>8</sup> maxwells). ::::'''[Wb]=[V]·[s]'''<ref>{{cita web | url = http://www.sc.ehu.es/sbweb/fisica/unidades/unidades/unidades.htm | título = Sistema Internacional de Unidades | fechaacceso = 23 de agosto | añoacceso = 2010 | idioma = español}}</ref> [[Archivo:FlujoMagnetico.svg|thumb|Flujo magnético por una espira.]] Para campos uniformes y superficies planas. si llamamos <math> \vec{B}\,\!</math> al {{w|vector}} campo magnético y <math>\vec{S}\,\!</math> al vector área de la superficie evaluada, el flujo Φ que pasa a través de dicha área es simplemente el producto escalar del valor absoluto de ambos vectores: :<math>\Phi = \vec{B} \cdot \vec{S}\,\!</math> Si llamamos <math>\vartheta</math> al ángulo entre los dos vectores podemos desarrollar la expresión como: :<math>\Phi = \vec{B} \cdot \vec{S} = |\vec B| |\vec S | \, \cos(\vartheta) \,\!</math> [[Archivo:Surface normals.svg|thumb|250px|Vectores normales a una superficie dada.]] Generalizando aún más, podemos tener en cuenta una superficie irregular atravesada por un campo magnético heterogéneo. De esta manera, tenemos que considerar cada diferencial de área: :<math>\Phi = \int_S \vec{B} \cdot d\vec{S} \,</math> == Cuantización del flujo magnético == [[Archivo:Cuantización del flujo magnético en un anillo superconductor.png|thumb|200px|Cuantización del flujo magnético en un anillo superconductor.<ref>{{cita publicación| autor= MG Castellano y otros | título= Tracing the characteristics of a flux qubit with a hysteretic dc-superconducting quantum interference device comparator | revista= Journal of Applied Physics | volumen= 94 | páginas= 7935 | fecha= 2003 | doi= 10.1063/1.1628382}}</ref>]] Como ya predijo {{w|Fritz London}} en 1948, es posible observar la [[w:cuantificación del flujo magnético|cuantización del flujo magnético]] en sustancias [[w:superconductividad|superconductoras]]. El ''{{w|cuanto}} de flujo magnético'' es una constante física: :<math>\Phi_0 = \frac{h}{2e} = 2.067 833 636 \cdot 10^{-15} \, Wb \,\!</math>. El inverso del cuanto de flujo magnético K<sub>J</sub> = 1/Φ<sub>0</sub> se suele conocer como ''constante de Josephson'', por {{w|Brian David Josephson}}. Empleando el {{w|efecto Josephson}} es posible medir con mucha precisión el cuanto de flujo magnético, lo cual se ha empleado junto con el {{w|efecto Hall cuántico}} para medir la {{w|constante de Planck}} con la máxima precisión hasta la fecha. Es bastante irónico el hecho de que la constante de Planck suela estar asociada a sistemas microscópicos, pero su valor se calcule a partir de dos fenómenos macroscópicos como el efecto Josephson y el efecto Hall cuántico.<ref>{{cita publicación | autor= Petley, BW, Kibble, BP y Hartland, A | título= A measurement of the Planck constant | fecha= 18 de junio de 1987 | revista= [[Nature]] | volumen= 327 | páginas= 605 - 606 | doi = 10.1038/327605a0 | url = http://www.nature.com/nature/journal/v327/n6123/abs/327605a0.html}}</ref><ref>{{cita publicación| autor= Williams, ER y otros | título= Accurate Measurement of the Planck Constant | revista= Physical Review Letters | volumen= 81 | páginas= 2404 - 2407 | fecha= 21 de septiembre de 1998 | número= 12 | url = http://link.aps.org/abstract/PRL/v81/p2404 | doi = 10.1103/PhysRevLett.81.2404}}</ref><ref>{{cita web | url = http://www.aip.org/png/html/planck.htm | título = Physics News Graphics: Measuring Planck's Constant | fechaacceso = 14 de mayo | añoacceso = 2008 | idioma = inglés|urlarchivo=http://web.archive.org/web/http://www.aip.org/png/html/planck.htm|fechaarchivo=18 de noviembre de 2015}}</ref> {{AutoCat}} ji9yj17iia9vs882btrzyfald6sjc8w Física/Electromagnetismo/Campo Magnético/Generalidades 0 54931 427972 323285 2026-07-16T06:13:40Z Mazbel 57931 categorización 427972 wikitext text/x-wiki - Los campos magnéticos no son centrales (como la gravedad) - No existen monopolos magnéticos (siempre hay como mínimo un dipolo) Líneas de campo para un dipolo (los polos Norte y Sur separados por una distancia) La fuerza es tangencial a las líneas de campo, la intensidad de la fuerza es proporcional a la densidad de líneas. Cualquier campo magnético requiere del movimiento de una carga eléctrica Un circuito de corriente en forma de anillo es equivalente a un dipolo. El campo magnético H a lo largo del eje de un solenoide con n vueltas por el que circula una corriente I es H =nI En imanes permanentes el campo es debido al movimiento de electrones en los átomos constituyentes. En coordinadas esféricas el campo debido a un dipolo de momento m es: Hr = 2m cosq /4p 3 H q= m sin q/4 p3 B es la intensidad del campo debido a corrientes aisladas (en espacio libre). Tambén se le llama Inducción magnética o Densidad de flujo magnético. Una definición apropiada es la siguiente: Una corriente eléctrica induce una fuerza sobre una carga en movimiento, la fuerza es el producto vectorial de la inducción magnética y la velocidad de la carga (la fuerza de Lorentz). Unidades de B? tesla (T) = weber*m2=(Newton/Coulomb)/(m/s) = N/(Am) [SI] gauss (G) = 10-4 T [cgs] Unidades de H? oersted (Oe) [cgs] A/m = 4 p * 10-3 oersted [SI] El Uso del Sistema Internacional (SI) de unidades crea cierta confusión en la conversión de unidades, que generalmente resulta por una terminología inadecuada. Existe cuatro unidades fundamentales, el campo magnético H , la inducción magnética B, la magnetización J (más correctamente llamada polarización magnética), y el momento magnético por unidad de volumen M. Campo magnético terrestre ~ 0.3-0.6 gauss En Geofísica se usa nanotesla nT (10-9 T) = gamma g (10-5 G) En el sistema cgs B=H+4 pM . En SI B=µoH + M , donde µo es la permeabilidad en el espacio libre, con un valor de 4 p * 10 -7 henry/m. El Momento de un dipolo (m) se puede definir en función de la corriente que circula por un lazo: 'Momentos Magnéticos' son producidos por: 1) órbitas electrónicas y 2) rotación de los electrones. Para electrones apareados los momentos magnéticos se cancelan è La mayoría de los materiales tienen pequeños momentos magnéticos en presencia de un campo magnético. En algunos materiales la cancelación es incompleta è el momento magnético es permanente aun en ausencia de un campo. La magnetización de un volumen V está definida como la suma vectorial de los momentos dipolares dividad por el volumen: M = 1/V * S mi Otra razón para confusión de unidades: En cgs J=M=k*H En SI J =µoM Es decir, en cgs los cuatro términos tienen las mismas unidades; en SI B y J se expresan en tesla mientras que H y M se expresan en A/m. http://www.geociencias.unam.mx/~rmolina/Paleomagnetismo-html/magnetismo.html {{AutoCat}} gqrkpojk31ir5cma2any9ai7u9m5ljk Introducción a la Programación Usando Java 0 56563 427850 425907 2026-07-15T12:09:12Z Antimundo 74354 Borrar 427850 wikitext text/x-wiki {{Borrar|[[WL:BR#L1]] no pertenece a Wikilibros, como mucho podría trasladarse a Wikisource, pero realmente hay tan poquísimo contenido traducido, que no merecería la pena el gran esfuerzo que esto supondria.}} == Introducción == BIENVENIDO a la Séptima Edición de ''Introducción a la Programación Usando Java'', un libro de texto en línea gratuito sobre programación introductoria, que usa Java como el lenguaje de instrucción. Este libro está dirigido principalmente a los programadores principiantes, aunque también puede ser útil para programadores experimentados que quieran aprender algo sobre Java. Ciertamente, no está destinado a proporcionar una cobertura completa del lenguaje Java. La séptima edición requiere Java 7, con solo un par de breves menciones de Java 8. Las versiones anteriores incluían applets de Java en las páginas web que componen este libro, pero los applets han sido eliminados de esta versión. Las ediciones anteriores del libro todavía están disponibles; ve el [[/prefacio/]] para los enlaces. Puedes descargar este sitio web para usarlo en tu propia computadora. Las versiones en PDF, e-book e impresas del libro de texto también están disponibles. El PDF que incluye enlaces puede ser la mejor manera de leerlo en tu computadora. '''Los enlaces a las descargas se pueden encontrar en la parte inferior de esta página'''. '''Se recomienda encarecidamente a los lectores que prueben los [[/Código Fuente/|programas de muestra]] mientras leen el libro. Puede descargar el código fuente por separado o como parte del sitio web usando los enlaces a continuación. Consulta la página [[/Compilación/]] para obtener información sobre cómo compilar y ejecutar los ejemplos'''. == Tabla de Contenido Breve == * '''[[/Tabla de Contenido Completa/]]''' * [[/Prefacio/]] * Capítulo 1: '''[[/El Paisaje Mental/|Descripción General: El Paisaje Mental]]''' * Capítulo 2: '''[[/Nombres y Cosas/|Programando a lo Pequeño I: Nombres y Cosas]]''' * Capítulo 3: '''[[/Control/|Programando a lo Pequeño II: Control]]''' * Capítulo 4: '''[[/Subrutinas/|Programando a lo Grande I: Subrutinas]]''' * Capítulo 5: '''[[/Objetos y Clases/|Programando a lo Grande II: Objetos y Clases]]''' * Capítulo 6: '''[[/Introducción a la Programación de GUI/]]''' * Capítulo 7: '''[[/Arrays y ArrayLists/]]''' * Capítulo 8: '''[[/Corrección, Robustez, Eficiencia/]]''' * Capítulo 9: '''[[/Estructuras de Datos Vinculados y Recursión/]]''' * Capítulo 10: '''[[/Programación Genérica y Clases de Colección/]]''' * Capítulo 11: '''[[/Entrada/Salida Avanzada: Transmisiones, Archivos y Redes/]]''' * Capítulo 12: '''[[/Hilos y Multiprocesamiento/]]''' * Capítulo 13: '''[[/Programación Avanzada de GUI/]]''' * [[/Código Fuente/|Código Fuente para Todos los Ejemplos en este Libro]] * [[/Glosario/]] * [[/Noticias y Errata/]] == Licencia == © 1996-2016, David J. Eck.  Este trabajo está licenciado bajo una licencia ''[[creativecommons:by-nc-sa/3.0/|Creative Commons Attribution-Noncommercial-ShareAlike 3.0 License]]''. (Esta licencia le permite redistribuir este libro en forma no modificada para fines no comerciales. Le permite crear y distribuir versiones modificadas para fines no comerciales, siempre que incluya una atribución al autor original, describa claramente las modificaciones que usted ha realizado y distribuido el trabajo modificado bajo la misma licencia que el original. El autor puede otorgar el permiso para otros usos. Consulte la [[creativecommons:by-nc-sa/3.0/|licencia]] para obtener más información). La versión más reciente de este libro está siempre disponible, sin cargo, para su descarga y uso en línea en la dirección web: http://math.hws.edu/javanotes/ == Descargas y Otros Enlaces == * '''Descarga Completa del Sitio Web:''' ** http://math.hws.edu/eck/cs124/downloads/javanotes7.zip - Este archivo "zip" contiene una copia completa del sitio web. Debería ser utilizable en casi cualquier computadora. Tamaño: 4.3 Megabytes. * '''Descargas de Código Fuente:''' ** http://math.hws.edu/eck/cs124/downloads/javanotes7-example-programs.zip - Un archivo zip del directorio "fuente" del sitio web, que incluye el código fuente para los programas de muestra de este texto. Tenga en cuenta que si descarga el sitio web completo, entonces ya tiene una copia del mismo directorio de origen. Mira la página [[/Compilación/]]. Tamaño: 773 Kilobytes. ** http://math.hws.edu/eck/cs124/downloads/javanotes7-exercise-solutions.zip - Un archivo zip que contiene el código fuente de todos los ejercicios al final de cada capítulo. Estos se extrajeron de las páginas web que contienen las soluciones para su comodidad. No están incluidos en el sitio web de descarga. Mira la página [[/Compilación/]]. Tamaño: 322 Kilobytes. * '''Descargas de PDF:''' ** http://math.hws.edu/eck/cs124/downloads/javanotes7-linked.pdf - una versión en PDF con enlaces internos para navegación y enlaces externos a archivos de código fuente, soluciones de ejercicio y otros recursos que no están incluidos en el PDF. Recomendado para lectura en pantalla. Tamaño: 6.3 Megabytes; 755 páginas. ** http://math.hws.edu/eck/cs124/downloads/javanotes7.pdf - una versión en PDF sin enlaces, más adecuada para imprimir. Este PDF está en el formato que se utiliza para la versión impresa del texto, excepto que también incluye un apéndice que enumera programas de ejemplo y un glosario (ya que habrían excedido el límite de la página de lulu.com). Tamaño: 5.9 Megabytes; 762 páginas. * '''Descargas de E-book:''' ** http://math.hws.edu/eck/cs124/downloads/javanotes7.mobi , para Kindle. ** http://math.hws.edu/eck/cs124/downloads/javanotes7.epub , para la mayoría de los otros lectores de libros electrónicos.        Estos deben ser considerados experimentales. Dependiendo del lector de libros electrónicos particular que utilices, puede haber problemas con la representación de líneas largas en la muestra del código del programa. Puede encontrar que las líneas que son demasiado largas para caber en su pantalla, se dividen incorrectamente en varias líneas, o que la parte que se extiende más allá del margen derecho simplemente se descarta. En algunos lectores, es posible que pueda desplazarse horizontalmente para ver el texto oculto. Los libros electrónicos incluyen respuestas a exámenes y ejercicios, pero no incluyen el código fuente para programas de muestra; los programas de muestra se pueden descargar por separado, arriba. * '''Imprimir Copias Disponibles desde Lulu.com:''' ** '''Versiones impresas''' — he hecho que este libro esté disponible para su compra en versiones impresas del editor de impresión a pedido [https://www.lulu.com/ lulu.com] . Esto es solo por conveniencia, para aquellos que deseen tener una copia impresa en una buena forma. (¡No se sienta obligado a comprar la versión impresa, no gano dinero con ella!) El libro completo está disponible en una versión impresa bastante gruesa en http://www.lulu.com/content/612392 . También está disponible en dos partes como http://www.lulu.com/content/559884 y http://www.lulu.com/content/822314. Tenga en cuenta que estos libros impresos son la Versión 7 original y aún contienen errores que se han corregido en la Versión 7.0.2. Consulte la página de noticias en línea para obtener una lista de errores sustantivos. * '''Archivos Fuente para el Libro:''' ** '''Fuentes completas''' — los archivos fuente completos que se utilizan para producir tanto el sitio web como las versiones en PDF de este libro están disponibles para su descarga, pero serán útiles solo para un público muy limitado. Consulta el final del prefacio para obtener más información y un enlace. [[Categoría:Introducción a la Programación Usando Java]] [[Categoría:Programación]] {{Libro}} bf5eeaw6u1d2gg2pe3qc0rgu5koqkcf Haskell/Historia de Haskell 0 61799 427912 427835 2026-07-16T03:56:24Z Mazbel 57931 actualización 427912 wikitext text/x-wiki La primera versión de Haskell ("'''Haskell 1.0'''") se definió en 1990, donde se realizaron una serie de definiciones del lenguaje, que posteriormente culminaría, a finales de 1997, en el estándar conocido como Haskell 98. Dicho estándar se intentó que fuera una versión del lenguaje mínima, estable y portable, junto con una biblioteca estándar asociada para la enseñanza. Luego posteriormente se fueron agregando extensiones al lenguaje y modificaciones aprobadas por el comité que definió Haskell 98, creándose así las distintas implementaciones que se conocen actualmente del lenguaje (Como por ejemplo GHC y Hugs). En enero de 2003, se publicó una versión revisada en "Haskell 98 Language and Libraries: The Revised Report". A principios del 2006 se empezó a definir un sucesor del estándar de Haskell 98, llamado Haskell′ ("Haskell Prime"). Luego en 2010 se lanza Haskell 2010, con varios cambios respecto a Haskell 98. Entre ellos: * Bloque '''Do''' y '''if then else'''. * Herencia. * Comentarios en el código. * Interfaz de función foranea. * Análisis de dependencias. * Se remueve el patrón '''n+k'''. {{AutoCat}} 0weadd9pqd8dlxqwzz1s1kyvkh8la1a Haskell/Implementaciones de Haskell 0 61802 427913 427836 2026-07-16T03:56:41Z Mazbel 57931 427913 wikitext text/x-wiki '''Implementaciones del lenguaje:''' Existen varias implementaciones del lenguaje disponible para múltiples sistemas operativos (Entre ellos Windows, Mac os y varias distribuciones de Linux). Todos son bajo licencia open source y cumplen con los estándares de Haskell 98. * Glasgow Haskell Compiler: Es un compilador nativo de código libre originalmente desarrollado en la Universidad de Glasgow, en un principio por Simon Peyton Jones y Simon Marlow. El compilador también está escrito en Haskell pero el núcleo de sistema para Haskell está escrito en C y C--. La última versión del compilador cumple con Haskell 98 * Hugs (Haskell User's Gofer System): Es un intérprete bytecode para el lenguaje funcional Haskell de código abierto. Ofrece compilación rápida y una velocidad de ejecución aceptable. Es la más portable y ligera de todas las implementaciones de Haskell en la actualidad. * NHC98 : Es un compilador que cumple con la característica de tener menor tiempo de ejecución que GHC y Hugs, ya que ocupa mucho menos memoria del sistema. Se desarrolló con el fin de instalarse en máquinas antiguas con poco poder de procesamiento y disposición de memoria RAM. * Helium: Es un nuevo dialecto de Haskell. Se centró en ser muy fácil de aprender; por ello, no incluye soporte para todo el estándar de Haskell, haciendo que no sea totalmente compatible. IDEs Existen varios IDEs y/o plugins que se pueden utilizar para desarrollar aplicaciones en Haskell. La mayoria son open source, pero también existen de índole comercial. Open Source * IntelliJ plugin for Haskell * EclipseFP plugin for Eclipse IDE * Colorer plugin for Eclipse IDE * Leksah * KDevelop * Vim * Emacs * Atom Commercial * Haskell for Mac * Sublime-Haskell {{AutoCat}} a50tym0b8e9qjqir792j3w9eprgzgui Haskell/Preparaciones 0 61814 427914 427837 2026-07-16T03:56:51Z Mazbel 57931 actualización 427914 wikitext text/x-wiki == Instalando Haskell == Haskell es un ''lenguaje de programación'', es decir, un lenguaje en el que las personas pueden expresar cómo deben comportarse las computadoras. Es como escribir una receta de cocina: se escribe la receta y la computadora la ejecuta. Para usar los programas Haskell, este necesita un programa especial llamado ''compilador'' de Haskell. Dicho compilador toma el código escrito en Haskell y lo traduce a ''código de máquina'', un lenguaje más elemental que la computadora entiende. Usando la analogía de la cocina, usted escribe una receta (su programa Haskell) y un cocinero (un programa compilador) hace el trabajo de juntar los ingredientes reales en un plato comestible (un archivo ejecutable). Por supuesto, no puede obtener fácilmente la receta de un plato final (y no puede obtener el código Haskell del ejecutable después de compilarlo). Para comenzar, visite [https://www.haskell.org/downloads haskell.org/downloads] para obtener las instrucciones más recientes. La forma recomendada actual es usar [https://haskell.org/ghcup GHCup]. Úselo para instalar la última versión recomendada de GHC <code>cabal</code> (not <code>stack</code>) y el servidor de idioma Haskell. Debe usar <code>cabal</code> para instalar cualquier biblioteca de Haskell que necesite. Cubriremos el uso de <code>cabal</code> en profundidad en [[Haskell/Packaging]] {{Nota de cuerpo|1= Usuarios de Linux: '''Se desaconseja encarecidamente instalar cualquier cosa relacionada con Haskell usando los repositorios de paquetes y el administrador de paquetes de su sistema (a menos que esté usando Fedora o NixOS). Específicamente, las distribuciones como Arch Linux y Debian administran muy mal los paquetes de Haskell y darán lugar a una mala experiencia con las herramientas. Use GHCup y Cabal como se indicó anteriormente.''' }} Para probar algunos conceptos básicos de Haskell sin descargar e instalar, hay un [https://play.haskell.org/ área] de ejecución que incluye algunos paquetes de forma predeterminada. La mayoría de las instrucciones aquí en Wikibook también funcionarán en el patio de recreo, aunque no acepta la entrada del usuario. == Primer código == Después de la instalación, se hará nuestra primera codificación Haskell con el programa llamado '''GHCi''' (la 'i' significa 'interactivo'). Dependiendo de su sistema operativo, realice los siguientes pasos: * En Windows: haga clic en Inicio, luego en Ejecutar, luego escriba 'cmd' y presione Enter, luego escriba <code>ghci</code> presione Enter una vez más. * En MacOS: Abra la aplicación "Terminal" que se encuentra en la carpeta "Aplicaciones/Utilidades", escriba las letras <code>ghci</code> en la ventana que aparece y presione la tecla Intro. * En Linux: abra una terminal y ejecute <code>ghci</code>. Debería obtener una salida similar a la siguiente: <pre> GHCi, version 8.10.7: http://www.haskell.org/ghc/ :? for help Prelude> </pre> El primer bit es la versión de GHCi y le indica cómo obtener ayuda en GHCi. El bit <code>Prelude></code> se conoce como aviso. Aquí es donde ingresa los comandos y GHCi responderá con sus resultados. El indicador también le indica que el módulo cargado actualmente es <code>Prelude</code>, lo que le da acceso a la mayoría de las funciones integradas. Ahora intentemos algo de aritmética básica: {{GHCi de Haskell|1= Prelude> 2 + 2 4 Prelude> 5 + 4 * 3 17 Prelude> 2 ^ 5 32 }} Estos operadores coinciden con la mayoría de los otros lenguajes de programación: <code>+</code> es suma, <code>*</code> es multiplicación y <code>^</code> es exponenciación (elevar a la potencia de, <math>a ^ b</math>). Como se muestra en el segundo ejemplo, Haskell sigue el orden estándar de las operaciones matemáticas (por ejemplo, la multiplicación antes que la suma). Haskell también puede calcular el resto de una división. En Haskell el operador para resto es <code>mod</code> Este operador se coloca antes de los dos operandos. Por ejemplo, se requiere conocer el resto de dividir 45 entre 6. Entonces hacemos: {{GHCi de Haskell|1= Prelude> mod 45 6 3 }} Una forma alternativa es colocar el operador mod entre medio de los operados. En este caso, este operador debe ir entre tilde izquierdo o grave <code>`</code>. {{GHCi de Haskell|1= Prelude> 42 `mod` 5 2 }} Puede ocurrir también que necesitemos saber el resto de la división entera de dos números. Para ello se utiliza el operador <code>div</code>. Al igual que ocurre con el operador anterior, este va siempre antes de los dos operandos. Siguiendo la misma idea que el operador anteriormente visto, si se desea usar entre medio de los operadores debe ir entre tildes izquierdo o grave. {{GHCi de Haskell|1= Prelude> div 35 10 3 Prelude> 54 `div` 3 18 }} Tabla que resume las operaciones aritméticas básicas de Haskell: {| border="1" cellpadding="5" cellspacing="0" align="center" |+'''Operaciones básicas de Haskell''' |- ! style="background:#efefef; | Operador ! style="background:#efefef; | Símbolo en Haskell |- | Adición | <code>+</code> |- | Sustracción | <code>-</code> |- | Multiplicación | <code>*</code> |- | División | <code>/</code> |- | División entera | <code>div</code> |- | Exponenciación | <code>^</code> |- | Resto | <code>mod</code> |- |} Ahora ya se explicó cómo usar Haskell como calculadora. En realidad, Haskell ''siempre'' es una calculadora, solo que realmente potente, capaz de manejar no solo números sino también otros objetos como caracteres, listas, funciones, árboles e incluso otros programas (si aún no está familiarizado con estos términos, no debe generar preocupación). Una vez que haya terminado, para salir de GHCi use <code>:quit</code> (o simplemente <code>:q</code>): {{GHCi de Haskell| Prelude> :quit Leaving GHCi. }} GHCi es un potente entorno de desarrollo. A medida que se avance con el curso, se aprenderá cómo cargar archivos con código fuente en GHCi y evaluar diferentes partes de ellos. Asumiendo que se aprendieron los conceptos (si no es así, ¡use la página de discusión y ayúdenos a mejorar este Wikilibro!), entonces está listo para el próximo capítulo donde presentaremos algunos de los conceptos básicos de Haskell y haremos nuestras primeras funciones de Haskell. {{AutoCat}} h8bs7r1upbiy9ocd37n5g7vo7exkicm Godot 0 61902 427877 412925 2026-07-15T18:39:49Z Antimundo 74354 Categorizar con estantes 427877 wikitext text/x-wiki {{Wikipedia|Godot}} __NOTOC__ {{+Portada/e |nombre = Godot |título = Curso de Godot {{Última versión estable de Godot|release}} |subtítulo = Curso de creación de videojuegos con el motor libre Godot, versión {{Última versión estable de Godot|major}} |encabezado = |imagen = Godot logo.svg |sección1 = Introducción |sección2 = Instalación |sección3 = Editor |sección4 = Tu primer juego |sección5 = Nodos, escenas y recursos |sección6 = GDScript |sección7 = 2D |sección8 = 3D |sección9 = Interfaz |sección10 = |sección11 = |sección12 = |sección13 = |sección14 = |sección15 = |sección16 = |sección17 = |sección18 = |sección19 = |sección20 = |sección21 = |sección22 = |sección23 = |sección24 = |sección25 = |sección26 = |sección27 = |sección28 = |sección29 = |sección30 = |rutacarrusel = |titcarrusel = |textoedición = |ancho = |alineartit = |imagenlink = |imagenedit = |tono = |tonosección = |tonocarrusel = |tonoedición = |tonoenlaces = |redondeo = }} {{Estantes|Desarrollo de videojuegos}} [[Categoría: Programación]] iqmxzsoovp1z0u8qyjrwqkfeytcbka8 Física/Preliminares/Introducción 0 61976 427952 413283 2026-07-16T05:49:46Z Mazbel 57931 actualización 427952 wikitext text/x-wiki == Definición == También llamada '''filosofía de la naturaleza''', pues proviene de la palabra latina ''physica'', que significa ''naturaleza'', la '''física''' se encarga del estudio riguroso de los ''fenómenos físicos'' que ocurren en la naturaleza, como son el movimiento de los cuerpos, los intercambios de temperatura entre distintos objetos, la electricidad, la luz, el tiempo... Para ello, se ayuda de las '''matemáticas''', ya que necesita que de su precisión para describir exactamente las ''leyes naturales'' o ''leyes físicas'' que gobiernan la naturaleza. [[File:Newtonbig.gif|thumb|200px|Imagen humorística de Isaac Newton]] La física es la ciencia que estudia la Naturaleza en su sentido más amplio. La física es la ciencia básica que estudia el cosmos, es decir, el todo desde el punto de vista científico. Aunque, aparentemente, la física consiste en buscar o encontrar una matematización de la realidad observable, no es así. Lo que ocurre es que la matemática es el idioma en que se puede expresar con mayor precisión lo que se dice en física. Desde un punto de vista aplicado, el campo de la física es mucho más amplio, ya que se utiliza, por ejemplo, en la explicación de la aparición de propiedades emergentes, más típicos de otras ciencias como Sociología y Biología. Esto hace que la física y sus métodos se pueda aplicar y utilizar en otros campos de la ciencia y se utilicen para cualquier tipo de investigación científica. La física es una de las Ciencias Naturales que más ha contribuido al desarrollo y bienestar del hombre porque gracias a su estudio e investigación ha sido posible encontrar explicación a los diferentes fenómenos de la naturaleza, que se presentan cotidianamente en nuestra vida diaria. Como por ejemplo, algo tan común para algunas personas como puede ser la lluvia, entre muchos otros. == La física y otras ciencias == La física estudia aspectos de muchas otras ciencias como la biología, geología y principalmente la química. A menudo se dice que la física es el fundamento de todas las demás ciencias, pues estas o bien clasifican en categorías los distintos aspectos que estudian (como es el caso de la botánica, que clasifica las plantas por sus características), o bien investigan acerca de los orígines de por qué ocurren las cosas, lo cual en el fondo resulta en razones físicas o químicas, y las razones químicas son explicadas por las leyes de la física. Por otro lado, la matemática es una herramienta para la física, '''"sin matemática no hay física"'''. Sin embargo, la matemática no es una ciencia de la naturaleza, ya que estudia ''entes idealizados'' solo concebibles en la mente, pero que no tienen por qué ser aplicables a la realidad. {{AutoCat}} p5xd2wbpby9l4zen689wb4u5zqbi22m Física/Magnetismo 0 61990 427965 413373 2026-07-16T05:59:51Z Mazbel 57931 categorización 427965 wikitext text/x-wiki {{+Capítulo |libro =Física |capítulo =Magnetismo |tema1 = Introducción |tema2 = Definiciones |tema3 = |tema4 = |tema5 = |tema6 = |tema7 = |tema8 = |tema9 = |tema10 = |tema11 = |tema12 = |tema13 = |tema14 = |tema15 = |tema16 = |tema17 = |tema18 = |tema19 = |tema20 = |tema21 = |tema22 = |tema23 = |tema24 = |tema25 = |tema26 = |tema27 = |tema28 = |tema29 = |tema30 = }} *[[Física/Electromagnetismo/Magnetismo|Magnetismo]] *[[Física/Electromagnetismo/Flujo Magnético|Flujo Magnético]] *[[Física/Electromagnetismo/Campo Magnético|Campo Magnético]] *[[Física/Electromagnetismo/Campo Magnético/Generalidades|Generalidades Campo Magnético]] *[[Física/Electromagnetismo/Imanes naturales|Imanes naturales]] <noinclude>{{Renglóndoble|[[Física/Magnetismo/Texto completo|'''Texto completo de este capítulo''']]|Esta página contiene todo el texto del capítulo de '''«Magnetismo»'''}} {{Física}}</noinclude> {{AutoCat}} 6wf0aofq17oxz9ymhfuc8cr3kih361q 427969 427965 2026-07-16T06:04:59Z Mazbel 57931 427969 wikitext text/x-wiki {{+Capítulo |libro =Física |capítulo =Magnetismo |tema1 = Introducción |tema2 = Definiciones |tema3 = |tema4 = |tema5 = |tema6 = |tema7 = |tema8 = |tema9 = |tema10 = |tema11 = |tema12 = |tema13 = |tema14 = |tema15 = |tema16 = |tema17 = |tema18 = |tema19 = |tema20 = |tema21 = |tema22 = |tema23 = |tema24 = |tema25 = |tema26 = |tema27 = |tema28 = |tema29 = |tema30 = }} *[[Física/Electromagnetismo/Magnetismo|Magnetismo]] *[[Física/Electromagnetismo/Flujo Magnético|Flujo Magnético]] *[[Física/Electromagnetismo/Campo Magnético|Campo Magnético]] *[[Física/Electromagnetismo/Campo Magnético/Generalidades|Generalidades Campo Magnético]] *[[Física/Electromagnetismo/Imanes naturales|Imanes naturales]] <noinclude>{{Renglóndoble|[[Física/Magnetismo/Texto completo|'''Texto completo de este capítulo''']]|Esta página contiene todo el texto del capítulo de '''«Magnetismo»'''}} {{Física}}</noinclude> 859xy4kndz4y8bgmlz89d8nx7lherod Física/Magnetismo/Introducción 0 63871 427966 424726 2026-07-16T06:03:37Z Mazbel 57931 categorización 427966 wikitext text/x-wiki El '''magnetismo''' es un fenómeno natural cuyas consecuencias casi se confundirían con la magia: por ejemplo, que dos objetos se atraigan entre sí, sin que nadie los toque. Por suerte, ha sido estudiado desde la antigüedad y ahora que conocemos ampliamente su funcionamiento, sabemos que dista mucho de ser un proceso mágico, en cambio, es algo meramente físico. Además, hemos aprendido a manipular y usar el magnetismo para nuestros intereses propios, y hoy en día casi no hay componente electrónico en nuestras vidas que no use magnetismo. Para que suceda un fenómeno magnético, necesitamos de la presencia de campos magnéticos. No los veríamos, pero los deduciríamos debido a su influencia sobre ciertos objetos. Los campos magnéticos ocupan el espacio alrededor de un imán, haciéndose más débiles a medida que aumenta la distancia al imán. Los imanes típicos que encontraríamos en la naturaleza son, por ejemplo, piedras llamadas magnetitas, de fórmula química Fe3O4; lo que les da las propiedades magnéticas es la presencia de átomos de hierro (Fe) y de algunos otros aspectos particulares en su estructura química. Los campos magnéticos se caracterizan por sus líneas de campo, que indican su magnitud y dirección: mientras más líneas, más fuerte es el campo. Las líneas siempre se dirigen desde el polo norte al polo sur de un imán. Un imán siempre posee dos polos, aunque intentemos dividir un imán por la mitad, cada uno de los trozos más pequeños nuevamente formarán dos polos. Es por esto que decimos que no existen las cargas magnéticas o los monopolos magnéticos, a diferencia de las cargas eléctricas en donde podemos aislar por separado partículas con carga positiva o negativa. Las líneas de campo magnético se manifiestan físicamente mediante un sencillo experimento. En la siguiente imagen, se ha colocado una barra imantada debajo de una hoja de papel, y por encima de la hoja de papel, se han dispersado pequeñas virutas o limaduras de hierro metálico. Estas partículas son atraídas por el campo magnético del imán y se orientan según la dirección de éste, mostrándonos exactamente la forma de las líneas de campo. Estas líneas de campo son las que participarán en las interacciones magnéticas. Una interacción que vivimos en la vida diaria es la atracción entre imanes: si alguna vez jugaste con ellos, seguro notaste que a veces los imanes se unen entre sí, mientras que otras veces, por más que hagas fuerza, no los acercarías. Esto se debe a que los polos opuestos, es decir, norte-sur, se atraen, al mismo tiempo, los polos iguales, norte-norte o sur-sur, se repelen. Este efecto se vería esquemáticamente analizando las líneas de campo de los imanes: En el primer ejemplo, los polos diferentes se atraen, en el segundo y tercer ejemplo, los polos iguales se repelen. Apreciaríamos realizando nuevamente el experimento de las virutas de hierro. En este caso, debajo de la hoja de papel se colocaron dos imanes: en la primera imagen, los polos iguales están alineados, aquí se ve claramente que no se forman líneas de campo al medio; y en la segunda imagen, los polos opuestos están alineados, en este caso, se aprecian claramente las líneas en el espacio entre ambos imanes. Para comprender qué materiales formarían imanes, veremos debidamente el comportamiento de los electrones de los átomos que los componen. Los electrones poseen una cualidad llamada spin, que surge desde la descripción de su comportamiento a través de la Mecánica Cuántica, una de las áreas más modernas de la física, por lo que resulta difícil encontrar un análogo en la vida cotidiana. El nombre spin proviene del inglés girar, ya que originalmente se interpretó que era como si los electrones estuviesen “girando” sobre su eje, en uno u otro sentido. Al hacer este movimiento de giro, los electrones se comportan como si fueran pequeños imanes cuyos polos norte y sur dependen del spin (el sentido en el cual “giran”). Si en un átomo dos electrones están apareados, es decir, ubicados de a pares en un dado nivel de energía, cada uno tendrá un spin opuesto al otro, y por lo tanto los campos magnéticos de cada uno se anulan entre sí. En átomos con muchos electrones, como es el caso de los llamados “metales pesados”, pueden existir electrones que no están apareados, es decir, que están solos ubicados en su nivel de energía, y se los denomina electrones desapareados. En algunos materiales, los spin de todos los electrones desapareados se orientarían en la misma dirección, y de este modo, los campos magnéticos de cada electrón desapareado se suman, generando un campo magnético más grande. Es así como este material potencialmente mostrará las propiedades magnéticas que observamos en el día a día. Un imán permanente es aquel en el cual los spin de sus electrones desapareados quedan fijos en una dirección, como es el caso de los átomos de hierro en el mineral ferrita, que mencionamos anteriormente; y un imán temporario es aquel en el que se induciría artificialmente una orientación definida de los spin de sus electrones desapareados para generar un campo magnético resultante, pero luego los spin volverán a cambiar a su valor inicial, desapareciendo entonces el campo magnético resultante que se había producido. Hasta ahora vimos un efecto típico de campos magnéticos producidos por imanes. Sin embargo, los campos magnéticos también se generan por la presencia de cargas eléctricas en movimiento, es decir, por una corriente eléctrica, siendo éste el principio del funcionamiento de un motor eléctrico. De la misma forma, un campo magnético que varía en el tiempo produce corrientes eléctricas, y éste es el principio del funcionamiento de un generador eléctrico. Debido a que el campo eléctrico y el campo magnético están interrelacionados, surge el concepto de electromagnetismo. El desarrollo del electromagnetismo se dio en primer lugar de forma empírica y experimental, principalmente de la mano de Michael Faraday, en las primeras décadas del siglo XIX, para luego formalizarse matemáticamente por James Maxwell, que escribió la primera versión de un conjunto de leyes, que luego pasarían a llamarse las Leyes de Maxwell del electromagnetismo, en 1865. {{AutoCat}} 53v9bkwoyb3r7c5v70w25mh4q4qma4e Wikilibros:Café/Archivo/2026 4 63880 427888 426493 2026-07-16T01:47:28Z Mazbel 57931 /* Petición para renombrar los «Proyectos» a «Wikiproyectos» */ archive from [[Wikilibros:Café]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]]) 427888 wikitext text/x-wiki {{Archivo}} == Thank You for Last Year – Join Wiki Loves Ramadan 2026 == Dear Wikimedia communities, We hope you are doing well, and we wish you a happy New Year. ''Last year, we captured light. This year, we’ll capture legacy.'' In 2025, communities around the world shared the glow of Ramadan nights and the warmth of collective iftars. In 2026, ''Wiki Loves Ramadan'' is expanding, bringing more stories, more cultures, and deeper global connections across Wikimedia projects. We invite you to explore the ''Wiki Loves Ramadan 2026'' [[m:Special:MyLanguage/Wiki Loves Ramadan 2026|Meta page]] to learn how you can participate and [[m:Special:MyLanguage/Wiki Loves Ramadan 2026/Participating communities|sign up]] your community. 📷 ''Photo campaign on '' [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan 2026|Wikimedia Commons]] If you have questions about the project, please refer to the FAQs: * [[m:Special:MyLanguage/Wiki Loves Ramadan/FAQ/|Meta-Wiki]] * [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan/FAQ|Wikimedia Commons]] ''Early registration for updates is now open via the '''[[m:Special:RegisterForEvent/2710|Event page]]''''' ''Stay connected and receive updates:'' * [https://t.me/WikiLovesRamadan Telegram channel] * [https://lists.wikimedia.org/postorius/lists/wikilovesramadan.lists.wikimedia.org/ Mailing list] We look forward to collaborating with you and your community. '''The Wiki Loves Ramadan 2026 Organizing Team''' 19:45 16 ene 2026 (UTC) <!-- Mensaje enviado por Usuario:ZI Jony@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29879549 --> == Revisión anual del Código Universal de Conducta y las Directrices de Aplicación == <section begin="announcement-content" /> <div lang="en" dir="ltr" class="mw-content-ltr"> I am writing to you to let you know the annual review period for the Universal Code of Conduct and Enforcement Guidelines is open now. You can make suggestions for changes through 9 February 2026. This is the first step of several to be taken for the annual review. [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2026|Read more information and find a conversation to join on the UCoC page on Meta]]. </div> <div lang="en" dir="ltr" class="mw-content-ltr"> The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|you may review the U4C Charter]]. </div> Por favor, comparte esta información con otros miembros de tu comunidad en cualquier otro lugar que sea apropiado. <div lang="en" dir="ltr" class="mw-content-ltr"> -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) </div><section end="announcement-content" /> 21:01 19 ene 2026 (UTC) <!-- Mensaje enviado por Usuario:Keegan (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29905753 --> == <span lang="en" dir="ltr">Upcoming deployment of CampaignEvents extension to Wikibooks</span> == <div lang="en" dir="ltr"> <section begin="message"/> Hello everyone, We are writing to inform you that the [[mw:Help:Extension:CampaignEvents|CampaignEvents extension]] will be deployed to all Wikibooks projects during the week of '''23 March 2026'''. This follows last year’s broader rollout across Wikimedia projects. We realized that Wikibooks was not included at the time, and we’re now addressing that to ensure consistency across all communities. The CampaignEvents extension provides tools to support event and campaign organization on-wiki, including features like on-wiki event registration and collaboration lists(global event list). We welcome any questions, feedback, or concerns you may have. We are also happy to support anyone interested in trying out the tools. ''Apologies if this message is not in your preferred language. If you’re able to help translate it for your community, please feel free to do so.'' <section end="message"/> </div> <bdi lang="en" dir="ltr">[[User:Udehb-WMF|Udehb-WMF]] ([[User talk:Udehb-WMF|discusión]]) 18:22 19 mar 2026 (UTC)</bdi> <!-- Mensaje enviado por Usuario:Udehb-WMF@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=User:Udehb-WMF/sandbox/MM_target&oldid=30284073 --> == Action Required: Update templates/modules for electoral maps (Migrating from P1846 to P14226) == Hello everyone, This is a notice regarding an ongoing data migration on Wikidata that may affect your election-related templates and Lua modules (such as <code>Module:Itemgroup/list</code>). '''The Change:'''<br /> Currently, many templates pull electoral maps from Wikidata using the property [[:d:Property:P1846|P1846]], combined with the qualifier [[:d:Property:P180|P180]]: [[:d:Q19571328|Q19571328]]. We are migrating this data (across roughly 4,000 items) to a newly created, dedicated property: '''[[:d:Property:P14226|P14226]]'''. '''What You Need To Do:'''<br /> To ensure your templates and infoboxes do not break or lose their maps, please update your local code to fetch data from [[:d:Property:P14226|P14226]] instead of the old [[:d:Property:P1846|P1846]] + [[:d:Property:P180|P180]] structure. A [[m:Wikidata/Property Migration: P1846 to P14226/List|list of pages]] was generated using Wikimedia Global Search. '''Deadline:'''<br /> We are temporarily retaining the old data on [[:d:Property:P1846|P1846]] to allow for a smooth transition. However, to complete the data cleanup on Wikidata, the old [[:d:Property:P1846|P1846]] statements will be removed after '''May 1, 2026'''. Please update your modules and templates before this date to prevent any disruption to your wiki's election articles. Let us know if you have any questions or need assistance with the query logic. Thank you for your help! [[User:ZI Jony|ZI Jony]] using [[Usuario:MediaWiki message delivery|MediaWiki message delivery]] ([[Usuario discusión:MediaWiki message delivery|discusión]]) 17:11 3 abr 2026 (UTC) <!-- Mensaje enviado por Usuario:ZI Jony@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29941252 --> == Request for comment (global AI policy) == <bdi lang="en" dir="ltr" class="mw-content-ltr"> Apologies for writing in English. {{int:Please-translate}} A [[:m:Requests for comment/Artificial intelligence policy|request for comment]] is currently being held to decide on a global AI policy. {{int:Feedback-thanks-title}} [[Usuario:MediaWiki message delivery|MediaWiki message delivery]] ([[Usuario discusión:MediaWiki message delivery|discusión]]) 00:57 26 abr 2026 (UTC) </bdi> <!-- Mensaje enviado por Usuario:Codename Noreste@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30424282 --> == Vota ahora en las elecciones del U4C de 2026 == <section begin="announcement-content" /> Se invita a las y los votantes con derecho a voto a participar en las elecciones de 2026 del [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Comité de Coordinación del Código de Conducta Universal]]. En Meta, en la [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026|página de información sobre las elecciones de 2026]], hay disponible más información, incluyendo una comprobación de elegibilidad, información sobre el proceso de votación, información sobre las y los candidatos y un enlace a la votación. La votación finaliza el 2 de junio de 2026 a las [https://zonestamp.toolforge.org/1780358400 00:00 UTC]. Por favor, vota si tu cuenta es elegible. Los resultados estarán disponibles para el 14 de junio de 2026. -- En cooperación con la U4C,<section end="announcement-content" /> [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 17:14 27 may 2026 (UTC) <!-- Mensaje enviado por Usuario:Keegan (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 --> == Actualizada una plantilla == Buenas. Quería comentar un cambio que he realizado en una plantilla de mantenimiento del sitio, con el objetivo de unificar criterios y facilitar la edición entre proyectos hermanos. En la Wikipedia en español existen desde 2007 dos plantillas con funciones bien diferenciadas: * [[w:Plantilla:Desactualizado]]: Para indicar que una página completa o sección ya contiene información obsoleta. * [[w:Plantilla:Actualizar]]: Para marcar pasajes específicos que requerirán revisión a partir de una fecha futura programada (como elecciones o eventos deportivos). Hasta ahora, en Wikilibros se venía utilizando la plantilla <nowiki>{{Actualizar}}</nowiki> con el mismo propósito que la plantilla <nowiki>{{Desactualizado}}</nowiki> en Wikipedia en español. Esto podía generar cierta confusión en los usuarios que editan en ambos proyectos (como fue mi caso al principio). Para estandarizar el flujo de trabajo entre ambos proyectos, he importado la plantilla <nowiki>{{Desactualizado}}</nowiki> a Wikilibros con su función original, he adaptado <nowiki>{{Actualizar}}</nowiki> para que cumpla su rol específico de aviso futuro al igual que se hace en la Wikipedia en español, y he actualizado las páginas pertinentes para que usen la plantilla adecuada. Así, esta plantilla se usa igual que con el resto de los proyectos hermanos, facilitando el trabajo a los editores actuales y futuros ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 12:18 9 jun 2026 (UTC) == Petición para renombrar los «Proyectos» a «Wikiproyectos» == Propongo renombrar los actuales «Proyectos» a «Wikiproyectos». Y que usen su propio espacio de nombres. Por ejemplo, en vez de «Wikilibros:Proyecto mantenimiento», pasaría a llamarse «Wikiproyecto:Mantenimiento» al igual que en otros proyectos de Wikimedia. Hasta donde he podido investigar, el nombre «Proyectos» se empezó a usar en 2008 porque así los llamó el usuario que los creó, sin una consulta o consenso previo documentado. Personalmente, considero que «Wikiproyecto» es un término mas claro y preciso. Cuando hablamos de un «Wikiproyecto» se entiende inmediatamente que nos referimos a un espacio concreto de coordinación dentro de la wiki, no a un proyecto en el sentido abstracto y general. Además, considero que sería positivo por consistencia con otros proyectos de Wikimedia. Históricamente, muchos usuarios valiosos de Wikilibros eran colaboradores de Wikipedia en español, donde se llaman «Wikiproyectos». Mantener una terminología familiar facilita la adaptación de un proyecto a otro y evita confusiones innecesarias por diferencias arbitrarias de nomenclatura. En varias ediciones de Wikilibros y Wikipedia en otros idiomas también se utiliza esta denominación: * En Wikibooks y Wikipedia en inglés se llaman «WikiProjects». * En Viquillibres y Wikipedia en catalán se llaman «Viquiprojectes». * En Wikiliburuak y Wikipedia en euskera se llaman «wikiproiektuak». * En Wikipedia en gallego se llaman «Wikiproxectos». También es cierto que no todas las ediciones de Wikilibros usan este concepto, por ejemplo, algunas como la francesa o la italiana ni si quiera tienen ninguna estructura equivalente de «Wikiproyectos». Pero muchas sí la tienen y, especialmente en proyectos como Wikipedia en Español, de donde surgen muchos colaboradores de esta wiki sí se llaman así. Hacer el traslado, además, sería muy sencillo, ya que actualmente solo existen 7 páginas en el actual «Wikilibros:Proyectos». Por eso quería plantearlo aquí primero y conocer si alguien mas está de acuerdo antes de realizar el traslado. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 07:55 23 jun 2026 (UTC) : No veo necesario realizar este cambio. : En primer lugar, creo que es importante distinguir qué es un Wikiproyecto y cuál es la realidad actual de Wikilibros. Históricamente, los Wikiproyectos surgieron en Wikipedia como espacios de coordinación de grupos de editores que comparten un interés temático o una meta editorial común. Su objetivo principal es organizar esfuerzos colectivos para desarrollar contenidos específicos, establecer estándares y coordinar trabajo entre varios participantes. : Si observamos la definición utilizada en Wikibooks en inglés, en la página "[[b:Wikibooks:WikiProject|WikiProject]]", estos espacios se describen principalmente como lugares destinados a coordinar la creación y desarrollo de libros. Es decir, se trata de iniciativas colaborativas enfocadas en la construcción de contenido, más que en la existencia de grupos reducidos dedicados a tareas administrativas o de mantenimiento. : La situación actual de Wikilibros en español es bastante distinta. Actualmente no existe una comunidad activa y numerosa que participe de manera sostenida en proyectos temáticos o grupos de trabajo especializados. Los espacios existentes funcionan más como páginas organizativas o de coordinación puntual que como verdaderos Wikiproyectos en el sentido en que se entiende el término dentro del movimiento Wikimedia. : Por ello, considero que adoptar la denominación «Wikiproyecto» podría incluso resultar confuso, ya que transmite la idea de una estructura comunitaria activa y consolidada que actualmente no existe. El nombre «Proyecto» cumple adecuadamente la función de identificar estos espacios sin atribuirles una naturaleza que, en la práctica, no poseen. : Tampoco veo una necesidad funcional que justifique crear un espacio de nombres específico. El sistema actual funciona correctamente, las páginas son pocas y su localización resulta sencilla. El cambio no resolvería ningún problema operativo ni facilitaría tareas que actualmente sean difíciles de realizar. : Respecto a la consistencia con otros proyectos Wikimedia, si bien es cierto que muchas Wikipedias utilizan el término «Wikiproyecto», también es cierto que cada proyecto ha desarrollado históricamente sus propias convenciones organizativas. La mera existencia de una denominación distinta en otros proyectos no constituye, por sí sola, una razón suficiente para modificar una estructura local que lleva años funcionando sin inconvenientes. : Finalmente, si el principal motivo es una cuestión estética o de preferencia terminológica, considero que no debería procederse al cambio. Los cambios de nomenclatura y espacios de nombres deberían responder a una necesidad práctica, organizativa o técnica claramente identificable. En este caso, no observo un beneficio concreto para los usuarios ni para el desarrollo de Wikilibros que justifique el traslado de páginas y la modificación de una convención establecida. [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 18:23 23 jun 2026 (UTC) ::Bien argumentado, me has convencido. Tienes razón en que estos «Proyectos» en Wikilibros sirven actualmente como espacio de coordinación puntual para tareas administrativas y de mantenimiento generales, y funcionan de manera distinta a cómo lo hacen los «Wikiproyectos» de otras wikis donde son espacios temáticos o grupos de trabajos especializados. ::Dicho esto, considero que si en un futuro surgiesen estos espacios y tuviesen el mismo propósito que tienen los Wikiproyectos en otras wikis como la Wikipedia en español, si me parecería que en tal caso deberían llamarse «Wikiproyectos» por lo que argumenté en mi primer mensaje. ::Pero estoy de acuerdo contigo en que, como esa no es la realidad ahora como bien has señalado, por mí queda consensuado que de momento los actuales proyectos se pueden quedar con ese nombre. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 18:55 23 jun 2026 (UTC) esx7r1mwi153aly6l1w2i7t4y5j1pt9 427890 427888 2026-07-16T01:47:41Z Mazbel 57931 /* RFC about AI-generated content in Wikimedia Commons */ archive from [[Wikilibros:Café]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]]) 427890 wikitext text/x-wiki {{Archivo}} == Thank You for Last Year – Join Wiki Loves Ramadan 2026 == Dear Wikimedia communities, We hope you are doing well, and we wish you a happy New Year. ''Last year, we captured light. This year, we’ll capture legacy.'' In 2025, communities around the world shared the glow of Ramadan nights and the warmth of collective iftars. In 2026, ''Wiki Loves Ramadan'' is expanding, bringing more stories, more cultures, and deeper global connections across Wikimedia projects. We invite you to explore the ''Wiki Loves Ramadan 2026'' [[m:Special:MyLanguage/Wiki Loves Ramadan 2026|Meta page]] to learn how you can participate and [[m:Special:MyLanguage/Wiki Loves Ramadan 2026/Participating communities|sign up]] your community. 📷 ''Photo campaign on '' [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan 2026|Wikimedia Commons]] If you have questions about the project, please refer to the FAQs: * [[m:Special:MyLanguage/Wiki Loves Ramadan/FAQ/|Meta-Wiki]] * [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan/FAQ|Wikimedia Commons]] ''Early registration for updates is now open via the '''[[m:Special:RegisterForEvent/2710|Event page]]''''' ''Stay connected and receive updates:'' * [https://t.me/WikiLovesRamadan Telegram channel] * [https://lists.wikimedia.org/postorius/lists/wikilovesramadan.lists.wikimedia.org/ Mailing list] We look forward to collaborating with you and your community. '''The Wiki Loves Ramadan 2026 Organizing Team''' 19:45 16 ene 2026 (UTC) <!-- Mensaje enviado por Usuario:ZI Jony@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29879549 --> == Revisión anual del Código Universal de Conducta y las Directrices de Aplicación == <section begin="announcement-content" /> <div lang="en" dir="ltr" class="mw-content-ltr"> I am writing to you to let you know the annual review period for the Universal Code of Conduct and Enforcement Guidelines is open now. You can make suggestions for changes through 9 February 2026. This is the first step of several to be taken for the annual review. [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2026|Read more information and find a conversation to join on the UCoC page on Meta]]. </div> <div lang="en" dir="ltr" class="mw-content-ltr"> The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|you may review the U4C Charter]]. </div> Por favor, comparte esta información con otros miembros de tu comunidad en cualquier otro lugar que sea apropiado. <div lang="en" dir="ltr" class="mw-content-ltr"> -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) </div><section end="announcement-content" /> 21:01 19 ene 2026 (UTC) <!-- Mensaje enviado por Usuario:Keegan (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29905753 --> == <span lang="en" dir="ltr">Upcoming deployment of CampaignEvents extension to Wikibooks</span> == <div lang="en" dir="ltr"> <section begin="message"/> Hello everyone, We are writing to inform you that the [[mw:Help:Extension:CampaignEvents|CampaignEvents extension]] will be deployed to all Wikibooks projects during the week of '''23 March 2026'''. This follows last year’s broader rollout across Wikimedia projects. We realized that Wikibooks was not included at the time, and we’re now addressing that to ensure consistency across all communities. The CampaignEvents extension provides tools to support event and campaign organization on-wiki, including features like on-wiki event registration and collaboration lists(global event list). We welcome any questions, feedback, or concerns you may have. We are also happy to support anyone interested in trying out the tools. ''Apologies if this message is not in your preferred language. If you’re able to help translate it for your community, please feel free to do so.'' <section end="message"/> </div> <bdi lang="en" dir="ltr">[[User:Udehb-WMF|Udehb-WMF]] ([[User talk:Udehb-WMF|discusión]]) 18:22 19 mar 2026 (UTC)</bdi> <!-- Mensaje enviado por Usuario:Udehb-WMF@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=User:Udehb-WMF/sandbox/MM_target&oldid=30284073 --> == Action Required: Update templates/modules for electoral maps (Migrating from P1846 to P14226) == Hello everyone, This is a notice regarding an ongoing data migration on Wikidata that may affect your election-related templates and Lua modules (such as <code>Module:Itemgroup/list</code>). '''The Change:'''<br /> Currently, many templates pull electoral maps from Wikidata using the property [[:d:Property:P1846|P1846]], combined with the qualifier [[:d:Property:P180|P180]]: [[:d:Q19571328|Q19571328]]. We are migrating this data (across roughly 4,000 items) to a newly created, dedicated property: '''[[:d:Property:P14226|P14226]]'''. '''What You Need To Do:'''<br /> To ensure your templates and infoboxes do not break or lose their maps, please update your local code to fetch data from [[:d:Property:P14226|P14226]] instead of the old [[:d:Property:P1846|P1846]] + [[:d:Property:P180|P180]] structure. A [[m:Wikidata/Property Migration: P1846 to P14226/List|list of pages]] was generated using Wikimedia Global Search. '''Deadline:'''<br /> We are temporarily retaining the old data on [[:d:Property:P1846|P1846]] to allow for a smooth transition. However, to complete the data cleanup on Wikidata, the old [[:d:Property:P1846|P1846]] statements will be removed after '''May 1, 2026'''. Please update your modules and templates before this date to prevent any disruption to your wiki's election articles. Let us know if you have any questions or need assistance with the query logic. Thank you for your help! [[User:ZI Jony|ZI Jony]] using [[Usuario:MediaWiki message delivery|MediaWiki message delivery]] ([[Usuario discusión:MediaWiki message delivery|discusión]]) 17:11 3 abr 2026 (UTC) <!-- Mensaje enviado por Usuario:ZI Jony@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29941252 --> == Request for comment (global AI policy) == <bdi lang="en" dir="ltr" class="mw-content-ltr"> Apologies for writing in English. {{int:Please-translate}} A [[:m:Requests for comment/Artificial intelligence policy|request for comment]] is currently being held to decide on a global AI policy. {{int:Feedback-thanks-title}} [[Usuario:MediaWiki message delivery|MediaWiki message delivery]] ([[Usuario discusión:MediaWiki message delivery|discusión]]) 00:57 26 abr 2026 (UTC) </bdi> <!-- Mensaje enviado por Usuario:Codename Noreste@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30424282 --> == Vota ahora en las elecciones del U4C de 2026 == <section begin="announcement-content" /> Se invita a las y los votantes con derecho a voto a participar en las elecciones de 2026 del [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Comité de Coordinación del Código de Conducta Universal]]. En Meta, en la [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026|página de información sobre las elecciones de 2026]], hay disponible más información, incluyendo una comprobación de elegibilidad, información sobre el proceso de votación, información sobre las y los candidatos y un enlace a la votación. La votación finaliza el 2 de junio de 2026 a las [https://zonestamp.toolforge.org/1780358400 00:00 UTC]. Por favor, vota si tu cuenta es elegible. Los resultados estarán disponibles para el 14 de junio de 2026. -- En cooperación con la U4C,<section end="announcement-content" /> [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 17:14 27 may 2026 (UTC) <!-- Mensaje enviado por Usuario:Keegan (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 --> == Actualizada una plantilla == Buenas. Quería comentar un cambio que he realizado en una plantilla de mantenimiento del sitio, con el objetivo de unificar criterios y facilitar la edición entre proyectos hermanos. En la Wikipedia en español existen desde 2007 dos plantillas con funciones bien diferenciadas: * [[w:Plantilla:Desactualizado]]: Para indicar que una página completa o sección ya contiene información obsoleta. * [[w:Plantilla:Actualizar]]: Para marcar pasajes específicos que requerirán revisión a partir de una fecha futura programada (como elecciones o eventos deportivos). Hasta ahora, en Wikilibros se venía utilizando la plantilla <nowiki>{{Actualizar}}</nowiki> con el mismo propósito que la plantilla <nowiki>{{Desactualizado}}</nowiki> en Wikipedia en español. Esto podía generar cierta confusión en los usuarios que editan en ambos proyectos (como fue mi caso al principio). Para estandarizar el flujo de trabajo entre ambos proyectos, he importado la plantilla <nowiki>{{Desactualizado}}</nowiki> a Wikilibros con su función original, he adaptado <nowiki>{{Actualizar}}</nowiki> para que cumpla su rol específico de aviso futuro al igual que se hace en la Wikipedia en español, y he actualizado las páginas pertinentes para que usen la plantilla adecuada. Así, esta plantilla se usa igual que con el resto de los proyectos hermanos, facilitando el trabajo a los editores actuales y futuros ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 12:18 9 jun 2026 (UTC) == Petición para renombrar los «Proyectos» a «Wikiproyectos» == Propongo renombrar los actuales «Proyectos» a «Wikiproyectos». Y que usen su propio espacio de nombres. Por ejemplo, en vez de «Wikilibros:Proyecto mantenimiento», pasaría a llamarse «Wikiproyecto:Mantenimiento» al igual que en otros proyectos de Wikimedia. Hasta donde he podido investigar, el nombre «Proyectos» se empezó a usar en 2008 porque así los llamó el usuario que los creó, sin una consulta o consenso previo documentado. Personalmente, considero que «Wikiproyecto» es un término mas claro y preciso. Cuando hablamos de un «Wikiproyecto» se entiende inmediatamente que nos referimos a un espacio concreto de coordinación dentro de la wiki, no a un proyecto en el sentido abstracto y general. Además, considero que sería positivo por consistencia con otros proyectos de Wikimedia. Históricamente, muchos usuarios valiosos de Wikilibros eran colaboradores de Wikipedia en español, donde se llaman «Wikiproyectos». Mantener una terminología familiar facilita la adaptación de un proyecto a otro y evita confusiones innecesarias por diferencias arbitrarias de nomenclatura. En varias ediciones de Wikilibros y Wikipedia en otros idiomas también se utiliza esta denominación: * En Wikibooks y Wikipedia en inglés se llaman «WikiProjects». * En Viquillibres y Wikipedia en catalán se llaman «Viquiprojectes». * En Wikiliburuak y Wikipedia en euskera se llaman «wikiproiektuak». * En Wikipedia en gallego se llaman «Wikiproxectos». También es cierto que no todas las ediciones de Wikilibros usan este concepto, por ejemplo, algunas como la francesa o la italiana ni si quiera tienen ninguna estructura equivalente de «Wikiproyectos». Pero muchas sí la tienen y, especialmente en proyectos como Wikipedia en Español, de donde surgen muchos colaboradores de esta wiki sí se llaman así. Hacer el traslado, además, sería muy sencillo, ya que actualmente solo existen 7 páginas en el actual «Wikilibros:Proyectos». Por eso quería plantearlo aquí primero y conocer si alguien mas está de acuerdo antes de realizar el traslado. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 07:55 23 jun 2026 (UTC) : No veo necesario realizar este cambio. : En primer lugar, creo que es importante distinguir qué es un Wikiproyecto y cuál es la realidad actual de Wikilibros. Históricamente, los Wikiproyectos surgieron en Wikipedia como espacios de coordinación de grupos de editores que comparten un interés temático o una meta editorial común. Su objetivo principal es organizar esfuerzos colectivos para desarrollar contenidos específicos, establecer estándares y coordinar trabajo entre varios participantes. : Si observamos la definición utilizada en Wikibooks en inglés, en la página "[[b:Wikibooks:WikiProject|WikiProject]]", estos espacios se describen principalmente como lugares destinados a coordinar la creación y desarrollo de libros. Es decir, se trata de iniciativas colaborativas enfocadas en la construcción de contenido, más que en la existencia de grupos reducidos dedicados a tareas administrativas o de mantenimiento. : La situación actual de Wikilibros en español es bastante distinta. Actualmente no existe una comunidad activa y numerosa que participe de manera sostenida en proyectos temáticos o grupos de trabajo especializados. Los espacios existentes funcionan más como páginas organizativas o de coordinación puntual que como verdaderos Wikiproyectos en el sentido en que se entiende el término dentro del movimiento Wikimedia. : Por ello, considero que adoptar la denominación «Wikiproyecto» podría incluso resultar confuso, ya que transmite la idea de una estructura comunitaria activa y consolidada que actualmente no existe. El nombre «Proyecto» cumple adecuadamente la función de identificar estos espacios sin atribuirles una naturaleza que, en la práctica, no poseen. : Tampoco veo una necesidad funcional que justifique crear un espacio de nombres específico. El sistema actual funciona correctamente, las páginas son pocas y su localización resulta sencilla. El cambio no resolvería ningún problema operativo ni facilitaría tareas que actualmente sean difíciles de realizar. : Respecto a la consistencia con otros proyectos Wikimedia, si bien es cierto que muchas Wikipedias utilizan el término «Wikiproyecto», también es cierto que cada proyecto ha desarrollado históricamente sus propias convenciones organizativas. La mera existencia de una denominación distinta en otros proyectos no constituye, por sí sola, una razón suficiente para modificar una estructura local que lleva años funcionando sin inconvenientes. : Finalmente, si el principal motivo es una cuestión estética o de preferencia terminológica, considero que no debería procederse al cambio. Los cambios de nomenclatura y espacios de nombres deberían responder a una necesidad práctica, organizativa o técnica claramente identificable. En este caso, no observo un beneficio concreto para los usuarios ni para el desarrollo de Wikilibros que justifique el traslado de páginas y la modificación de una convención establecida. [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 18:23 23 jun 2026 (UTC) ::Bien argumentado, me has convencido. Tienes razón en que estos «Proyectos» en Wikilibros sirven actualmente como espacio de coordinación puntual para tareas administrativas y de mantenimiento generales, y funcionan de manera distinta a cómo lo hacen los «Wikiproyectos» de otras wikis donde son espacios temáticos o grupos de trabajos especializados. ::Dicho esto, considero que si en un futuro surgiesen estos espacios y tuviesen el mismo propósito que tienen los Wikiproyectos en otras wikis como la Wikipedia en español, si me parecería que en tal caso deberían llamarse «Wikiproyectos» por lo que argumenté en mi primer mensaje. ::Pero estoy de acuerdo contigo en que, como esa no es la realidad ahora como bien has señalado, por mí queda consensuado que de momento los actuales proyectos se pueden quedar con ese nombre. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 18:55 23 jun 2026 (UTC) == RFC about AI-generated content in Wikimedia Commons == <bdi lang="en" dir="ltr">Apologies for writing in English, please help translate this message to your language. You are invited to participate in a [[c:Commons:Requests for comment/Policy update for AI content|request for comment on Wikimedia Commons about a policy update for AI content]]. This may affect files that are uploaded to Wikimedia Commons for use on this project. Thank you. [[m:User:Codename Noreste|Codename Noreste]] ([[m:User talk:Codename Noreste|discusión]])</bdi> 17:11 23 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Codename Noreste@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 --> amdt01k82yhev2wlnci371qjbih1qqr 427892 427890 2026-07-16T01:47:52Z Mazbel 57931 /* Incorporación del enlace «Contactos legales y de seguridad» en el pie de página de vuestra wiki */ archive from [[Wikilibros:Café]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]]) 427892 wikitext text/x-wiki {{Archivo}} == Thank You for Last Year – Join Wiki Loves Ramadan 2026 == Dear Wikimedia communities, We hope you are doing well, and we wish you a happy New Year. ''Last year, we captured light. This year, we’ll capture legacy.'' In 2025, communities around the world shared the glow of Ramadan nights and the warmth of collective iftars. In 2026, ''Wiki Loves Ramadan'' is expanding, bringing more stories, more cultures, and deeper global connections across Wikimedia projects. We invite you to explore the ''Wiki Loves Ramadan 2026'' [[m:Special:MyLanguage/Wiki Loves Ramadan 2026|Meta page]] to learn how you can participate and [[m:Special:MyLanguage/Wiki Loves Ramadan 2026/Participating communities|sign up]] your community. 📷 ''Photo campaign on '' [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan 2026|Wikimedia Commons]] If you have questions about the project, please refer to the FAQs: * [[m:Special:MyLanguage/Wiki Loves Ramadan/FAQ/|Meta-Wiki]] * [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan/FAQ|Wikimedia Commons]] ''Early registration for updates is now open via the '''[[m:Special:RegisterForEvent/2710|Event page]]''''' ''Stay connected and receive updates:'' * [https://t.me/WikiLovesRamadan Telegram channel] * [https://lists.wikimedia.org/postorius/lists/wikilovesramadan.lists.wikimedia.org/ Mailing list] We look forward to collaborating with you and your community. '''The Wiki Loves Ramadan 2026 Organizing Team''' 19:45 16 ene 2026 (UTC) <!-- Mensaje enviado por Usuario:ZI Jony@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29879549 --> == Revisión anual del Código Universal de Conducta y las Directrices de Aplicación == <section begin="announcement-content" /> <div lang="en" dir="ltr" class="mw-content-ltr"> I am writing to you to let you know the annual review period for the Universal Code of Conduct and Enforcement Guidelines is open now. You can make suggestions for changes through 9 February 2026. This is the first step of several to be taken for the annual review. [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2026|Read more information and find a conversation to join on the UCoC page on Meta]]. </div> <div lang="en" dir="ltr" class="mw-content-ltr"> The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|you may review the U4C Charter]]. </div> Por favor, comparte esta información con otros miembros de tu comunidad en cualquier otro lugar que sea apropiado. <div lang="en" dir="ltr" class="mw-content-ltr"> -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) </div><section end="announcement-content" /> 21:01 19 ene 2026 (UTC) <!-- Mensaje enviado por Usuario:Keegan (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29905753 --> == <span lang="en" dir="ltr">Upcoming deployment of CampaignEvents extension to Wikibooks</span> == <div lang="en" dir="ltr"> <section begin="message"/> Hello everyone, We are writing to inform you that the [[mw:Help:Extension:CampaignEvents|CampaignEvents extension]] will be deployed to all Wikibooks projects during the week of '''23 March 2026'''. This follows last year’s broader rollout across Wikimedia projects. We realized that Wikibooks was not included at the time, and we’re now addressing that to ensure consistency across all communities. The CampaignEvents extension provides tools to support event and campaign organization on-wiki, including features like on-wiki event registration and collaboration lists(global event list). We welcome any questions, feedback, or concerns you may have. We are also happy to support anyone interested in trying out the tools. ''Apologies if this message is not in your preferred language. If you’re able to help translate it for your community, please feel free to do so.'' <section end="message"/> </div> <bdi lang="en" dir="ltr">[[User:Udehb-WMF|Udehb-WMF]] ([[User talk:Udehb-WMF|discusión]]) 18:22 19 mar 2026 (UTC)</bdi> <!-- Mensaje enviado por Usuario:Udehb-WMF@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=User:Udehb-WMF/sandbox/MM_target&oldid=30284073 --> == Action Required: Update templates/modules for electoral maps (Migrating from P1846 to P14226) == Hello everyone, This is a notice regarding an ongoing data migration on Wikidata that may affect your election-related templates and Lua modules (such as <code>Module:Itemgroup/list</code>). '''The Change:'''<br /> Currently, many templates pull electoral maps from Wikidata using the property [[:d:Property:P1846|P1846]], combined with the qualifier [[:d:Property:P180|P180]]: [[:d:Q19571328|Q19571328]]. We are migrating this data (across roughly 4,000 items) to a newly created, dedicated property: '''[[:d:Property:P14226|P14226]]'''. '''What You Need To Do:'''<br /> To ensure your templates and infoboxes do not break or lose their maps, please update your local code to fetch data from [[:d:Property:P14226|P14226]] instead of the old [[:d:Property:P1846|P1846]] + [[:d:Property:P180|P180]] structure. A [[m:Wikidata/Property Migration: P1846 to P14226/List|list of pages]] was generated using Wikimedia Global Search. '''Deadline:'''<br /> We are temporarily retaining the old data on [[:d:Property:P1846|P1846]] to allow for a smooth transition. However, to complete the data cleanup on Wikidata, the old [[:d:Property:P1846|P1846]] statements will be removed after '''May 1, 2026'''. Please update your modules and templates before this date to prevent any disruption to your wiki's election articles. Let us know if you have any questions or need assistance with the query logic. Thank you for your help! [[User:ZI Jony|ZI Jony]] using [[Usuario:MediaWiki message delivery|MediaWiki message delivery]] ([[Usuario discusión:MediaWiki message delivery|discusión]]) 17:11 3 abr 2026 (UTC) <!-- Mensaje enviado por Usuario:ZI Jony@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29941252 --> == Request for comment (global AI policy) == <bdi lang="en" dir="ltr" class="mw-content-ltr"> Apologies for writing in English. {{int:Please-translate}} A [[:m:Requests for comment/Artificial intelligence policy|request for comment]] is currently being held to decide on a global AI policy. {{int:Feedback-thanks-title}} [[Usuario:MediaWiki message delivery|MediaWiki message delivery]] ([[Usuario discusión:MediaWiki message delivery|discusión]]) 00:57 26 abr 2026 (UTC) </bdi> <!-- Mensaje enviado por Usuario:Codename Noreste@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30424282 --> == Vota ahora en las elecciones del U4C de 2026 == <section begin="announcement-content" /> Se invita a las y los votantes con derecho a voto a participar en las elecciones de 2026 del [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Comité de Coordinación del Código de Conducta Universal]]. En Meta, en la [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026|página de información sobre las elecciones de 2026]], hay disponible más información, incluyendo una comprobación de elegibilidad, información sobre el proceso de votación, información sobre las y los candidatos y un enlace a la votación. La votación finaliza el 2 de junio de 2026 a las [https://zonestamp.toolforge.org/1780358400 00:00 UTC]. Por favor, vota si tu cuenta es elegible. Los resultados estarán disponibles para el 14 de junio de 2026. -- En cooperación con la U4C,<section end="announcement-content" /> [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 17:14 27 may 2026 (UTC) <!-- Mensaje enviado por Usuario:Keegan (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 --> == Actualizada una plantilla == Buenas. Quería comentar un cambio que he realizado en una plantilla de mantenimiento del sitio, con el objetivo de unificar criterios y facilitar la edición entre proyectos hermanos. En la Wikipedia en español existen desde 2007 dos plantillas con funciones bien diferenciadas: * [[w:Plantilla:Desactualizado]]: Para indicar que una página completa o sección ya contiene información obsoleta. * [[w:Plantilla:Actualizar]]: Para marcar pasajes específicos que requerirán revisión a partir de una fecha futura programada (como elecciones o eventos deportivos). Hasta ahora, en Wikilibros se venía utilizando la plantilla <nowiki>{{Actualizar}}</nowiki> con el mismo propósito que la plantilla <nowiki>{{Desactualizado}}</nowiki> en Wikipedia en español. Esto podía generar cierta confusión en los usuarios que editan en ambos proyectos (como fue mi caso al principio). Para estandarizar el flujo de trabajo entre ambos proyectos, he importado la plantilla <nowiki>{{Desactualizado}}</nowiki> a Wikilibros con su función original, he adaptado <nowiki>{{Actualizar}}</nowiki> para que cumpla su rol específico de aviso futuro al igual que se hace en la Wikipedia en español, y he actualizado las páginas pertinentes para que usen la plantilla adecuada. Así, esta plantilla se usa igual que con el resto de los proyectos hermanos, facilitando el trabajo a los editores actuales y futuros ¡Un saludo! [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 12:18 9 jun 2026 (UTC) == Petición para renombrar los «Proyectos» a «Wikiproyectos» == Propongo renombrar los actuales «Proyectos» a «Wikiproyectos». Y que usen su propio espacio de nombres. Por ejemplo, en vez de «Wikilibros:Proyecto mantenimiento», pasaría a llamarse «Wikiproyecto:Mantenimiento» al igual que en otros proyectos de Wikimedia. Hasta donde he podido investigar, el nombre «Proyectos» se empezó a usar en 2008 porque así los llamó el usuario que los creó, sin una consulta o consenso previo documentado. Personalmente, considero que «Wikiproyecto» es un término mas claro y preciso. Cuando hablamos de un «Wikiproyecto» se entiende inmediatamente que nos referimos a un espacio concreto de coordinación dentro de la wiki, no a un proyecto en el sentido abstracto y general. Además, considero que sería positivo por consistencia con otros proyectos de Wikimedia. Históricamente, muchos usuarios valiosos de Wikilibros eran colaboradores de Wikipedia en español, donde se llaman «Wikiproyectos». Mantener una terminología familiar facilita la adaptación de un proyecto a otro y evita confusiones innecesarias por diferencias arbitrarias de nomenclatura. En varias ediciones de Wikilibros y Wikipedia en otros idiomas también se utiliza esta denominación: * En Wikibooks y Wikipedia en inglés se llaman «WikiProjects». * En Viquillibres y Wikipedia en catalán se llaman «Viquiprojectes». * En Wikiliburuak y Wikipedia en euskera se llaman «wikiproiektuak». * En Wikipedia en gallego se llaman «Wikiproxectos». También es cierto que no todas las ediciones de Wikilibros usan este concepto, por ejemplo, algunas como la francesa o la italiana ni si quiera tienen ninguna estructura equivalente de «Wikiproyectos». Pero muchas sí la tienen y, especialmente en proyectos como Wikipedia en Español, de donde surgen muchos colaboradores de esta wiki sí se llaman así. Hacer el traslado, además, sería muy sencillo, ya que actualmente solo existen 7 páginas en el actual «Wikilibros:Proyectos». Por eso quería plantearlo aquí primero y conocer si alguien mas está de acuerdo antes de realizar el traslado. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 07:55 23 jun 2026 (UTC) : No veo necesario realizar este cambio. : En primer lugar, creo que es importante distinguir qué es un Wikiproyecto y cuál es la realidad actual de Wikilibros. Históricamente, los Wikiproyectos surgieron en Wikipedia como espacios de coordinación de grupos de editores que comparten un interés temático o una meta editorial común. Su objetivo principal es organizar esfuerzos colectivos para desarrollar contenidos específicos, establecer estándares y coordinar trabajo entre varios participantes. : Si observamos la definición utilizada en Wikibooks en inglés, en la página "[[b:Wikibooks:WikiProject|WikiProject]]", estos espacios se describen principalmente como lugares destinados a coordinar la creación y desarrollo de libros. Es decir, se trata de iniciativas colaborativas enfocadas en la construcción de contenido, más que en la existencia de grupos reducidos dedicados a tareas administrativas o de mantenimiento. : La situación actual de Wikilibros en español es bastante distinta. Actualmente no existe una comunidad activa y numerosa que participe de manera sostenida en proyectos temáticos o grupos de trabajo especializados. Los espacios existentes funcionan más como páginas organizativas o de coordinación puntual que como verdaderos Wikiproyectos en el sentido en que se entiende el término dentro del movimiento Wikimedia. : Por ello, considero que adoptar la denominación «Wikiproyecto» podría incluso resultar confuso, ya que transmite la idea de una estructura comunitaria activa y consolidada que actualmente no existe. El nombre «Proyecto» cumple adecuadamente la función de identificar estos espacios sin atribuirles una naturaleza que, en la práctica, no poseen. : Tampoco veo una necesidad funcional que justifique crear un espacio de nombres específico. El sistema actual funciona correctamente, las páginas son pocas y su localización resulta sencilla. El cambio no resolvería ningún problema operativo ni facilitaría tareas que actualmente sean difíciles de realizar. : Respecto a la consistencia con otros proyectos Wikimedia, si bien es cierto que muchas Wikipedias utilizan el término «Wikiproyecto», también es cierto que cada proyecto ha desarrollado históricamente sus propias convenciones organizativas. La mera existencia de una denominación distinta en otros proyectos no constituye, por sí sola, una razón suficiente para modificar una estructura local que lleva años funcionando sin inconvenientes. : Finalmente, si el principal motivo es una cuestión estética o de preferencia terminológica, considero que no debería procederse al cambio. Los cambios de nomenclatura y espacios de nombres deberían responder a una necesidad práctica, organizativa o técnica claramente identificable. En este caso, no observo un beneficio concreto para los usuarios ni para el desarrollo de Wikilibros que justifique el traslado de páginas y la modificación de una convención establecida. [[User:Mazbel|<span style="color:#000000;font-weight:bold;font-family:cursive, serif">Mazbel</span>]] [[User talk:Mazbel|<span style="color:#000000;font-size:small;font-family:cursive, serif;">(Talk)</span>]] 18:23 23 jun 2026 (UTC) ::Bien argumentado, me has convencido. Tienes razón en que estos «Proyectos» en Wikilibros sirven actualmente como espacio de coordinación puntual para tareas administrativas y de mantenimiento generales, y funcionan de manera distinta a cómo lo hacen los «Wikiproyectos» de otras wikis donde son espacios temáticos o grupos de trabajos especializados. ::Dicho esto, considero que si en un futuro surgiesen estos espacios y tuviesen el mismo propósito que tienen los Wikiproyectos en otras wikis como la Wikipedia en español, si me parecería que en tal caso deberían llamarse «Wikiproyectos» por lo que argumenté en mi primer mensaje. ::Pero estoy de acuerdo contigo en que, como esa no es la realidad ahora como bien has señalado, por mí queda consensuado que de momento los actuales proyectos se pueden quedar con ese nombre. [[Usuario:Antimundo|Antimundo]] ([[Usuario discusión:Antimundo|discusión]]) 18:55 23 jun 2026 (UTC) == RFC about AI-generated content in Wikimedia Commons == <bdi lang="en" dir="ltr">Apologies for writing in English, please help translate this message to your language. You are invited to participate in a [[c:Commons:Requests for comment/Policy update for AI content|request for comment on Wikimedia Commons about a policy update for AI content]]. This may affect files that are uploaded to Wikimedia Commons for use on this project. Thank you. [[m:User:Codename Noreste|Codename Noreste]] ([[m:User talk:Codename Noreste|discusión]])</bdi> 17:11 23 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Codename Noreste@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 --> == Incorporación del enlace «Contactos legales y de seguridad» en el pie de página de vuestra wiki == <section begin="Message"/> '''Contactos legales y de seguridad''' Hola a toda la comunidad: la Fundación Wikimedia ha puesto a vuestra disposición una [[wmf:Special:MyLanguage/Legal:Wikimedia Foundation Legal and Safety Contact Information|página única de contacto sobre cuestiones legales y de seguridad]], que debéis incluir en el pie de página de vuestra wiki para garantizar el acceso a información jurídica precisa. Se trata de un requisito normativo. Ya hemos implementado enlaces a las wikis en inglés, alemán, italiano, español y otros idiomas de Wikipedia, y pronto los implementaremos en vuestra wiki. [[m:Special:MyLanguage/Wikimedia_Foundation_Legal_and_Safety_Contacts_FAQ|Por favor, leed más información en la página del proyecto]] y dejad vuestros comentarios en este hilo o en la [[m:Special:MyLanguage/Talk:Wikimedia Foundation Legal and Safety Contacts FAQ|página de discusión]]. <section end="Message"/> -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 13:30 25 jun 2026 (UTC) <!-- Mensaje enviado por Usuario:Sannita (WMF)@metawiki mediante la lista en https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=30731267 --> bdvfhj4iyx31kgzyh5dlut0qucsbr83 Wikichicos/Geografía de España/Geografía física/Relieve/Montañas 0 64050 427852 427673 2026-07-15T16:21:03Z AAbelardoo 123302 427852 wikitext text/x-wiki Las principales cordilleras de la península pueden considerarse, en relación con la '''Meseta Central''', organizadas en tres grupos: :[[Archivo:Spain topo.png|miniaturadeimagen|300x300px]] :* '''Cordilleras interiores a la Meseta Central''' :* '''Cordilleras que rodean la Meseta Central''' :* '''Cordilleras exteriores a la Meseta Central''' == Cordilleras interiores a la Meseta Central == Dentro de la Meseta Central hay dos sistemas montañosos: el '''sistema Central''' y los '''montes de Toledo'''. * El '''sistema Central''', ubicado en el centro de la meseta, la divide en dos '''submesetas''' (norte y sur) y es la frontera natural entre las comunidades autónomas de '''Castilla y León''' por un lado, y de la '''Comunidad de Madrid''' y '''Castilla-La Mancha''' por otro. La cordillera se extiende de oeste a este a lo largo de 700 km, y su pico más alto es el Almanzor, con 2592 m s. n. m. Algunas de sus sierras son la de Gata y de Gredos en su mitad oeste, y las de Guadarrama y de Ayllón en su mitad este. * Los '''montes de Toledo''' son una pequeña cordillera de 350 km de longitud y 100 km de anchura que se extiende de oeste a este en las provincias de '''Toledo''' y '''Cáceres'''. Estas montañas no son especialmente elevadas puesto que el pico más alto, el de la Villuerca Alta, mide 1603 m s. n. m. A esta cordillera pertenece la sierra de Guadalupe, ubicada en el centro de Extremadura. <center> <gallery widths="250" heights="250"> Archivo:Montes de Toledo9.png|Los Montes de Toledo señalados en el mapa Archivo:Sistema Central.png|El sistema Central señalado en el mapa </gallery> </center> == Cordilleras que rodean la Meseta Central == La '''Meseta Central''' está rodeada por varias cordilleras que actúan como límites naturales. * Al norte se encuentra la '''cordillera Cantábrica''', que separa la meseta de la costa del mar Cantábrico y cuyo pico más alto es la '''Torre Cerredo''' (2.648 m). * Al este y noreste se sitúa el '''Sistema Ibérico''', que separa la meseta de la depresión del Ebro y del mar Mediterráneo. Su cumbre más alta es el '''Moncayo''' (2.313 m). * Al sur está '''Sierra Morena''', que divide la meseta de la depresión del Guadalquivir y presenta montañas de menor altura. * En el noroeste se encuentran los '''Montes de León'''. Estas cordilleras han sido importantes barreras naturales a lo largo de la historia de España. <center> <gallery widths="250" heights="250"> Archivo:Cordillera Cantabrica.jpg|Cordillera Cantábrica Archivo:Spain-2008-29-11.png|Sistema Ibérico Archivo:Location Sierra Morena.PNG|Sierra Morena </gallery> </center> == Cordilleras exteriores a la Meseta Central == Además de las montañas que rodean la Meseta Central, España cuenta con otras importantes cordilleras. * Los '''Pirineos''', situados en la frontera con Francia, son una de las cadenas montañosas más altas y extensas del país, y su pico más elevado es el '''Aneto''' (3.404 m). * En el noreste se encuentran las '''Cordilleras Costero-Catalanas''', paralelas a la costa mediterránea y formadas por la '''Cordillera Litoral''' y la '''Prelitoral'''. * En el sur y sureste se sitúan las '''Cordilleras Béticas''', donde se encuentra el '''Mulhacén''' (3.478 m), la montaña más alta de la península ibérica. Entre sus sierras destacan '''Sierra Nevada''', '''la sierra de Cazorla''' y '''la sierra de Grazalema'''. * En el noroeste de la península se encuentra el '''Macizo Galaico''', un relieve antiguo y muy erosionado que ocupa gran parte de Galicia. <center><gallery widths="200" heights="200"> Archivo:Pyrenees topographic map.png|Los Pirineos Archivo:Map-of-spain-cos-cat.png|Las cordilleras Costero-Catalanas arriba a la derecha en el mapa Archivo:Baetic System in Spanish - Cordilleras Béticas.png|Sistema Bético Archivo:Galicia Topo.svg|El macizo Galaico </gallery> </center> == Relieve insular == A España pertenecen dos archipiélagos de islas. Uno de ellos es el de las islas Baleares, ubicado en el mar Mediterráneo y a 90 km al este del cabo de la Nao (Alicante). El otro es el de las Islas Canarias, situado en el océano Atlántico, a 1050 km al suroeste de Cádiz y a 100 km al oeste de la costa africana. === Relieve de las islas Baleares === Las islas Baleares es un archipiélago situado en el mar Mediterráneo, a 80 km al este de la península ibérica. Las tres islas más grandes e importantes que componen Baleares son Ibiza, Mallorca y Menorca. Las tres islas principales están alineadas en ese orden orientadas de suroeste a noreste. Aparte de estas tres, hay otras islas de menor tamaño como son Formentera y la Cabrera. En el relieve de las islas Baleares predominan las zonas llanas y de escasa altitud, exceptuando la sierra de la Tramontana, situada en Mallorca ==== Costas de las islas Baleares ==== Las costas de las islas Baleares son altas, ya que en muchos lugares las montañas llegan hasta el mar. Si el mar baña una llanura, la costa es baja y arenosa. === Relieve de las islas Canarias === El archipiélago de las islas Canarias está situado en el océano Atlántico norte, a 1050 km al suroeste de la costa de Cádiz y a 100 km al oeste de la costa africana. Canarias se compone de siete islas principales dispuestas de oeste a este y de dos islotes, Alegranza y Graciosa. Es de origen volcánico debido a su formación mediante la acumulación de sedimentos procedentes de las erupciones. El relieve de las islas es montañoso, con una importante presencia de volcanes y con costas altas. El más alto de ellos es el Teide (3715 m), situado en la isla de Tenerife, siendo también el más alto del territorio español y el tercer volcán más grande del mundo desde su base. ==== Costas de las islas Canarias ==== Las costas de las islas Canarias son algunas costas altas, con acantilados; y otras de costas bajas con playas de arena o de piedra, donde se forman las dunas. Si es de origen volcánico, la playa tiene arena de color negro. == Relieve de las plazas de soberanía == Las plazas de soberanía es el conjunto de posesiones españolas en la costa norte de África. ; Ceuta : Ceuta es una ciudad autónoma situado en la costa norte de África, en el estrecho de Gibraltar y hace frontera con Marruecos. El relieve es ligeramente montañoso por el oeste, en la zona fronteriza con Marruecos. Cabe destacar en su extremo este el cabo de la punta Almina, y el Monte Hacho de 195 m de altitud. El monte Anyera, con 349 metros de altitud es el punto más alto de Ceuta. En la costa predominan más las rasas y acantilados que las playas. ; Melilla : Melilla es un municipio situado en la costa norte africana, al sur de la costa andaluza y tiene frontera con Marruecos. El relieve es muy llano, en el que las altitudes máximas se acercan a los 30 metros en la zona oeste. En la costa predominan las playas. ; Islas Chafarinas : islas Chafarinas es un archipiélago español del mar Mediterráneo, situado frente a las costas del norte de África de las que dista 4 km y constituido por tres islas principales: del Congreso, Isabel II y del Rey. Están protegidas bajo la forma de ''Reserva Nacional''. La superficie terrestre total es de 52,5 ha, el relieve es accidentado y rocoso y el punto más alto está en el cerro del Nido de las Águilas, en la isla del Congreso, con 137 m sobre el nivel del mar. Las playas son muy escasas en la costa de las islas. ; Peñón de Alhucemas : El peñón de Alhucemas es un islote situado en el mar Mediterráneo, a 2 km al norte de la costa africana y en la bahía homónima. Integra, junto con dos islotes deshabitados, el islote de Tierra y el de Mar, las islas Alhucemas. Mide unos 170 metros de largo por 86 de ancho, cuenta con una extensión superficial aproximada de 0,15 km² y tiene una altitud máxima de 15 metros. ; Peñón de Vélez de la Gomera : El Peñón de Vélez de la Gomera es una península (originalmente isla) situada en el norte de África, a 126 km al oeste de Melilla y a 117 km al sudeste de Ceuta unida al continente por una estrecha franja de arena. Tiene una extensión de 19 000 m² aproximadamente y una altitud máxima de 87 m sobre el nivel del mar. fk4zwvxiztwphbctg1wm5fcbym0tbvk 427853 427852 2026-07-15T16:25:31Z AAbelardoo 123302 /* Relieve de las islas Baleares */ 427853 wikitext text/x-wiki Las principales cordilleras de la península pueden considerarse, en relación con la '''Meseta Central''', organizadas en tres grupos: :[[Archivo:Spain topo.png|miniaturadeimagen|300x300px]] :* '''Cordilleras interiores a la Meseta Central''' :* '''Cordilleras que rodean la Meseta Central''' :* '''Cordilleras exteriores a la Meseta Central''' == Cordilleras interiores a la Meseta Central == Dentro de la Meseta Central hay dos sistemas montañosos: el '''sistema Central''' y los '''montes de Toledo'''. * El '''sistema Central''', ubicado en el centro de la meseta, la divide en dos '''submesetas''' (norte y sur) y es la frontera natural entre las comunidades autónomas de '''Castilla y León''' por un lado, y de la '''Comunidad de Madrid''' y '''Castilla-La Mancha''' por otro. La cordillera se extiende de oeste a este a lo largo de 700 km, y su pico más alto es el Almanzor, con 2592 m s. n. m. Algunas de sus sierras son la de Gata y de Gredos en su mitad oeste, y las de Guadarrama y de Ayllón en su mitad este. * Los '''montes de Toledo''' son una pequeña cordillera de 350 km de longitud y 100 km de anchura que se extiende de oeste a este en las provincias de '''Toledo''' y '''Cáceres'''. Estas montañas no son especialmente elevadas puesto que el pico más alto, el de la Villuerca Alta, mide 1603 m s. n. m. A esta cordillera pertenece la sierra de Guadalupe, ubicada en el centro de Extremadura. <center> <gallery widths="250" heights="250"> Archivo:Montes de Toledo9.png|Los Montes de Toledo señalados en el mapa Archivo:Sistema Central.png|El sistema Central señalado en el mapa </gallery> </center> == Cordilleras que rodean la Meseta Central == La '''Meseta Central''' está rodeada por varias cordilleras que actúan como límites naturales. * Al norte se encuentra la '''cordillera Cantábrica''', que separa la meseta de la costa del mar Cantábrico y cuyo pico más alto es la '''Torre Cerredo''' (2.648 m). * Al este y noreste se sitúa el '''Sistema Ibérico''', que separa la meseta de la depresión del Ebro y del mar Mediterráneo. Su cumbre más alta es el '''Moncayo''' (2.313 m). * Al sur está '''Sierra Morena''', que divide la meseta de la depresión del Guadalquivir y presenta montañas de menor altura. * En el noroeste se encuentran los '''Montes de León'''. Estas cordilleras han sido importantes barreras naturales a lo largo de la historia de España. <center> <gallery widths="250" heights="250"> Archivo:Cordillera Cantabrica.jpg|Cordillera Cantábrica Archivo:Spain-2008-29-11.png|Sistema Ibérico Archivo:Location Sierra Morena.PNG|Sierra Morena </gallery> </center> == Cordilleras exteriores a la Meseta Central == Además de las montañas que rodean la Meseta Central, España cuenta con otras importantes cordilleras. * Los '''Pirineos''', situados en la frontera con Francia, son una de las cadenas montañosas más altas y extensas del país, y su pico más elevado es el '''Aneto''' (3.404 m). * En el noreste se encuentran las '''Cordilleras Costero-Catalanas''', paralelas a la costa mediterránea y formadas por la '''Cordillera Litoral''' y la '''Prelitoral'''. * En el sur y sureste se sitúan las '''Cordilleras Béticas''', donde se encuentra el '''Mulhacén''' (3.478 m), la montaña más alta de la península ibérica. Entre sus sierras destacan '''Sierra Nevada''', '''la sierra de Cazorla''' y '''la sierra de Grazalema'''. * En el noroeste de la península se encuentra el '''Macizo Galaico''', un relieve antiguo y muy erosionado que ocupa gran parte de Galicia. <center><gallery widths="200" heights="200"> Archivo:Pyrenees topographic map.png|Los Pirineos Archivo:Map-of-spain-cos-cat.png|Las cordilleras Costero-Catalanas arriba a la derecha en el mapa Archivo:Baetic System in Spanish - Cordilleras Béticas.png|Sistema Bético Archivo:Galicia Topo.svg|El macizo Galaico </gallery> </center> == Relieve insular == A España pertenecen dos archipiélagos de islas. Uno de ellos es el de las islas Baleares, ubicado en el mar Mediterráneo y a 90 km al este del cabo de la Nao (Alicante). El otro es el de las Islas Canarias, situado en el océano Atlántico, a 1050 km al suroeste de Cádiz y a 100 km al oeste de la costa africana. === Relieve de las islas Baleares === [[Archivo:Mallorca topo s-tra.png|miniaturadeimagen|La sierra de la Tramontana en Mallorca]] Las islas Baleares es un archipiélago situado en el mar Mediterráneo, a 80 km al este de la península ibérica. Las tres islas más grandes e importantes que componen Baleares son Ibiza, Mallorca y Menorca. Las tres islas principales están alineadas en ese orden orientadas de suroeste a noreste. Aparte de estas tres, hay otras islas de menor tamaño como son Formentera y la Cabrera. En el relieve de las islas Baleares predominan las zonas llanas y de escasa altitud, exceptuando la sierra de la Tramontana, situada en Mallorca ==== Costas de las islas Baleares ==== Las costas de las islas Baleares son altas, ya que en muchos lugares las montañas llegan hasta el mar. Si el mar baña una llanura, la costa es baja y arenosa. === Relieve de las islas Canarias === El archipiélago de las islas Canarias está situado en el océano Atlántico norte, a 1050 km al suroeste de la costa de Cádiz y a 100 km al oeste de la costa africana. Canarias se compone de siete islas principales dispuestas de oeste a este y de dos islotes, Alegranza y Graciosa. Es de origen volcánico debido a su formación mediante la acumulación de sedimentos procedentes de las erupciones. El relieve de las islas es montañoso, con una importante presencia de volcanes y con costas altas. El más alto de ellos es el Teide (3715 m), situado en la isla de Tenerife, siendo también el más alto del territorio español y el tercer volcán más grande del mundo desde su base. ==== Costas de las islas Canarias ==== Las costas de las islas Canarias son algunas costas altas, con acantilados; y otras de costas bajas con playas de arena o de piedra, donde se forman las dunas. Si es de origen volcánico, la playa tiene arena de color negro. == Relieve de las plazas de soberanía == Las plazas de soberanía es el conjunto de posesiones españolas en la costa norte de África. [[Archivo:Mapa del sur de España neutral.png|miniaturadeimagen]] ; Ceuta : Ceuta es una ciudad autónoma situado en la costa norte de África, en el estrecho de Gibraltar y hace frontera con Marruecos. El relieve es ligeramente montañoso por el oeste, en la zona fronteriza con Marruecos. Cabe destacar en su extremo este el cabo de la punta Almina, y el Monte Hacho de 195 m de altitud. El monte Anyera, con 349 metros de altitud es el punto más alto de Ceuta. En la costa predominan más las rasas y acantilados que las playas. ; Melilla : Melilla es un municipio situado en la costa norte africana, al sur de la costa andaluza y tiene frontera con Marruecos. El relieve es muy llano, en el que las altitudes máximas se acercan a los 30 metros en la zona oeste. En la costa predominan las playas. ; Islas Chafarinas : islas Chafarinas es un archipiélago español del mar Mediterráneo, situado frente a las costas del norte de África de las que dista 4 km y constituido por tres islas principales: del Congreso, Isabel II y del Rey. Están protegidas bajo la forma de ''Reserva Nacional''. La superficie terrestre total es de 52,5 ha, el relieve es accidentado y rocoso y el punto más alto está en el cerro del Nido de las Águilas, en la isla del Congreso, con 137 m sobre el nivel del mar. Las playas son muy escasas en la costa de las islas. ; Peñón de Alhucemas : El peñón de Alhucemas es un islote situado en el mar Mediterráneo, a 2 km al norte de la costa africana y en la bahía homónima. Integra, junto con dos islotes deshabitados, el islote de Tierra y el de Mar, las islas Alhucemas. Mide unos 170 metros de largo por 86 de ancho, cuenta con una extensión superficial aproximada de 0,15 km² y tiene una altitud máxima de 15 metros. ; Peñón de Vélez de la Gomera : El Peñón de Vélez de la Gomera es una península (originalmente isla) situada en el norte de África, a 126 km al oeste de Melilla y a 117 km al sudeste de Ceuta unida al continente por una estrecha franja de arena. Tiene una extensión de 19 000 m² aproximadamente y una altitud máxima de 87 m sobre el nivel del mar. e32z1x1ewk0j4j1v0ha9bxyz42r9ztd 427854 427853 2026-07-15T16:27:43Z AAbelardoo 123302 /* Relieve de las islas Baleares */ 427854 wikitext text/x-wiki Las principales cordilleras de la península pueden considerarse, en relación con la '''Meseta Central''', organizadas en tres grupos: :[[Archivo:Spain topo.png|miniaturadeimagen|300x300px]] :* '''Cordilleras interiores a la Meseta Central''' :* '''Cordilleras que rodean la Meseta Central''' :* '''Cordilleras exteriores a la Meseta Central''' == Cordilleras interiores a la Meseta Central == Dentro de la Meseta Central hay dos sistemas montañosos: el '''sistema Central''' y los '''montes de Toledo'''. * El '''sistema Central''', ubicado en el centro de la meseta, la divide en dos '''submesetas''' (norte y sur) y es la frontera natural entre las comunidades autónomas de '''Castilla y León''' por un lado, y de la '''Comunidad de Madrid''' y '''Castilla-La Mancha''' por otro. La cordillera se extiende de oeste a este a lo largo de 700 km, y su pico más alto es el Almanzor, con 2592 m s. n. m. Algunas de sus sierras son la de Gata y de Gredos en su mitad oeste, y las de Guadarrama y de Ayllón en su mitad este. * Los '''montes de Toledo''' son una pequeña cordillera de 350 km de longitud y 100 km de anchura que se extiende de oeste a este en las provincias de '''Toledo''' y '''Cáceres'''. Estas montañas no son especialmente elevadas puesto que el pico más alto, el de la Villuerca Alta, mide 1603 m s. n. m. A esta cordillera pertenece la sierra de Guadalupe, ubicada en el centro de Extremadura. <center> <gallery widths="250" heights="250"> Archivo:Montes de Toledo9.png|Los Montes de Toledo señalados en el mapa Archivo:Sistema Central.png|El sistema Central señalado en el mapa </gallery> </center> == Cordilleras que rodean la Meseta Central == La '''Meseta Central''' está rodeada por varias cordilleras que actúan como límites naturales. * Al norte se encuentra la '''cordillera Cantábrica''', que separa la meseta de la costa del mar Cantábrico y cuyo pico más alto es la '''Torre Cerredo''' (2.648 m). * Al este y noreste se sitúa el '''Sistema Ibérico''', que separa la meseta de la depresión del Ebro y del mar Mediterráneo. Su cumbre más alta es el '''Moncayo''' (2.313 m). * Al sur está '''Sierra Morena''', que divide la meseta de la depresión del Guadalquivir y presenta montañas de menor altura. * En el noroeste se encuentran los '''Montes de León'''. Estas cordilleras han sido importantes barreras naturales a lo largo de la historia de España. <center> <gallery widths="250" heights="250"> Archivo:Cordillera Cantabrica.jpg|Cordillera Cantábrica Archivo:Spain-2008-29-11.png|Sistema Ibérico Archivo:Location Sierra Morena.PNG|Sierra Morena </gallery> </center> == Cordilleras exteriores a la Meseta Central == Además de las montañas que rodean la Meseta Central, España cuenta con otras importantes cordilleras. * Los '''Pirineos''', situados en la frontera con Francia, son una de las cadenas montañosas más altas y extensas del país, y su pico más elevado es el '''Aneto''' (3.404 m). * En el noreste se encuentran las '''Cordilleras Costero-Catalanas''', paralelas a la costa mediterránea y formadas por la '''Cordillera Litoral''' y la '''Prelitoral'''. * En el sur y sureste se sitúan las '''Cordilleras Béticas''', donde se encuentra el '''Mulhacén''' (3.478 m), la montaña más alta de la península ibérica. Entre sus sierras destacan '''Sierra Nevada''', '''la sierra de Cazorla''' y '''la sierra de Grazalema'''. * En el noroeste de la península se encuentra el '''Macizo Galaico''', un relieve antiguo y muy erosionado que ocupa gran parte de Galicia. <center><gallery widths="200" heights="200"> Archivo:Pyrenees topographic map.png|Los Pirineos Archivo:Map-of-spain-cos-cat.png|Las cordilleras Costero-Catalanas arriba a la derecha en el mapa Archivo:Baetic System in Spanish - Cordilleras Béticas.png|Sistema Bético Archivo:Galicia Topo.svg|El macizo Galaico </gallery> </center> == Relieve insular == A España pertenecen dos archipiélagos de islas. Uno de ellos es el de las islas Baleares, ubicado en el mar Mediterráneo y a 90 km al este del cabo de la Nao (Alicante). El otro es el de las Islas Canarias, situado en el océano Atlántico, a 1050 km al suroeste de Cádiz y a 100 km al oeste de la costa africana. === Relieve de las islas Baleares === [[Archivo:Reliefkarte Balearische Inseln 2022.png|miniaturadeimagen|Relieve de las islas Baleares]] [[Archivo:Mallorca topo s-tra.png|miniaturadeimagen|La sierra de la Tramontana en Mallorca|izquierda]] Las islas Baleares es un archipiélago situado en el mar Mediterráneo, a 80 km al este de la península ibérica. Las tres islas más grandes e importantes que componen Baleares son Ibiza, Mallorca y Menorca. Las tres islas principales están alineadas en ese orden orientadas de suroeste a noreste. Aparte de estas tres, hay otras islas de menor tamaño como son Formentera y la Cabrera. En el relieve de las islas Baleares predominan las zonas llanas y de escasa altitud, exceptuando la sierra de la Tramontana, situada en Mallorca ==== Costas de las islas Baleares ==== Las costas de las islas Baleares son altas, ya que en muchos lugares las montañas llegan hasta el mar. Si el mar baña una llanura, la costa es baja y arenosa. === Relieve de las islas Canarias === El archipiélago de las islas Canarias está situado en el océano Atlántico norte, a 1050 km al suroeste de la costa de Cádiz y a 100 km al oeste de la costa africana. Canarias se compone de siete islas principales dispuestas de oeste a este y de dos islotes, Alegranza y Graciosa. Es de origen volcánico debido a su formación mediante la acumulación de sedimentos procedentes de las erupciones. El relieve de las islas es montañoso, con una importante presencia de volcanes y con costas altas. El más alto de ellos es el Teide (3715 m), situado en la isla de Tenerife, siendo también el más alto del territorio español y el tercer volcán más grande del mundo desde su base. ==== Costas de las islas Canarias ==== Las costas de las islas Canarias son algunas costas altas, con acantilados; y otras de costas bajas con playas de arena o de piedra, donde se forman las dunas. Si es de origen volcánico, la playa tiene arena de color negro. == Relieve de las plazas de soberanía == Las plazas de soberanía es el conjunto de posesiones españolas en la costa norte de África. [[Archivo:Mapa del sur de España neutral.png|miniaturadeimagen]] ; Ceuta : Ceuta es una ciudad autónoma situado en la costa norte de África, en el estrecho de Gibraltar y hace frontera con Marruecos. El relieve es ligeramente montañoso por el oeste, en la zona fronteriza con Marruecos. Cabe destacar en su extremo este el cabo de la punta Almina, y el Monte Hacho de 195 m de altitud. El monte Anyera, con 349 metros de altitud es el punto más alto de Ceuta. En la costa predominan más las rasas y acantilados que las playas. ; Melilla : Melilla es un municipio situado en la costa norte africana, al sur de la costa andaluza y tiene frontera con Marruecos. El relieve es muy llano, en el que las altitudes máximas se acercan a los 30 metros en la zona oeste. En la costa predominan las playas. ; Islas Chafarinas : islas Chafarinas es un archipiélago español del mar Mediterráneo, situado frente a las costas del norte de África de las que dista 4 km y constituido por tres islas principales: del Congreso, Isabel II y del Rey. Están protegidas bajo la forma de ''Reserva Nacional''. La superficie terrestre total es de 52,5 ha, el relieve es accidentado y rocoso y el punto más alto está en el cerro del Nido de las Águilas, en la isla del Congreso, con 137 m sobre el nivel del mar. Las playas son muy escasas en la costa de las islas. ; Peñón de Alhucemas : El peñón de Alhucemas es un islote situado en el mar Mediterráneo, a 2 km al norte de la costa africana y en la bahía homónima. Integra, junto con dos islotes deshabitados, el islote de Tierra y el de Mar, las islas Alhucemas. Mide unos 170 metros de largo por 86 de ancho, cuenta con una extensión superficial aproximada de 0,15 km² y tiene una altitud máxima de 15 metros. ; Peñón de Vélez de la Gomera : El Peñón de Vélez de la Gomera es una península (originalmente isla) situada en el norte de África, a 126 km al oeste de Melilla y a 117 km al sudeste de Ceuta unida al continente por una estrecha franja de arena. Tiene una extensión de 19 000 m² aproximadamente y una altitud máxima de 87 m sobre el nivel del mar. lcusa2g48qo5qih73ri6lh8mtwewvva Categoría:Estante:Desarrollo de videojuegos 14 64069 427861 2026-07-15T17:59:29Z Antimundo 74354 Crear categoría 427861 wikitext text/x-wiki [[Categoría:Estante:Informática]] enh012omgx29c4glx9her8df1md4s44 Categoría:Libro:Crear un MUD 14 64070 427862 2026-07-15T18:00:16Z Antimundo 74354 Crear categoría 427862 wikitext text/x-wiki [[Categoría:Estante:Desarrollo de videojuegos]] dt18x1fv37wk3v5sybkg446llwhfouk Categoría:Libro:Desarrollo de videojuegos para PSP con C++ y SDL 14 64071 427864 2026-07-15T18:03:12Z Antimundo 74354 Crear categoría 427864 wikitext text/x-wiki [[Categoría:Estante:Desarrollo de videojuegos]] dt18x1fv37wk3v5sybkg446llwhfouk Categoría:Libro:Programación en C++ 14 64072 427920 2026-07-16T04:22:29Z Mazbel 57931 Se creó una página vacía 427920 wikitext text/x-wiki phoiac9h4m842xq45sp7s6u21eteeq1 427922 427920 2026-07-16T04:24:49Z Mazbel 57931 Añadiendo la [[Categoría:Estante:Lenguajes de programación]] mediante [[Wikipedia:HotCat|HotCat]] 427922 wikitext text/x-wiki [[Categoría:Estante:Lenguajes de programación]] 86firlmvnwn0hoj5alkzyl287jfoofb Categoría:Libro:Programación en PHP 14 64073 427926 2026-07-16T04:30:57Z Mazbel 57931 categorización 427926 wikitext text/x-wiki [[Category:Estante:Lenguajes de programación]] 35bn2f2ffksqpuhjbvezrd6pmlc0ti2 Categoría:Estante:Física 14 64074 427946 2026-07-16T05:39:23Z Mazbel 57931 Página creada con «[[Categoría:Estantes]]» 427946 wikitext text/x-wiki [[Categoría:Estantes]] gy0m9h7rr598skjkjre3p5rgzpbhnyf 427947 427946 2026-07-16T05:40:14Z Mazbel 57931 actualización 427947 wikitext text/x-wiki [[Categoría:Estante:Ciencias]] bbgwsmrnqse4nnb0qos1hukn0s818uk Categoría:Estante:Ciencias 14 64075 427948 2026-07-16T05:40:47Z Mazbel 57931 [[Categoría:Estantes]] 427948 wikitext text/x-wiki [[Categoría:Estantes]] gy0m9h7rr598skjkjre3p5rgzpbhnyf Categoría:Libro:Física 14 64076 427950 2026-07-16T05:48:43Z Mazbel 57931 Creando 427950 wikitext text/x-wiki [[Categoría:Estante:Ciencias]] bbgwsmrnqse4nnb0qos1hukn0s818uk