2012-04-03 19 views
26

cito "El Lenguaje de Programación C" de Kernighan & Ritchie:== para la comparación puntero

Cualquier puntero se puede comparar de manera significativa por la igualdad o desigualdad con cero. Pero el comportamiento no está definido para la aritmética o las comparaciones con punteros que no apuntan a miembros de la misma matriz. (Hay una excepción: la dirección del primer elemento más allá del final de una matriz se puede utilizar en la aritmética de punteros.)

¿Esto significa que no se puede confiar en == para comprobar la igualdad de las diferentes punteros? ¿Cuáles son las situaciones en las que esta comparación conduce a un resultado incorrecto?

+0

Si tiene diferentes tipos de punteros y tienen el mismo valor, apuntan a la misma dirección de memoria y es posible que tenga un pequeño problema. Pero de todos modos, generalmente es correcto comparar los punteros si está absolutamente seguro de que el diseño de la memoria es completamente lineal. De lo contrario, no. Piense en un 8086. –

Respuesta

0

No puede usar la comparación de punteros para comparar punteros que apuntan a diferentes matrices.

Así:

int arr[5] = {1, 2, 3, 4, 5};

int * p = &arr[0];

int anotherarr[] = {1, 2};

int * pf = &anotherarr[0];

No se puede hacer desde if (p == pf)p y pf no apuntan en la misma array Esto conducirá a un comportamiento indefinido.

Puede confiar en la comparación de punteros si apuntan dentro de la misma matriz.

No estoy seguro acerca de la caja aritmética.

2

interpreto esto como siguiente:

short a[9]; 
int b[12]; 
short * c = a + 9; 

Aquí es válido decir que

c > a 

porque c resultados de a a través de la aritmética de punteros,

pero no necesariamente que

b == c 

o

c <= b 

o algo por igual, ya que son el resultado de diferentes matrices, cuyo orden y alineación en la memoria no está definido.

8

El operador de igualdad se define para todos los punteros válidos, y el único momento en que puede dar un "falso positivo" es cuando un puntero apunta a un elemento más allá del final de una matriz, y el otro al punto (o puntos en virtud de una definición de estructura) a otro objeto almacenado justo después de la matriz en la memoria.

Creo que su error es tratar K & R como normativo. Consulte el estándar C99 (buena versión html aquí: http://port70.net/~nsz/c/c99/n1256.html), 6.5.9 en el operador de igualdad. El problema de que las comparaciones no se definan solo se aplica a los operadores relacionales (ver 6.5.8):

Cuando se comparan dos punteros, el resultado depende de las ubicaciones relativas en el espacio de direcciones de los objetos apuntados. Si dos punteros a objetos o tipos incompletos apuntan al mismo objeto, o ambos señalan uno pasado el último elemento del mismo objeto de matriz, se comparan iguales. Si los objetos apuntados son miembros del mismo objeto agregado, los punteros a los miembros de estructura declarados posteriormente comparan mayor que los punteros con los miembros declarados anteriormente en la estructura, y los punteros a los elementos de matriz con valores de subíndices más grandes comparan mayor que los punteros a elementos de la misma matriz con valores de subíndice más bajos Todos los apuntadores a miembros del mismo objeto de unión se comparan iguales. Si la expresión P apunta a un elemento de un objeto de matriz y la expresión Q apunta al último elemento del mismo objeto de matriz, la expresión de puntero Q + 1 se compara mayor que P. En todos los demás casos, el comportamiento no está definido.

+0

Tenga en cuenta que ISO/IEC 9899: 1990 no especifica el resultado al comparar un puntero de función con un puntero de objeto. –

+8

-1 Usted declara que * "El operador de igualdad se define para todos los punteros válidos" *, luego cita la sección de la norma que dice exactamente lo contrario * (tenga en cuenta que dice que la igualdad se evalúa como verdadera si ambos apuntan al mismo objeto ; no ** dice ** que la igualdad es falsa si apuntan a objetos diferentes) *. –

+2

+1: primera respuesta para hacer referencia a una especificación. Danny, creo que estás confundido: el pasaje citado es sobre comparación relacional, no comparación de igualdad. La sección sobre el operador de igualdad dice: "Dos punteros se comparan igual si y solo si ... ambos son punteros al mismo objeto ...". Esta debería ser la respuesta aceptada. – chazomaticus

31

Un ejemplo que me viene a la mente es la arquitectura de Harvard con espacios de direcciones separados para el código y para los datos. En las computadoras de esa arquitectura, el compilador puede almacenar datos constantes de en la memoria de códigos. Dado que los dos espacios de direcciones están separados, un puntero a una dirección en la memoria de código podría ser numéricamente igual a un puntero en la memoria de datos, sin apuntar a la misma dirección.

+0

Esta respuesta podría reformularse como "en compiladores C que no se adhieren al estándar ISO C". – chazomaticus

+2

Esta respuesta es irrelevante para C ya que los punteros de objetos y funciones no son directamente comparables, y dado que la conversión entre ellos no está definida. No hay una forma significativa de comparar un puntero de función con un puntero de objeto sin hacks específicos de implementación. Y como ha señalado chazomaticus, es imposible para un compilador de una arquitectura de Harvard almacenar datos en el segmento de código. –

+0

@R .. A principios de los años noventa trabajé con un compilador C [8051] (http://en.wikipedia.org/wiki/Intel_MCS-51) que le permitía colocar constantes en la memoria * code *. No recuerdo si requirió una extensión de compilación o simplemente declarar que una matriz de const lo haría, pero recuerdo que puedo obtener 'char *' y 'const char *' apuntando a * diferentes * tipos de memoria. También había un tipo especial de puntero que le permitía apuntar a un tipo de memoria u otra en tiempo de ejecución, pero requería tres bytes en lugar de los dos habituales. Esto fue hace un tiempo, el estándar estaba en C89 en el mejor de los casos. – dasblinkenlight

-2

Puede hacer == y != con punteros de diferentes matrices.

<, < =,>,> = no está definido.

Cuestiones relacionadas