c++中的数组元素指针,指针数组,字符数组和字符串指针变量

数组元素指针

数据元素的指针变量用来保存数组元素的地址
可以保存任意一个元素的地址

int arr[5] = {0,10,20,30,40};
int *p;

p = &arr[0];// 指向第0个元素
p = &arr[3];// 指向第3个元素
p = arr; // 指向第0个元素

重点

数组元素的指针变量和数组名等价,如果直接cout数组名,其结果也是地址。
也就是说 arr = &arr[0]? 或者 arr[1] = *(p+1)!!!

为什么呢?为什么arr = &arr[0]?
&arr[0] == &*(arr+0) == arr+0 == arr

void test01()
{

    int arr[5] = {0,10,20,30,40};
    int *p;
//    p = &arr[0];
    p = arr;// arr本身就是地址,所以不需要取地址操作,这样的结果就是数组元素的指针变量和数组名等价

    cout << arr << endl;// 如果直接对arr进行输出,输出的是地址
    cout << arr[0] << endl;
    cout << p << endl;
    cout << *(p+1) << endl;// 当数组指针p指向的类型是int的时候,+1代表了跳过4个字符,正好到了下一个元素。因此p+1就直接代表下一个内容
    cout << "arr[1] = " << arr[1] <<endl;
    cout << "*(arr + 1) = " << * (arr +1) <<endl;
    
    // 当指针指向的变量类型与数组的类型一致时就符合,不一致时强转也不符合
	short arr_2[5] = {5,15,25,25,45};
    int *p_2;
    p_2 = (int *)arr_2;

    cout << arr_2[1] << endl;// 如果直接对arr进行输出,输出的是地址
    cout << *(p+1) << endl;
}

再做一下总结,地址一定是4字节的,一个变量/数组可能是int(4字节), short(2字节),char(1字节). 指向变量的指针变量的大小一定是4字节. 所以指针变量可以用void定义,而变量不可以。
int *p中 int *是指针变量自身的类型,而int是指针变量指向的类型。
由于指针变量只指向变量的第一个字节,并且指针变量指向的类型决定指针变量能跳的宽度,如果指针变量是int型,那么p+1就跳4个字节。

同样在数组元素指针中,指针变量指向一个数组的第一个元素的的地址,指针变量指向的类型决定能跳到哪一个元素。
而指针数组是一个数组,里面的每个元素都是一个指针变量,取出来每一个指针数组的元素后,需要取*后才能获得该指针变量指向的变量内容

指针数组是一个数组,只不过元素都是地址

指针数组的首元素地址,数组的首地址和数组指针

数组首元素地址: &arr[0] == arr arr+1跳过一个元素
数组的首地址:&arr &arr+1跳过整个数组

数组指针本质是指针变量,保存的是数组的首地址
定义 int (*p)[5]
两个定义的区别 int *p[5] 和 int (*p)[5],前者是指针数组,后者是数组指针
int *p[5], 先是数组,然后是 * 指针,反过来读就是指针数组
int (*p)[5] 由于()优先级高,所以p指针,然后是[]数组,反过来读就是数组指针

void test01()
{
    // 数组指针
    int arr[5] = {10,20,30,40,50};
    int (*p)[5] = &arr;
    int *a = NULL;
    // 如果想取30整个数据,首先要拿到首元素地址 因为p = &arr, 所以*p = *&arr,也就是首元素地址
    a = (*p+2);
    cout << *a << endl;
    cout << p+1<< endl;

    // 数组元素指针
    int *p2 = arr;
    cout << *(p2+2) << endl;
    cout << p2+5 << endl;// 这里可以看到 数组指针+1 和 数组元素指针+5是相同的 (我是64位)
}

对二维数组的深入解析

int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 这是一个常规的二维数组定义
arr代表首地址的话,则代表第0行第一个元素的首地址,而arr+1代表第一行第一个元素的首地址,arr+2代表第二行第一个元素的首地址。
*(arr+1) +2 代表第一行第二列的元素的的地址,注意对行地址取✳代表当前行第0列的地址

因此 *(*arr+1)+2 = arr[1][2]
[num]可以替换变成✳( +num)!!!

一维数组指针和二维数组是完全等价的的
n维数组 和n-1位的数组指针等价

字符串与指针

字符串指针变量和字符数组的区别
char str1[128]=“hello world”;
字符数组是正儿八经开辟了空间,也就是"hello world"是放在栈区或全局区的
char *str2=“hello world”;
字符串指针的"hello world"是放在文字常量区的,而地址是放在栈区/全局区的

void test03()
{

    char *str2 = "hello world";
    cout << str2 << endl; // 输出 hello world str2会从指针指向的位置开始,一直读取到字符串结束的位置(具体为什么我也不太清楚)
    cout << *(str2+1)<<endl; //输出 e, 表示对字符串数组的第二位进行取值

}

void test04()
{
    char num1[4] = "abc";
    char num2[4] = "def";
    char num3[4] ="ghi";
    char num4[4] = "jkl";
    char num5[4] = "mno";

    char *arr[5]={num1,num2,num3,num4,num5};// 首先是数组,有5个元素,5个元素是char *,这个是一个数组元素指针,不知道理解的对不对
    char *arr_2[5]={"ab","cd","ef","hi","gh"};// 这个是字符串指针变量
    cout << arr <<endl;// 输出地址 因为是数据元素指针,所以输出地址
    cout << arr_2[1] <<endl;//结果是cd 这个是指向字符串数组的第一位,而如上面所说,有第一位就可以一直去读的字符串结束
    cout << *(arr_2[1]+1) <<endl;//结果是d // 这个是指向字符串数值第一位,并且对第一位后的以为进行取值(*)
}
}

字符串指针数据:也是数组,只是元素是字符串。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值