C/C++でポインタを比較する方法とは?基本と注意点を解説
ポインタの比較とは
ポインタは、同じ配列を指している場合に意味のある比較を行うことができます。比較には <、>、<=、>= といった関係演算子を使用します。なお、ポインタ同士を掛けたり割ったりすることはできません。
C言語でのポインタ比較の例
#include <stdio.h>
int main() {
int *p2;
int *p1;
p2 = (int *)300;
p1 = (int *)200;
if(p1 > p2) {
printf("P1 is greater than p2");
} else {
printf("P2 is greater than p1");
}
return(0);
}
実行結果
P2 is greater than p1
C++でのポインタ比較の例
#include <iostream>
using namespace std;
int main() {
int *p2;
int *p1;
p2 = (int *)300;
p1 = (int *)200;
if(p1 > p2) {
cout << "P1 is greater than p2";
} else {
cout << "P2 is greater than p1";
}
return(0);
}
実行結果
P2 is greater than p1
この例では、p1 にアドレス値 200、p2 にアドレス値 300 を代入しているため、「p2 のほうが p1 より大きい」と判定されています。このように、ポインタが保持するアドレス値を関係演算子で比較することができます。
ポインタ比較に関する重要ポイント
同じ対象を指す場合: 同じ型の2つのポインタ p1 と p2 が、同一のオブジェクトまたは同一の関数を指している、同じ配列の末尾の次の位置を指している、あるいは両方がヌルポインタである場合、
p1<=p2とp1>=p2はどちらも真となり、p1<p2とp1>p2はどちらも偽となります。無関係な対象を指す場合: 同じ型の2つのポインタ p1 と p2 が、同一オブジェクトのメンバーでも同一配列の要素でもない別々のオブジェクトや別々の関数を指している場合、または片方だけがヌルポインタである場合、
p1<p2、p1>p2、p1<=p2、p1>=p2のいずれの結果も未規定(unspecified)となります。同じアクセス制御のメンバーの場合: 2つのポインタが同じオブジェクトの非静的データメンバー、またはそのメンバーのサブオブジェクトや配列要素を指していて、両者が同じアクセス制御を持つ場合、比較結果は規定されます。
異なるアクセス制御のメンバーの場合: 2つのポインタが同じオブジェクトの、アクセス制御が異なる非静的データメンバーを指している場合、比較結果は未規定となります。
まとめ
ポインタの比較は、同じ配列内の要素や同一オブジェクトに関連するポインタ同士であれば安全に行えます。一方、互いに無関係なメモリ領域を指すポインタ同士の比較は未規定動作となるため、移植性の高いコードを書く際には注意が必要です。ポインタ比較の挙動を正しく理解し、適切な場面でのみ使用するようにしましょう。
-
C/C++で文字列がint(整数)かどうかを判定する方法
C/C++で文字列が整数(int)として妥当かどうかを判定する方法はいくつかあります。その中でも手軽なのが、標準ライブラリのisdigit()関数を使って文字列を1文字ずつチェックする方法です。ここでは、C++で文字列が整数を含んでいるかどうかを判定する具体例を紹介します。サンプルコード#include<iostream> #include<string.h> using namespace std; int main() { char str[] = "3257fg"; for (int i = 0; i < strlen
-
C++でfloatとdoubleを比較する方法|許容誤差(EPSILON)を使った実装例
C++においてfloat型やdouble型などの浮動小数点数を比較する方法は、最終的に何を実現したいかによって異なります。浮動小数点数は内部で2進数の近似値として表現されるため、「==」演算子による単純な等価比較では意図しない結果になることがあります。そこで一般的には、許容できる誤差(イプシロン)を設定し、その範囲内であれば同じ値とみなす手法が用いられます。 理論面に深入りしすぎず、すぐに使える関数が必要で、多少の計算誤差が許容できる場合は、以下のような関数が便利です。 サンプルコード #include<iostream> using namespace std; // 許容でき