这是个人学习总结,如果有不合理的地方请大家不吝赐教
主要参考资料:
http://c.biancheng.net/view/2020.html https://blog.csdn.net/u013684730/article/details/46565577 https://blog.csdn.net/daiyutage/article/details/8604720
backgrond: 关于指针数组的重新认识,是在我想用二维数组存储多段字符串时, 发现二维数组大小不好分配,后来在网上参考大佬解法时发现指针数组在这方面的优越性,当然二重指针按道理也行,下回再学习一下。
A small thought: int* a[100],char* ch[100]我一直在想它们与普通数组有什么联系, 下表横向对比int a[100], char ch[100]。
| 特点 |
---|
int *a[100] | 存储(int型数据)地址的数组 | int a[100] | 存数字的憨憨,与int *a相互对应,但存储空间不同 | char *a[100] | 存100段字符串的首地址,注意与字符串本身不在同一个区域存储 | char a[100] | 只能存一段字符串 |
这里就又要展开说一下,我就把(int,int*)和(char,char*)分两类理解: 1.初始化(不叫赋值,c++primer做过区分) int *a[2]={&b,&c};这样十分容易理解,然后 char *a[2]={“abc”,“abcxx”};嘿嘿,就这么简单。
2.输出 char* 虽然可以直接写成这种printf("%s\n%s\n", a[0],a[1]) ;但要记住a[0],a[1]里存的是地址,不是字符串本身,这种情况的发生是默认首地址自动输出该地址对应的字符串 对比一下其他类型的输出写法就能明显感觉到char型真NB,毕竟别人是全自动 例:int*输出 printf("%d, %d\n", *a[0], *a[1]);还要亲手通过地址带到门口,benB
------------补充-------------------- 关于二维数组和二重指针的问题,我结合前面大佬的解释说一下:
#include<iostream>
using namespace std;
int main()
{
int a[2][3]={1,2,3,4,5,6};
int **p;
int *f[2]={&a[0][0],&a[0][1]};
p=(int **)malloc(sizeof(int**));
*p=a[0];
cout<<*(*(p+0)+1)<<endl;
cout<<*f[0]<<*f[1]<<endl;
return 0;
}
我们结合代码分析一波,
1.a为二维数组,p是二重指针,f为指针数组; 2.使用p一定要给它分配一个地址:
p=(int **)malloc(sizeof(int**));
不然你试试不写这步会输出不了,因为p地址是无效的; 3.后面就是老生常谈的了*(*p+1) ,可以这样理解,*p+1 意味着偏移一个内存地址,于是乎就从a[0][0] 变成了a[0][1] 的地址,因为二维数组连续存储(类似一维数组)的原因,如果你想得到比如a[1][2] 就要变成*p+5 ; 4.这一点很重要,平时我们可能会石乐志得写出这种:
#include <iostream>
using namespace std;
#define ROW 2
#define COL 3
void myputs(char **pos);
int main()
{
char **p;
char a[ROW][COL] = {"abc", "def"};
p = a;
myputs(p);
return 0;
}
void myputs(char **pos)
{
int i, j;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
cout << pos[i][j];
cout << endl;
}
}
这里参考了佬的解释:
https://blog.csdn.net/u013684730/article/details/46565577
这种会报错,原因是因为二维数组与二重指针内存分配不同,一个是连续的,另一个就是要分行列。 改正方法一: 指针数组,这里因为字符串自带NB,本身就是地址(详见上文),可直接用字面值初始化,不用像上面的int型那么复杂 改正方法二: 比较好理解,就是传入参量改为二维数组,与p赋值类型一致
|