面试题-指针-指针数组与数组指针

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chen1083376511/article/details/82720836

返回目录:https://blog.csdn.net/chen1083376511/article/details/82723709

问题:

问:int (*p)[n]与int *p[n]的区别?

答:

1.int (*p)[n]是数组指针,指向某n个元素所组成的整块的数组,返回值是整型指针类型的。

2.int *p[n]是指针数组,指向数组里面的每个元素,即p指向第一个元素,p[1]指向第二个元素,以此类推,p[n-1]指向第n-1个元素,返回值是整型的。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

问题:
问:下面代码的输出结果是什么?
void main()
{
 int arr[][3] = { 1, 2, 3, 4, 5, 6 };
 int(*ptr)[3] = arr;
 printf("%d %d\n",(*ptr)[0],(*ptr)[1]);
 ptr++;
 printf("%d %d\n", (*ptr)[0], (*ptr)[1]); 
}

答:1 2 4 5
分析:
int(*ptr)[3] = arr;指向整型数组的指针,数组包含3个元素,也就是说ptr这个指针指向包含了3个元素的一维数组,并且指向arr的首地址。
如果ptr++,ptr指向数组的下一个包含3个元素的一维数组。
小结:
int (*ptr)[n]指向int a[n]这整块数组。
详细分析,请看下一题。
-----------------------------------------------------------------------------------------------------------------------------------------------

问题:

问:下面代码的输出结果是什么?
void main()
{
 int arr[6] = { 1, 2, 3, 4, 5, 6 };
 int(*ptr)[6] = &arr;
 printf("%d,%d,%d,%d,%d,%d\n", (*ptr)[0], (*ptr)[1], (*ptr)[2], (*ptr)[3], (*ptr)[4], (*ptr)[5]);
 ptr++;
 printf("%d %d\n", (*ptr)[0]);

}
答:

1,2,3,4,5,6
-858993460(随机)

分析:

void main()
{
 int arr[6] = { 1, 2, 3, 4, 5, 6 };
 int(*ptr)[6] = &arr;//这里一定要用取地址符&,因为arr是int *类型的,而&arr是int (*)[6]类型的
 printf("%d,%d,%d,%d,%d,%d\n", (*ptr)[0], (*ptr)[1], (*ptr)[2], (*ptr)[3], (*ptr)[4], (*ptr)[5]);//(*ptr)[0]与*(ptr[0])结果相同
 ptr++;
 printf("%d %d\n", (*ptr)[0]);//不再指向arr数组。
}

根据上一面试题与这道题结合分析:

int (*ptr)[]是指向由整型数据组成的数组的指针,也就是说ptr指向的是整型元素的数组。

在二维数组当中:

假如int a[2][3]={1,2,3,4,5,6},ptr声明应为int (*ptr)[3]必须为3,因为在二维数组中,拆分为有两个一位数组,即a[2]和a[3],这里ptr指向必须是与后面a[3]保持一致,由此可得int (*ptr)[3]。ptr指向包含3个元素的一维数组。

注意:由于是二维数组,有a[2],即ptr可以自增指向下一个地址,原先ptr指向的是a[0]中包含3个元素的首地址(即&a[0][0])自增之后,ptr就指向了下一个a[1]中包含3个元素的首地址(即&a[1][0])。

一维数组中:

假如int a[6]={1,2,3,4,5,6},ptr声明应为int (*ptr)[6]必须为6,因为在一维数组中,ptr指向必须与a[6]保持一致.ptr指向包含6个元素的一维数组。

注意:ptr不能自增,因为ptr指针指向了包含6个元素的a数组地址.

ptr是数组指针,指向包含有一个或者一个以上元素的数组的地址。一个ptr对多个元素的数组。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

问题:

问:下面代码输出结果是什么?

    int map[2][3] = { { 10, 20, 30 }, { 40, 50, 60 } };
    int(*p)[3] =map;
    p++;
    cout<< **p << endl;
    cout<<*p << endl;
    cout<< *p + 1 << endl;
    cout<< *(*p + 1) << endl;

答:输出结果:40     0x0019FF34(内存地址)      0x0019FF38(内存地址)      50

分析:

    int map[2][3] = { { 10, 20, 30 }, { 40, 50, 60 } };
    int(*p)[3] =map;//如果int (*p)[3]=&map[1];那下一句的p++就可以省略掉
    p++;//指向map[1][0]~map[1][2]的数组段的地址
    cout<< **p << endl;//map[1][0]值
    cout<<*p << endl;//map[1][0]地址
    cout<< *p + 1 << endl;//map[1][1]地址
    cout<< *(*p + 1) << endl;//因为前面p++,所以一直指向第二个数组段,这里指第二个数组段的第二个元素 
 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

问题:

问:求下面代码的输出结果?

int(*p)[4];
    int a[4] = { 5, 66, 123, 589 };
    p = &a;
    cout << p << endl; //注意,p不等于p[0]    
    cout << "p[0]是a的地址:" << p[0] << "  a的地址:" << &a << endl;
    cout << "a[0]的内容:" << *(p[0]) << endl;
    cout << "a[1]的内容:" << *(p[0] + 1) << endl;

答:

0027F740
p[0]是a的地址:0027F740  a的地址:0027F740
a[0]的内容:5
a[1]的内容:66

-----------------------------------------------------------------------------------------------------------------------------------------------

问题:

问:下面代码的输出结果是什么?

