C++基础概念:指针与数组,指针运算,指针与机器物理地址

C++基础概念:指针与数组,指针运算,指针与机器物理地址

编码文章call10242024-12-13 11:58:4751A+A-

关键字:指针,数组,指针与数组,指针运算,标准库函数begin和end;

指针与数组:

在C++中,指针与数组有着非常紧密的联系。

在使用数组的时候,实际上编译器会把它转化成指针。

数组还有一个特性:编译器会自动将数组名字替换为一个指向数组首元素的指针。

string StringArray[10] = {"A1", "A2", "A3","A4", "A5", "A6", "A7", "A8", "A9", "A10" } ;
string *p = StringArray;// 等价于 p = &StringArray[0]

所以在C++中,数组操作就是指针操作。

所以这几个做法是等价的:

1.

 
 for (int i=0; i < 10 ; ++i ) {
 cout << StringArray[i] << " " ;
 }

2.

string *ArrayEnd = end(StringArray) ;
 for (string *p = StringArray ; p < ArrayEnd; ++p ) {
 cout << *p << " " ;
 }

3.

 string *ArrayBegin = StringArray;
 for (int i=0 ; i < 10 ; ++i ) {
 cout << *(ArrayBegin + i) << " " ;
 }

4.

 for (int i=0 ; i < 10 ; ++i ) {
 cout << ArrayBegin[i] << " " ;
 }


指针运算:

指针是可以进行比大小,加减一个整数,自增,自减,互相减等运算的。

注意:这些都只能在同类型的指针之间进行

1. 两个同类型的指针变量,可以比较大小

  • 地址p1< 地址 p2, p1< p2 值为真。
  • 地址p1= 地址 p2, p1== p2 值为真
  • 地址p1> 地址 p2 ,p1 > p2 值为真

2. 两个同类型的指针变量,可以相减

  • 两个T * 类型的指针 p1 和 p2
  • p1 - p2 = ( 地址 p1 - 地址 p2 ) / sizeof(T)

注意两个指针相减的结果并不是两指针所在的物理地址相减。

C++是强数据类型的,编译器会根据指针指向的变量的类型,做相应调整。

所以两个整形指针相减的结果是实际物理地址的差值然后再除以4。

3.指针变量加减一个整数的结果是指针

  • p: T * 类型的指针
  • n: 整数类型的变量或常量
  • p+n: T * 类型的指针,指向地址: p + n × sizeof(T)

4.指针变量可以自增、自减

  • T* 类型的指针 p 指向地址 n
  • p++,++p : p 指向 n + sizeof (T)
  • p--,--, p : p 指向 n - sizeof (T)

5. 指针可以用下标运算符 “[ ]”进行运算

  • p是一个 T * 类型的指针,
  • n是整数类型的变量或常量
  • p[n] 等价于 *(p+n)


指针与机器物理地址:

指针可以理解为一种数据类型,是与它所指向的变量的类型强相关的;

所以指针变量并不完全等于它的机器物理地址的值

所以指针的+,-, ++, --与其机器地址的+,-, ++, --是不一样的。

string * 类型的指针 ArrayBegin进行加1操作后,实际的物理地址增加了32, 也就是string的字节数。

ArrayBegin: 	0x7ffc061df210
ArrayBegin +1 :	0x7ffc061df230

如果要得到指针的实际物理地址,

在C++中可以采用强制类型转化

把指针转化成long long类型的整数地址;

long long intAttrayBegin_address = (long long) intArrayBegin ;


示例代码中的其他细节:

在cout中可以用hex直接把指针用16进制数输出,对应的就是其编译后的实际物理地址。

把指针强制转化为整数要用long long类型;如果用int,可能会有溢出,导致编译错误。

可以用标准库函数begin和end,取数组的首元素的地址,和最后一个元素的地址的后面一个地址。

其他细节请直接查看源代码。


程序源代码:

#include <iostream>
#include <string>
#include <iterator>
using namespace std;

int main ()
{
 string StringArray[10] = {"A1", "A2", "A3","A4", "A5", "A6", "A7", "A8", "A9", "A10" } ;

 string *ArrayEnd = end(StringArray) ;
 for (int i=0; i < 10 ; ++i ) {
 cout << StringArray[i] << " " ;
 }
 cout << endl;

 for (string *p = StringArray ; p != ArrayEnd; ++p ) {
 cout << *p << " " ;
 }
 cout << endl;

 for (string *p = StringArray ; p < ArrayEnd; ++p ) {
 cout << *p << " " ;
 }
 cout << endl;

 string *ArrayBegin = StringArray;
 for (int i=0 ; i < 10 ; ++i ) {
 cout << *(ArrayBegin + i) << " " ;
 }
 cout << endl;

 for (int i=0 ; i < 10 ; ++i ) {
 cout << ArrayBegin[i] << " " ;
 }
 cout << endl;

 cout << "size of string is:" << sizeof(string) << endl ;
 cout << "ArrayBegin:"<< "\t" << hex << ArrayBegin << endl ;
 cout << "ArrayBegin +1 :"<< "\t" << hex << (ArrayBegin +1 ) << endl ;

 int intArray[] = {11, 12} ;
 int *intArrayBegin = intArray;
 cout << "size of int is:" << sizeof(int) << endl ;
 cout << "intArrayBegin:"<< "\t\t" << hex << intArrayBegin << endl ;
 cout << "intArrayBegin +1 :"<< "\t" << hex << (intArrayBegin +1 ) << endl ;
 int *intArrayEnd = end(intArray);
 cout << "intArrayEnd - intArrayBegin =" << (intArrayEnd - intArrayBegin) << endl ;

 long long intAttrayBegin_address = (long long) intArrayBegin ;
 cout << "intAttrayBegin_address = " << hex << intAttrayBegin_address << endl ;
 long long intAttrayEnd_address = (long long) intArrayEnd ;
 cout << "intAttrayEnd_address - intAttrayBegin_address = " << intAttrayEnd_address - intAttrayBegin_address << endl ;

 return 0 ;
}

输出结果:

A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
size of string is:32
ArrayBegin: 	0x7ffc061df210
ArrayBegin +1 : 0x7ffc061df230
size of int is:4
intArrayBegin: 	   0x7ffc061df208
intArrayBegin +1 : 0x7ffc061df20c
intArrayEnd - intArrayBegin = 2
intAttrayBegin_address = 7ffc061df208
intAttrayEnd_address - intAttrayBegin_address = 8
点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4