¿Cómo se diferencia de std::string?¿Qué es una cadena terminada en nulo?
Respuesta
Una cadena terminada en nulo es una secuencia contigua de caracteres, la última de las cuales tiene todos los ceros del patrón de bits binarios. No estoy seguro de lo que quiere decir con una "cadena habitual", pero si quiere decir std::string
, entonces no es necesario un std::string
(until C++11) para que sea contiguo y no se requiere un terminador. Además, los datos de cadena std::string
siempre se asignan y administran mediante el objeto std::string
que lo contiene; para una cadena terminada en nulo, no hay tal contenedor, y normalmente se refiere y administra tales cadenas usando punteros simples.
Todo esto debería estar cubierto en cualquier libro de texto C++ decente. Recomiendo apoderarse de Accelerated C++, uno de los mejores de ellos.
Una cadena con terminación nula significa que el final de la cadena se define mediante la aparición de un carácter nulo (todos los bits son cero).
"Otras cadenas", p. tiene que almacenar su propia duración.
Una "cadena" es realmente solo una matriz de char
s; una cadena terminada en nulo es aquella donde un carácter nulo '\0'
marca el final de la cadena (no necesariamente el final de la matriz). El compilador anula automáticamente todas las cadenas de código (delimitadas por comillas dobles ""
).
Entonces, por ejemplo, "hi"
es lo mismo que {'h', 'i', '\0'}
.
Forma mejor de entender que la respuesta aceptada. +1 – Mike
Puede valer la pena mencionar que los compiladores buscan el carácter nulo para determinar la longitud de la cadena. –
Tengo una temperatura de cadena, y guardé a, b, c como temp [0], temp [1] y temp [2]. Ahora, cuando hago "cout << temp", no da - "abc". ¿Que debería hacer? Tengo que saber que '\ 0' tampoco funciona como terminador de cadena aquí. –
Una cadena con terminación nula es un formato de cadena nativo en C. Los literales de cadena, por ejemplo, se implementan como terminados en nulo. Como resultado, una gran cantidad de código (biblioteca de tiempo de ejecución de C, para empezar) asume que las cadenas tienen terminación nula.
Hay dos formas principales para representar una cadena:
1) Una secuencia de caracteres ASCII con un nulo (nulo) carácter, 0, al final. Puedes saber cuánto tiempo está buscando el terminador. Esto se llama una cadena terminada en nulo, o a veces terminada en nulo.
2) Una secuencia de caracteres, más un campo separado (ya sea una longitud entera o un puntero al final de la cadena), para decirle cuánto tiempo es.
No estoy seguro acerca de "cadena habitual", pero lo que sucede a menudo es que cuando se habla de un idioma en particular, la palabra "cadena" se usa para referirse a la representación estándar para ese idioma. Entonces en Java, java.lang.String es una cadena de tipo 2, así que eso es lo que significa "cadena". En C, "cadena" probablemente significa una cadena tipo 1. El estándar es bastante detallado para ser preciso, pero la gente siempre quiere dejar fuera lo que es "obvio".
En C++, desafortunadamente, ambos tipos son estándar. std :: string es una cadena de tipo 2 [*], pero las funciones de biblioteca estándar heredadas de C operan en cadenas de tipo 1.
[*] En realidad, std :: string a menudo se implementa como una matriz de caracteres, con un campo de longitud separado y un terminador nulo. Eso es para que la función c_str()
se pueda implementar sin tener que copiar o volver a asignar los datos de cadena. No recuerdo de improviso si es legal implementar std :: string sin almacenar un campo de longitud: la pregunta es qué garantías de complejidad son requeridas por el estándar. Para contenedores en general size()
se recomienda que sea O (1), pero en realidad no se requiere que lo sea.Entonces, incluso si es legal, una implementación de std :: string que solo use terminadores nulos sería sorprendente.
'\0'
es un carácter ASCII con el código 0, terminador nulo, carácter nulo, NUL. En C idioma que sirve como un carácter reservado utilizado para indicar el final de una cadena. Muchas funciones estándar tales como strcpy, strlen, strcmp entre otros se basan en esto. De lo contrario, si no había NUL, otra forma de señal de final de cadena debe haber sido utilizada:
Esto permite que la cadena a ser de cualquier longitud, con sólo la sobrecarga de uno byte; la alternativa de almacenar un conteo requiere una cadena límite de longitud de 255 o una sobrecarga de más de un byte.
de wikipedia
C++std::string
sigue esta otra convención y sus datos está representado por una estructura llamada _Rep
:
// _Rep: string representation
// Invariants:
// 1. String really contains _M_length + 1 characters: due to 21.3.4
// must be kept null-terminated.
// 2. _M_capacity >= _M_length
// Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
// 3. _M_refcount has three states:
// -1: leaked, one reference, no ref-copies allowed, non-const.
// 0: one reference, non-const.
// n>0: n + 1 references, operations require a lock, const.
// 4. All fields==0 is an empty string, given the extra storage
// beyond-the-end for a null terminator; thus, the shared
// empty string representation needs no constructor.
struct _Rep_base
{
size_type _M_length;
size_type _M_capacity;
_Atomic_word _M_refcount;
};
struct _Rep : _Rep_base
{
// Types:
typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
// (Public) Data members:
// The maximum number of individual char_type elements of an
// individual string is determined by _S_max_size. This is the
// value that will be returned by max_size(). (Whereas npos
// is the maximum number of bytes the allocator can allocate.)
// If one was to divvy up the theoretical largest size string,
// with a terminating character and m _CharT elements, it'd
// look like this:
// npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
// Solving for m:
// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
// In addition, this implementation quarters this amount.
static const size_type _S_max_size;
static const _CharT _S_terminal;
// The following storage is init'd to 0 by the linker, resulting
// (carefully) in an empty string with one reference.
static size_type _S_empty_rep_storage[];
static _Rep&
_S_empty_rep()
{
// NB: Mild hack to avoid strict-aliasing warnings. Note that
// _S_empty_rep_storage is never modified and the punning should
// be reasonably safe in this case.
void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
return *reinterpret_cast<_Rep*>(__p);
}
bool
_M_is_leaked() const
{ return this->_M_refcount < 0; }
bool
_M_is_shared() const
{ return this->_M_refcount > 0; }
void
_M_set_leaked()
{ this->_M_refcount = -1; }
void
_M_set_sharable()
{ this->_M_refcount = 0; }
void
_M_set_length_and_sharable(size_type __n)
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
{
this->_M_set_sharable(); // One reference.
this->_M_length = __n;
traits_type::assign(this->_M_refdata()[__n], _S_terminal);
// grrr. (per 21.3.4)
// You cannot leave those LWG people alone for a second.
}
}
_CharT*
_M_refdata() throw()
{ return reinterpret_cast<_CharT*>(this + 1); }
_CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
{
return (!_M_is_leaked() && __alloc1 == __alloc2)
? _M_refcopy() : _M_clone(__alloc1);
}
// Create & Destroy
static _Rep*
_S_create(size_type, size_type, const _Alloc&);
void
_M_dispose(const _Alloc& __a)
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
-1) <= 0)
_M_destroy(__a);
} // XXX MT
void
_M_destroy(const _Alloc&) throw();
_CharT*
_M_refcopy() throw()
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
__gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
return _M_refdata();
} // XXX MT
_CharT*
_M_clone(const _Alloc&, size_type __res = 0);
};
los datos reales se pueden obtener con:
_Rep* _M_rep() const
{ return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
este fragmento de código proviene de archivo basic_string.h
, que en mi máquina se encuentra en usr/include/c++/4.4/bits/basic_string.h
Así como se puede ver, la diferencia es significativa.
Una cadena terminada nula (cadena c) es una matriz de caracteres, y el último elemento de la matriz es un valor 0x0. Std :: string es esencialmente un vector, ya que es un contenedor de cambio de tamaño automático para valores. No necesita un terminador nulo, ya que debe hacer un seguimiento del tamaño para saber cuándo se necesita un cambio de tamaño.
Honestamente, prefiero las cadenas c sobre las estándar, simplemente tienen más aplicaciones en las bibliotecas básicas, las que tienen un código y asignaciones mínimos, y las más difíciles de usar debido a eso.
- 1. Cadena terminada en nulo
- 2. Lectura de una cadena terminada en nulo
- 3. ¿std :: string :: c_str() siempre devuelve una cadena terminada en nulo?
- 4. ¿Cómo imprimo una cadena no terminada en nulo usando printf?
- 5. strlen() en cadena de caracteres no terminada en nulo?
- 6. Obtención de cadena terminada en nulo desde System.Text.Encoding.Unicode.GetString
- 7. ¿Cómo obtener una cadena terminada nula de una cadena C#?
- 8. Cadena terminada en cero doble
- 9. ¿Por qué cadenas terminadas en nulo? O: terminada en nulo vs almacenamiento de caracteres + longitud
- 10. ¿Cómo puedo convertir una cadena terminada en nulo en un buffer de byte a una cadena en Go? Este
- 11. ¿Hay un equivalente strtol que no requiera una cadena terminada en nulo?
- 12. Cómo imprimir una cadena terminada en nulo con líneas nuevas sin mostrar escapes de barra invertida en gdb?
- 13. Uso de printf con una cadena terminada no nula
- 14. ¿Cuándo es nulo Request.Form ["name"] y una cadena vacía?
- 15. ¿Por qué HttpContext.Current.Handler es nulo?
- 16. ¿Por qué SynchronizationContext.Current es nulo?
- 17. ¿Por qué HttpContext.Current.Session es nulo en Global.asax?
- 18. ¿Por qué es self.navigationController nulo en viewDidLoad?
- 19. ¿Por qué mi DbContext DbSet es nulo?
- 20. ¿Qué es nulo en C#, java?
- 21. /bin/sh: Error de sintaxis: cadena entrecomillada no terminada
- 22. ¿Por qué es legal agregar un valor nulo a una cadena?
- 23. javascript valor nulo en cadena
- 24. Encontrar el nulo en una cadena de invocación de método
- 25. AbrirArgs es error nulo
- 26. ¿Por qué mi user_id es nulo?
- 27. copia no terminada en nulo matriz de caracteres sin signo a std :: string
- 28. ¿Qué es un carácter nulo binario?
- 29. ¿Qué es una cadena de cultura
- 30. ¿Cómo comprobar si mi cadena es igual a nulo?
¿Qué es una cadena "habitual"? –
std :: string De todos modos, ya recibí una respuesta, gracias. – lhj7362