C/C++中指针是非常重要的,在前面我帮助大家系统的认识了下指针,但是在实际开发中仅仅依靠这些指针知识是远远不够的,这篇文章就带大家来了解了解二级指针的用法以及对其的认识。接下来在这段代码来了解了解二级指针。
void printArray(int **arr,int len)
{
for (int i = 0; i < len; ++i)
{
printf("%d ",*arr[i]);
}
}
在这里先给大家介绍一下数组指针和指针数组。
指针数组就是一个数组中存储的为指针变量或者指针常量。例如下面这段代码:
int p = 1, q = 2;
int *m = &p;
int *n = &q;
int a[2] = { *m,*n };
cout << a[0] << "," << a[1] << endl; //1,2
return 0;
a这个数组中存储的为指针常量,因此叫指针数组。还有另一种为数组指针,顾名思义,是指针类型的数组。例如下面的代码:
int test1[3] = { 1,2,3 };
int test2[4] = { 5,6,7,8 };
int *p[2] = { &test1[2],&test2[3] };
cout << **p << endl;
//先定义数组类型,在定义数组指针类型
int a[5] = { 1,4,7,99,67 };
typedef int(ARRAY_TYPE)[5];
ARRAY_TYPE myarray;
for (int i = 0; i < 5; i++)
{
myarray[i] = 100 + i;
}
for (int i = 0; i < 5; i++)
{
cout << myarray[i] << ",";
}
//对数组名取地址则代表获得指向整个数组的指针
ARRAY_TYPE *p_aray = &myarray; //获得指向myarray首元素的指针,因此可以取到数组的每一个元素
printf("*(*p_array + 1) = %d", *(*p_aray + 1));
p_aray = &a;
printf("*(*p_array + 1) = %d", *(*p_aray + 1));
typedef int(*ARR_PIONEER)[5]; //直接定义数组指针类型
ARR_PIONEER pioneer = &a;
int(*pioneerarr)[5] = &a;
printf("\n");
cout << *(a+1) << endl;
cout << **pioneer << endl;
cout << *(*pioneerarr + 1) << endl;
这段代码即为指针类型的数组,即为数组指针。p为储存两个指针的数组,在这里可以将数组看作是具有连续地址的指针。因此这两个指针为test1[2]和test2[3]这两个指针。因此对p采用两个解引用可以得到3.这里对p一级解引用得到*p的第一个元素,即为test1[2]的地址,再对其解引用就可以得到test1[2]指向的值,即为3.
那么问题来了,如何更通俗的理解二级指针,在这里我提供一种思路,即将二级指针看作是数组指针,即第二次解引用看作是取出数组指向的值,第一次解引用看作是取出该指针指向的地址。总体来说是获得指针指向的数组的值。这便是二级指针理解的一种思路。接下来通过一些练习来更深入的了解二级指针。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//获得文件行数
int getFileLines(FILE *file)
{
if (NULL == file)
{
return -1;
}
char buf[1024] = { 0 };
int lines = 0;
while (fgets(buf, 1024, file) != NULL)
{
++lines;
}
//恢复文件指针指向文件起始位置
fseek(file,0,SEEK_SET);
return lines;
}
//读取文件数据
void readFileData(FILE *file, int lines, char ** contents)
{
if (NULL == file)
{
return;
}
if (NULL == contents)
{
return;
}
if (lines <= 0)
{
return;
}
//创建缓冲区
char buf[1024] = { 0 };
int index = 0;
while (fgets(buf,1024,file) != NULL)
{
//printf("buf:%s", buf);
int curLineLen = strlen(buf) + 1;
//给当前行分配内存
char *lineContent = malloc(sizeof(char)* curLineLen);
//将行数据拷贝到空间中
strcpy(lineContent, buf);
contents[index++] = lineContent;
memset(buf, 0, 1024);
}
}
void showFileContents(char **contents,int lines)
{
for (int i = 0; i < lines; ++i)
{
printf("%d行:%s",i + 1,contents[i]);
}
}
//释放文件数据内存
void freeFileSpace(char **contents, int lines)
{
for (int i = 0; i < lines; ++i)
{
if (contents[i] != NULL)
{
free(contents[i]);
contents[i] = NULL;
}
}
free(contents);
contents = NULL;
}
void test()
{
//打开文件
FILE *file = fopen("./text.txt","r");
if (NULL == file)
{
printf("打开文件失败!\n");
return;
}
//统计文件行数
int lines = 10;
lines = getFileLines(file);
printf("lines:%d\n", lines);
char **pContents = malloc(sizeof(char *)* lines);
//读取文件内容
readFileData(file, lines, pContents);
//关闭文件
fclose(file);
file = NULL;
//打印文件内容
showFileContents(pContents, lines);
//释放文件数据
freeFileSpace(pContents, lines);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
因此,我通过将数组和指针联系在一起来更通俗的理解二级指针,但是二级指针不仅仅是这种关系,二级指针也是一种对指针的更深入的利用,将常量换成指针量,对指针进行取地址。因此,给大家开个头,接下来大家有兴趣的可以继续钻研。
最后,如果这篇文章中有些不正确的地方,欢迎大家批评指正。也可以留言与我共同探讨二级指针的应用。