栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言学习笔记【02】——指针及其本质(二)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言学习笔记【02】——指针及其本质(二)

指针操作数组 指针操作一维数组

在介绍之前,我们先了解一下关于数组名的知识。

数组名

代表这段内存首地址

回忆一下指针的定义,这数组名不就是指针吗,我们试着操作一下

int array[3]={1,2,3};
for(int i=0;i<3;i++)
    {
        printf("%dt%dn",array[i],*(array+i));
    	printf("%pt%pn",&array[i],&*(array+i));
    }

 可以看到,数据和地址都一致。

//对于array(数组名)
//正常操作: 直接存储数组的首地址
//直接把指针当作数组名就可以了
//非正常操作:指向其他元素开始操作数组

所以,对应指针(一级指针)也可以操作数组

int array[3]={1,2,3};
int* p=array;
for(int i=0;i<3;i++)
{
    printf("%dt",p[i]);//对于这种方法我比较推荐,好理解,也可以用指针偏移
    //printf("%dt",*(p+i));
}
ptintf("n");

*p等效于p[0] 取当前地址对应内存中的值

 但是数组名的地址是不能更改的,这也是与指针的区别

	int test[3] = { 1,2,3 };
	int* pT = &test[2];
	printf("%dn", pT[0]);//指针的[0]并不指数组第几个元素
	printf("%dn", pT[-1]);//pT[-1]等效于*(pT-1)
	printf("%dn", pT[1]);//未知量,垃圾值

指针操作二维数组

一级指针操作二维数组

二维数组(举例为array[2] [3])在内存中是连续的,而二维数组的数组名是个数组指针(数组指针的首地址)。

对于每行的首地址为数组名[i],例: array[i]

使用数组名的偏移方式与一维数组不太一样

光看着可能不太明白,我们直接操作

int array[2][3]={1,2,3,4,5,6};
int* p=&array[0][0];

printf("%pn",array);
printf("%pn",&array[0][0]);
printf("%pn",array+1);
printf("%pn",p+1);

 粗略分析一下

array与&array[0] [0]输出的值相同,即两者地址相同

(array+1)-array 的值为C(0x64-0x58=0xC,转十进制为12,即12个字节),正好是一行元素所占字节数

同理,p+1对于p(即array[0] [0]) 偏移了4个字节(0x5c-0x58=0x4)

所以对于二维数组不能直接用数组名赋给一级指针

直接点就是,有几个元素就加几

array[i] [j]==*(p+n) (n=i *每行元素个数+j)

for(int i=0;i<6;i++)
{
    printf("%dt",*(p+i));
}
printf("%dn",array[1][2]);
printf("%dn",*(p+(1*3+2)));

 

数组指针操作二位数组

数组指针

指向数组的指针

定义时,括号不能少

只要指向首地址,可以直接当作数组名使用

int array[2][3]={1,2,3,4,5,6};
int (*pArray)[3]=NULL;//(*pArray)可以理解为数组名
pArray=array;
for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%dt", pArray[i][j]);
		}
		printf("n");
	}

 还有不一样的用法(不推荐)

for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%dt", *(*(pArray + i) + j));//或者printf("%dt",*(pArray[i]+j));
            //printf("%dt",*((pArray+i)[0]+j));
            //printf("%dt",((pArray+i)[0]+j)[0]);
        }
    printf("n");
	}

 数组指针也可以作为函数参数

void printArray(int (*p)[3],int row,int col)
//等效void printfArray(int p[][3],int row,int col)
{
    for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf("%dt", p[i][j]);
		}
		printf("n");
	}
}

指针数组

指针数组也可以控制二维数组

就是多个指针

一般用于操作字符串

char str[3][20] = {"ILoveYou","IMissYou","abc"};
char* pstr[3] = {str[0],str[1],str[2]};
//每个pstr[i]都是一级指针
for (int i = 0; i < 3; i++)
{
    puts(pstr[i]);
}

二级指针

 

用于存放一级指针的地址

同,N级指针是用来存放N-1级指针的地址

定义

类型说明符 ** 名称

int* p=NULL;
int** pp=&p;
//几个*就是几级指针

看一下实例

int a=1;
int* p=&a;
int** pp=&p;
printf("%dt%dn",*p,p[0]);
printf("%dt%dn",**pp,*pp[0]);//或者pp[0][0],类似于二维指针但不同于二维数组

 

不能纯粹地当作二维数组来用

有的编译器可以,但是在C++中是错的

 下期我会整合一下关于内存的知识点,最后感谢您能阅读我的博客,谢谢。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号