指针及其应用2——数组指针、字符串指针

指针与数组的关系    
指向数组的指针变量称为数组指针变量。一个数组是一块连续的内存单元组成的,数组 名就是这块连续内存单元的首地址。一个数组元素的首地址就是指它所占有的几个内存单元的首地址。一个指针变量即可以指向一个数组,也可以指向一个数组元素,可把数组名或第 一个元素的地址赋予它。如要使指针变量指向第 i 号元素,可以把 i 元素的首地址赋予它,或把数组名加 i 赋予它。
设有数组 a,指向 a 的指针变量为 pa,则有以下关系:pa、a、&a[0]均指向同一单元, 是数组 a 的首地址,也是 0 号元素 a[0]的首地址。pa+1、a+1、&a[1]均指向 1 号元素 a[1]。 类推可知 pa+i、a+i、&a[i]指向 i 号元素 a[i]。pa 是变量,而 a,&a[i]是常量,在编程时 应予以注意。 
 
指向数组的指针
数组指针变量说明的一般形式为:         类型说明符  *指针变量名      
引入指针变量后,就可以用两种方法访问数组元素了, 例如定义了 int a[5];int *pa=a;     第一种方法为下标法,即用 pa[i]形式访问 a 的数组元素。 第二种方法为指针法,即采用*(pa+i)形式,用间接访问的方法来访问数组元素。 
 
【例 5】scanf 使用数组名,用数组名或指针访问数组。 

#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
	int a[5],i,*pa=a;//定义整型数组和指针,*pa=a也可以在下一行pa=a 
	for(i=0;i<5;i++)
		scanf("%d",a+i);//可写成pa+i和&a[i] 
	for(i=0;i<5;i++)
		printf("a[%d]=%d\n",i,*(pa+i)); //指针访问数组,可写成*(pa+i)或pa[i]或a[i] 
	return 0;
 } 

输入:1 2 3 4 5 
输出:a[0]=1
          a[1]=2
          a[2]=3
          a[3]=4 
          a[4]=5 

【说明】
①、直接拿 a 当指针用,a 指向数组的开始元素,a+i 是指向数组的第 i 个元素的指针。 
②、指针变量 pa 是变量,可以变的。但数组 a 是静态的变量名,不可变,只能当做常 量指针使用。例如:p=p+2;是合法的,a=a+2;是非法的。
③、最早在使用标准输入 scanf 时就使用了指针技术,读入一个变量时要加取地址运算 符’&’传递给 scanf 一个指针。对于数组,可以直接用数组名当指针。

指针也可以看成数组名
指针可以动态申请空间,如果一次申请多个变量空间,系统给的地址是连续的,就可以当成数组使用,这就是传说中的动态数组的一种。 
【例 6】动态数组,计算前缀和数组。b是数组 a 的前缀和的数组定义:b[i]=a[1]+a[2] +…+a[i],即b[i]是 a 的 i 个元素的和。 

#include<cstdio>
using namespace std;
int n;
int *a;//定义指针变量a,后面直接当数组使用 
int main()
{
	scanf("%d",&n);
	a=new int[n+1];//向操作系统申请了连续的n+1个int型的空间 
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=2;i<=n;i++)
		a[i]+=a[i-1];
	for(int i=1;i<=n;i++)
		printf("%d ",a[i]);
	return 0;
 } 

输入:
5
1 2 3 4 5
输出:
1 3 6 10 15 

【说明】
动态数组的优点:在 OI 中,对于大数据可能超空间的情况是比较纠结的事,用小数组 只的部分分,大数组可能爆空间(得 0 分)。使用“动态数组”,可以在确保小数据没问题的 前提下,尽量满足大数据的需求。

指针与字符串 
字符串的表示形式    在 C++中,我们可以用两种方式访问字符串。 
(1)用字符数组存放一个字符串,然后输出该字符串。

 int main()
 {
    char str[]="I love China!";
    printf("%s\n", str);
 } 

(2)用字符指针指向一个字符串。可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串中的字符。 

int main()
{
    char *str="I love China!";
    printf("%s\n", str);
 } 

在这里,我们没有定义字符数组,而是在程序中定义了一个字符指针变量 str,用字符串常量"I love China!",对它进行初始化。C++对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组用来才存放该字符串常量。对字符指针变量初始化,实际上是把字符串第 1 个元素的地址(即存放字符串的字符数组的首元素地址)赋给 str。有人认为 str 是 一个字符串变量,以为在定义时把"I love China!"这几个字符赋给该字符串变量,这是不 对的。
实际上,

char *str="I love China!";  

等价于:

char *str; 
str="I love China!";    

可以看到,str被定义为一个指针变量,指向字符型数据,请注意它只是指向了一个字符变量或其他字符类型数据,不能同时指向多个字符数据,更不是把"I love China!"这些字符存放到 str 中(指针变量只能存放地址)。只是把"I love China!"的第一个字符的地址赋给指针变量 str。 
在输出时,要用:

printf(“%s\n”, str);

其中“%s”是输出字符串时所用的格式符,在输出项中给出字符指针变量名,则系统先输出它所指向的一个字符数据,然后自动是 str 加 1,使之指向下一个字符,然后再输出一 个字符……如此知道遇到字符串结束标志“\0”为止。 
注意:可以通过字符数组名或者字符指针变量输出一个字符串。而对一个数值型数组,是不能企图用数组名输出它的全部元素的。 例如:

int i[10];
…… printf(”%d\n”, i);

这样是不行的,只能逐个输出。显然 %s 可以对一个字符串进行整体的输入和输出。

字符串指针作函数参数
将一个字符串从一个函数传递到另外一个函数,可以用地址传递的方法,即用字符数组 名作参数或用指向字符的指针变量做参数。在被调用的函数中可以改变字符串内容,在主调 函数中可以得到改变了的字符串。 

【例 8】输入一个长度最大为 100 的字符串,以字符数组的方式储存,再将字符串倒序储存, 输出倒序储存后的字符串。(这里以字符指针为函数参数)

#include<cstdio>
#include<cstring> 
using namespace std;
void swapp(char &a,char &b)
{
	char t;
	t=a;a=b;b=t;
}
void work(char* str)
{
	int len=strlen(str);//strlen(str)返回str的长度
	//需要包含头文件cstring 函数原型是"size_t strlen(const char* str)"  
	for(int i=0;i<=len/2;++i)
		swapp(str[i],str[len-i-1]);
}
int main()
{
	char s[110];
	char *str=s;
	gets(s);
	work(str);
	printf("%s",s);
	return 0;
 } 

输入:
!anihC evol I 
输出:
I love China! 

 


版权声明:本文为lybc2019原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。