C++ Aritmética de punteros
Un puntero es una dirección representada por un valor numérico. Por lo tanto, se pueden realizar operaciones aritméticas sobre punteros. Se pueden realizar cuatro operaciones aritméticas con punteros: ++, --, +, -.
Supongamos queptres un puntero a entero que apunta a la dirección 1000, y es un entero de 32 bits; realicemos las siguientes operaciones aritméticas sobre este puntero:
ptr++
Después de ejecutar ptr++, el puntero ptr avanza 4 bytes y apunta a la dirección del siguiente elemento entero. Esto se debe a que la aritmética de punteros determina la distancia del desplazamiento según el tipo y el tamaño del puntero. En este caso, al ser un puntero a entero de 32 bits, cada entero ocupa 4 bytes, por lo que ptr++ mueve el puntero ptr 4 bytes hacia adelante y apunta a la dirección del siguiente elemento entero.
Siptrptr apunta a un carácter en la dirección 1000; al ejecutar ptr++, el valor del puntero ptr aumentará y apuntará a la dirección del siguiente elemento de carácter. Como ptr es un puntero a carácter, cada carácter ocupa 1 byte, por lo que ptr++ incrementará el valor de ptr en 1; después de la ejecución, ptr apunta a la dirección 1001.
Análisis detallado de la aritmética de punteros:
Suma: se puede realizar una suma con punteros. Cuando un puntero p se suma con un entero n, el resultado es que el puntero p avanza n veces el tamaño de un elemento. Por ejemplo, si p es un puntero de tipo int, y cada int ocupa 4 bytes, entonces p + 1 apuntará al siguiente elemento int al que apunta p.
Resta: se puede realizar una resta con punteros. Cuando un puntero p se resta con un entero n, el resultado es que el puntero p retrocede n veces el tamaño de un elemento. Por ejemplo, si p es un puntero de tipo int, y cada int ocupa 4 bytes, entonces p - 1 apuntará al elemento int anterior al que apunta p.
Resta entre punteros: se puede calcular la distancia entre dos punteros. Cuando se resta otro puntero q de un puntero p, el resultado es el número de elementos entre los dos punteros. Por ejemplo, si p y q son dos punteros de tipo int, y cada int ocupa 4 bytes, entonces p - q dará el número de elementos entre los dos punteros.
Comparación entre punteros y enteros: se pueden comparar punteros con enteros. Se pueden usar operadores relacionales (como <, >, <=, >=) para comparar punteros y enteros. Esta comparación se usa normalmente para determinar si un puntero apunta a una ubicación de memoria válida.
Incrementar un puntero
En C++, un puntero es una variable que almacena una dirección de memoria. Incrementar un puntero significa hacer que apunte a la siguiente ubicación de memoria, lo que normalmente significa apuntar al siguiente elemento de un arreglo. Incrementar un puntero ajusta automáticamente el valor del puntero según el tipo de dato al que apunta.
Por ejemplo, si un puntero apunta a un elemento de un arreglo de tipo int, incrementar el puntero hará que apunte al siguiente elemento int. A continuación se muestra un ejemplo sencillo que demuestra cómo incrementar un puntero:
Ejemplo
Cuando el código anterior se compila y se ejecuta, produce el siguiente resultado:
指针当前指向的元素: 10 递增指针后指向的元素: 20
En este ejemplo, el punteroptrinicialmente apunta al arreglo,arral primer elemento. Al ejecutarptr++, el punteroptrse incrementa para apuntar al siguiente elemento del arreglo (es decir, el segundo elemento).
Al incrementar un puntero, el valor del puntero aumentará en un desplazamiento igual al tamaño del tipo de dato al que apunta. Por ejemplo, si el puntero es de tipoint*int, cada incremento del puntero aumentará 4 bytes (suponiendo que el tipointint ocupa 4 bytes).
Es importante tener en cuenta que, al usar punteros, se debe asegurar que el puntero apunte a una zona de memoria válida; de lo contrario, se pueden producir comportamientos indefinidos o fallos del programa. Al operar con arreglos, se debe tener especial cuidado de evitar que el puntero sobrepase el límite del arreglo.
Decrementar un puntero
En C++, un puntero no solo se puede incrementar, sino también decrementar. Decrementar un puntero significa hacer que apunte a la ubicación de memoria anterior. Al igual que incrementar un puntero, decrementar un puntero también ajusta automáticamente su valor según el tipo de dato al que apunta.
A continuación se muestra un ejemplo sencillo que demuestra cómo decrementar un puntero:
Ejemplo
Cuando el código anterior se compila y se ejecuta, produce el siguiente resultado:
指针当前指向的元素: 20 递减指针后指向的元素: 10
En este ejemplo, el punteroptrinicialmente apunta al arreglo,arral segundo elemento. Al ejecutarptr--, el punteroptrse decrementa para apuntar al primer elemento del arreglo.
Al decrementar un puntero, el valor del puntero disminuirá en un desplazamiento igual al tamaño del tipo de dato al que apunta. Por ejemplo, si el puntero es de tipoint*int, cada decremento del puntero disminuirá 4 bytes (suponiendo que el tipointint ocupa 4 bytes).
Comparación de punteros
En C++, las operaciones de comparación de punteros se pueden usar para determinar si dos punteros apuntan a la misma ubicación, si la ubicación a la que apunta un puntero está antes o después de la de otro puntero, etc. La comparación de punteros incluye principalmente los siguientes tipos:
- Comparación de igualdad (
==y!=) - Comparación relacional (
<,<=,>,>=)
Comparación de igualdad
La comparación de igualdad se utiliza para comprobar si dos punteros apuntan a la misma ubicación.
Ejemplo
int main() {
int a = 10;
int b = 20;
int* ptr1 = &a;
int* ptr2 = &a;
int* ptr3 = &b;
// Comparar si los punteros son iguales
if (ptr1 == ptr2) {
std::cout << ptr1 y ptr2 apuntan a la misma ubicación << std::endl;
} else {
std::cout << ptr1 y ptr2 apuntan a ubicaciones diferentes << std::endl;
}
if (ptr1 != ptr3) {
std::cout << ptr1 y ptr3 apuntan a ubicaciones diferentes << std::endl;
} else {
std::cout << ptr1 y ptr3 apuntan a la misma ubicación << std::endl;
}
return 0;
}
Cuando el código anterior se compila y se ejecuta, produce el siguiente resultado:
ptr1 和 ptr2 指向相同的位置 ptr1 和 ptr3 指向不同的位置
Comparación relacional
La comparación relacional se utiliza para determinar si la ubicación a la que apunta un puntero está antes o después de la de otro puntero. Esto suele tener sentido cuando los punteros apuntan a elementos del mismo arreglo.
Ejemplo
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr1 = &arr[1]; // Apuntar al segundo elemento del arreglo
int* ptr2 = &arr[3]; // Apuntar al cuarto elemento del arreglo
// Comparar las posiciones relativas de los punteros
if (ptr1 < ptr2) {
std::cout << El elemento al que apunta ptr1 está antes del elemento al que apunta ptr2 << std::endl;
} else {
std::cout << El elemento al que apunta ptr1 no está antes del elemento al que apunta ptr2 << std::endl;
}
if (ptr2 > ptr1) {
std::cout << El elemento al que apunta ptr2 está después del elemento al que apunta ptr1 << std::endl;
} else {
std::cout << El elemento al que apunta ptr2 no está después del elemento al que apunta ptr1 << std::endl;
}
return 0;
}
Cuando el código anterior se compila y se ejecuta, produce el siguiente resultado:
ptr1 指向的元素在 ptr2 指向的元素之前 ptr2 指向的元素在 ptr1 指向的元素之后
Ejemplo completo de comparación de punteros:
Ejemplo
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr1 = &arr[1]; // Apuntar al segundo elemento del arreglo
int* ptr2 = &arr[3]; // Apuntar al cuarto elemento del arreglo
int* ptr3 = &arr[1]; // Apuntar al segundo elemento del arreglo
// Comparación de igualdad
if (ptr1 == ptr3) {
std::cout << ptr1 y ptr3 apuntan a la misma ubicación << std::endl;
} else {
std::cout << ptr1 y ptr3 apuntan a ubicaciones diferentes << std::endl;
}
if (ptr1 != ptr2) {
std::cout << ptr1 y ptr2 apuntan a ubicaciones diferentes << std::endl;
} else {
std::cout << ptr1 y ptr2 apuntan a la misma ubicación << std::endl;
}
// Comparación relacional
if (ptr1 < ptr2) {
std::cout << El elemento al que apunta ptr1 está antes del elemento al que apunta ptr2 << std::endl;
} else {
std::cout << El elemento al que apunta ptr1 no está antes del elemento al que apunta ptr2 << std::endl;
}
if (ptr2 > ptr1) {
std::cout << El elemento al que apunta ptr2 está después del elemento al que apunta ptr1 << std::endl;
} else {
std::cout << El elemento al que apunta ptr2 no está después del elemento al que apunta ptr1 << std::endl;
}
return 0;
}
Cuando el código anterior se compila y se ejecuta, produce el siguiente resultado:
ptr1 和 ptr3 指向相同的位置 ptr1 和 ptr2 指向不同的位置 ptr1 指向的元素在 ptr2 指向的元素之前 ptr2 指向的元素在 ptr1 指向的元素之后
Precauciones
Comparación dentro del mismo arreglo: La comparación relacional (como
<,>,<=,>=) tiene sentido cuando se realiza entre elementos del mismo arreglo. Si los punteros no pertenecen al mismo arreglo, el resultado de la comparación relacional no está definido.Puntero nulo: Antes de comparar punteros, asegúrese de que el puntero no sea un puntero nulo (
nullptr), de lo contrario, se puede producir un comportamiento indefinido.
Punteros en C++