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

C语言基础——教你如何玩转指针(2)

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

C语言基础——教你如何玩转指针(2)

目录

常量字符串和数组创建的字符串

常量字符串

常量字符串和数组创建的字符串的区别

指针数组

数组指针

数组指针的作用

对于一维数组

对于二维数组


lucky同学在前面介绍了指针的一些基本内容,我们一起来回忆下:计算机将内存划分为一块一块的空间,且每一块有一个编号,这个编号就叫地址,即地址唯一标识一块空间,用来存放地址的变量叫做指针变量。指针类型与其所指向的数据有关,决定了指针解引用的时候能访问的权限。指针变量的大小也是固定的,32位平台下为4字节,64位平台下为8字节。还有指针的三种运算:指针加减整数、指针减指针、指针的关系运算。下面,lucky同学将进一步对指针进行介绍。

常量字符串和数组创建的字符串

对一个字符指针的修改和解引用:

#include
int main()
{
    char ch = 'w';
	char* pc=&ch;
	*pc='a';
	printf("%cn",ch); // a
return 0;
}

常量字符串

一个常量字符串如 "abcdef()" 的地址放到指针 p 里,指针存放的是这个常量字符串的首元素字符 'a' 的地址,打印时只需要知道首字符的地址就能找到整个字符串。注意的是,对于常量字符串,创建在常量区,是不能被随意修改的,所以可以在存储常量字符串地址的指针前面加上 const,防止被错误修改。 

#include
int main()
{
    char* p="abcdef"; // 常量字符串: a b c d e f 
	//把这个字符串的首字符a的地址放到了指针p里

	printf("%cn",*p); // a
	printf("%sn",p); // abcdef
	//打印这个字符串只需要给出这个字符串的首字符的地址 

	char* p="abcdef"; //常量字符串: a b c d e f 
	*p='w';
    //由于是常量字符串,*p不能改
	printf("%sn",p); // err

return 0;
}

常量字符串和数组创建的字符串的区别

首先看下面一组代码:

#include
int main()
{
    const char* p1="abcdef";
	const char* p2="abcdef";

	char arr1[]="abcdef";
	char arr2[]="abcdef";

	if(p1 == p2)
	{
		printf("p1 == p2n");
	}
	else
	{
		printf("p1 != p2n");
	}

	if(arr1 == arr2)
	{
		printf("arr1 == arr2n");
	}
	else
	{
		printf("arr1 != arr2n");
	}

	// 打印结果:p1 == p2	arr1 != arr2

return 0;
}

分析两者的区别可以发现,由于常量字符串放在常量区,它的地址只会保存一份,所以对两个内容一样的常量字符串,分别放在两个指针里,那么这两个指针是相同的。

而对于由数组创建的字符串 char arr1[ ] = "abcdef" 和 char arr2[ ] = "abcdef" ,告诉我们初始化了两个数组,分别为数组 arr1 和数组 arr2 ,内存中这两个数组分别各为独立的空间,所以它们的首元素的地址也肯定是不同的。

注意:上面数组 arr1 和 arr2 是放在栈区的,p1、p2 是指针,也是放在栈区的,其指向的那个字符串是放在常量区的。常量字符串如果创建在常量区,永远不能被改,而数组创建的字符串就可以更改。

指针数组

指针数组,顾名思义,即存放指针的数组,如整型数组和字符数组的创建:

整形数组:
int arr[10]; //存放整形的数组

字符数组:
char arr2[5]; //存放字符的数组

#include
int main()
{
	int* p1=&a;
	int* p2=&b;
	int* p3=&c; 
    // 数量多了会显得繁琐,借助指针数组

	int* arr[3]={&a,&b,&c};
    //arr就是一个指针数组

    //打印
	for(i=0;i<3;i++)
	{
		printf("%d ",*(arr[i]));
	}

return 0;
}
#include
int main()
{
    int i=0;
	int j=0;

	int arr1[5]={1,2,3,4,5};
	int arr2[5]={2,3,4,5,6};
	int arr3[5]={3,4,5,6,7};

	int* parr[3]={arr1,arr2,arr3}; // 分别存放三个数组首元素的地址
	// parr是指针数组

	for(i=0;i<3;i++)
	{
		for(j=0;j<5;j++)
		{
			//printf("%d ",parr[i][j]);
			printf("%d ",*(parr[i]+j)); // 也可以这样写
		}
		printf("n");
	}

return 0;
}

注意:

二维数组在内存中是连续存放的:

int arr[3][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};

内存中:1 2 3 4 5   2 3 4 5 6   3 4 5 6 7

但上面代码中 parr 指针数组,虽然在打印的时候,有二维数组的影子,但其中的三组数据在内存中并不是连续存放的。

数组指针

与整形指针、字符指针分别指向整型和字符一样,数组指针即指向数组的指针,例如下面的p2:

int (*p2)[10];
p2是个指针,指向数组,这个数组有10个元素,每个元素是int,所以称p2是个数组指针

所以数组指针可以用来存放数组的地址:&数组名

通常情况下,我们说的数组名都是首元素的地址
但是有两个例外:
1、sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小
2、&数组名,这里的数组名表示整个数组,&数组名,取出的是整个数组的地

看下面代码,区分不同情况下的指针加一: 

#include
int main()
{
	int arr[10]={0};

    int (*pa)[10]=&arr; // 利用数组指针一个数组的指针

	printf("%pn",arr); // 首元素地址 0073FBEC

	printf("%pn",&arr[0]); // 首元素地址 0073FBEC

	printf("%pn",&arr); // 这个数组的地址 0073FBEC

	printf("%pn",arr+1); // 0073FBF0		整型指针加一跳过4个字节

	printf("%pn",&arr[0]+1); // 0073FBF0 	整型指针加一跳过4个字节

	printf("%pn",&arr+1); // 0073FC14 数组指针加一,跳过这个数组的大小---40字节

return 0;
}

数组指针的作用

对于一维数组
#include

void print1(int* arr,int sz)
{
	int i=0;
	for(i=0;i 

可以知道,这个写法用来打印一维数组反而显得别扭,所以说数组指针一般不用于一维数组。

对于二维数组
#include

void print2(int arr[3][5],int c,int r)
{
	int i=0;
	int j=0;
	for(i=0;i 

注意理解:
arr[i] = *(arr+i)
arr[i][j] = *(arr+i)[j] = *(*(arr+i)+j)

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

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

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