void main()
{
 int arr[3] = { 1, 2, 3 };
 int* ptr[3];
 ptr[0]= &arr[0];
 ptr[1] = &arr[1];
 ptr[2] = &arr[2];
 printf("%d,%d,%d\n", *ptr[0], *ptr[1], *ptr[2]);
 ptr++;//正确吗?

}

答:1,2,3

分析:

void main()
{
 int arr[3] = { 1, 2, 3 };
 int* ptr[3];
 ptr[0]= &arr[0];
 ptr[1] = &arr[1];
 ptr[2] = &arr[2];
 printf("%d,%d,%d\n", *ptr[0], *ptr[1], *ptr[2]);//*ptr[0]与*(ptr[0])结果相同
 //ptr++;错误,不能自增
}

int* ptr[3]:由返回整型数据的指针所组成的数组 ,是指针数组,有3个成员,每个成员都是一个指针,共有3个指针,返回类型为int*。

ptr++错误,因为ptr是指针数组,有指向对象个数的限定,ptr++,就不知道指向哪个内存块了,反正不是数组arr[3]的内存块。

int *ptr[n]与int (*ptr)[n]区别:

第一点:
int (*ptr)[n]声明分析:ptr先与*结合,再与外面()结合,ptr是一个指针,又与[n]结合,ptr是指向数组的指针,指向的返回类型为int,所以ptr是一个指向整型数组的指针,即数组指针。

int * ptr[n]声明分析:ptr先与[n]结合,ptr是一个数组,数组返回类型为int*,意思是ptr是一个由整型指针的数组组成,数组里面的每一个元素都是整型指针,即指针数组。

第二点:

ptr[0]对应一个a[0]的地址,ptr[1]对应一个a[1]的地址,ptr[2]对应一个a[2]的地址。

int *a[n]用在一维数组的方法与直接变量赋值相同,例如:
 int *a[3];
 int m = 8, n = 4, x = 3;
 //a = &m;//错误, 
 a[0] = &m;
 a[1] = &n;
 a[2] = &x;

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
问题:

问:请输出下面代码的结果?

 int *a[3];
 int m[2][3] = { 9, 88, 55, 22, 44, 66};
 //a = &m;错误 
 a[0] = m[1];

 cout<<a<<endl; 
 cout<<a[0]<< endl;
 cout<<*a[0]<<endl; 
 cout<<*(a[0]+1)<<endl;

答:

0x0019FF34
0x0019FF28
22
44

分析:

 int *a[3];
 int m[2][3] = { 9, 88, 55, 22, 44, 66};
 //a = &m;错误 
 a[0] = m[1];//指定m[1]的一维数组 

 cout<<a<<endl; 
 cout<<a[0]<< endl;//a[0]是含有三个元素的m[1]的地址
 cout<<*a[0]<<endl; //*a[0]是含有三个元素的m[1]的m[1][0]首地址的内容
 cout<<*(a[0]+1)<<endl;//*(a[0]+1)是含有三个元素的m[1]的m[1][1]的值
 //cout<<"a+1是a[1],指针没有指向的地址:"<<**(a+1)<<endl;//出错 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

问题:

问:下面代码的输出结果是什么? 

#include<stdio.h>
void main()
{
 int arr[2][3] = { 1, 2, 3 ,4,5,6};
 int* ptr[1];
 ptr[0]= arr[1];
 printf("%d,%d\n", *ptr[0],ptr[0][2]);

答:4,6 

分析: 

void main()
{
 int arr[2][3] = { 1, 2, 3 ,4,5,6};
 int* ptr[1];
 ptr[0]= arr[1];//arr[1]首地址赋值给ptr[0]指针 
 printf("%d,%d\n", *ptr[0],ptr[0][2]);//ptr[0][2]是arr[1]中的第三个元素
}

int *ptr[n]的用法其实和int *ptr差不多。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

问题:

问:下面代码的各个值的输出结果是什么?

void main(){
 int** a;
 int *b[1];
 a = new int*[2];
 int m[3] = { 22, 33, 44 };
 int n[4] = { 4, 5, 6, 7 };
 a[0] = m; 
 a[1] = n; 
 b[0] = m;
 for (int i = 0; i < 3; i++)
 {
  cout << " a[0][i]是m[3]数组的第i个元素:" << a[0][i] 
   << "   和a[0][i]等价的是*(b[0] + i):" << *(b[0] + i) 
   << endl << endl; 
 }
}

答:

22 22 22

33 33 33

44 44 44

分析: 

void main(){
 int** a;
 int *b[1];
 a = new int*[2];//动态二维数组
 int m[3] = { 22, 33, 44 };
 int n[4] = { 4, 5, 6, 7 };
 a[0] = m; // 等价于*a = m;  
 a[1] = n; // 等价于*(a+1) = n;  
 b[0] = m;// b[0]和a[0]运用效果一样的,但是类型不一样。b[0]是int *b[0],而a[0]是int **a. 
 for (int i = 0; i < 3; i++)
 {
  cout << " a[0][i]是m[3]数组的第i个元素:" << a[0][i] 
   << "   和a[0][i]等价的是*(b[0] + i):" << *(b[0] + i) 
   << endl << endl; 
 }
}

该题的代码是动态二维数组,就是在堆上开辟一块内存,然后赋值给二级指针,使用的方法类似于int *a[n]。

猜你喜欢

转载自blog.csdn.net/chen1083376511/article/details/82720836