IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言指针学习(3) -> 正文阅读

[C++知识库]C语言指针学习(3)

1.字符串的引用方式

在C语言程序中,字符串是存放在字符数组中的,想引用一个字符串,可以用以下俩种方法

(1)用字符数组存放一个字符串,可以通过数组名和下标引用字符串其中一个字符,也可以用数组名和格式声明“%s”输出字符串

【例题】定义一个字符数组,在其中存放字符串“I love China!”输出该字符串和第八个字符

#include<stdio.h>
int main()
{
	char string[]="I love China!";               //定义字符数组
	printf("%s\n",string);                      //输出整个字符串
	printf("%c",string[7]);                     //输出第八个字符
	return 0; 
}

运行结果:

在定义字符串数组时没有指定长度,但是对它初始化了,所以它的长度是确定的虽然只存放了“I love China!”13个字符,但是应该是14个,因为最后还有一个字符串结束符‘\0’?,数组名string代表字符数组首元素地址,实际上string[7]就是*(string+7),string+7就是一个地址,它指向“C”。

(2)用字符指针变量指向一个字符串常量,通过字符指针变量指向字符串常量

【例题】通过字符指针变量输出一个字符串

#include<stdio.h>
int main()
{
	char *string="I love China!";               //定义字符指针变量并初始化 
	printf("%s\n",string);                      //输出整个字符串
	return 0; 
}

运行结果:

在程序中没有定义字符数组,只定义了一个字符指针变量,用字符常量“I love China!”?对其进行初始化,C语言对字符串常量是按字符数组处理的,在内存中开辟一个字符串数组来存放字符串常量,但是这个字符数组是没有名字的,因此不能通过数组名来引用,只能通过指针变量来引用。

注意:string被定义为一个指针常量,基类型为字符型,请注意它只能指向一个字符类型数据,而不能同时指向多个字符数据,更不是把“I love China!”这些存放到string中(指针变量只能存放地址),也不是把字符串赋值给*string。只是把“I love Chian!”的第一个字符的地址赋值给指针变量。

//可以对指针变量进行再次赋值,例如
string = "I am a student."; 

%s是输出字符串时所用的格式符,在输出时能确定输出的字符到何时结束,也就是对一个字符串进行整体的输入输出。

通过字符数组名或字符指针变量可以输出一个字符串,而对于一个数值型数组,是不能用数组名输出它的全部元素的,例如:

int a[10];
.
.
.
printf("%d\n",a);

是不行的,它输出的是数组首元素的地址。对于数值型数组的元素值只能逐个输出。

对于字符串中字符的存取,可以用下标方法,也可以用指针方法。

【例题】将字符串a复制为字符串b,然后输出字符串b

#include<stdio.h>
int main()
{
	char a[]="I am a student.",b[20];                      //定义字符数组
	int i;
	for(i=0;*(a+i)!='\0';i++){                             //a[i]的值赋值给b[i] 
		*(b+i)=*(a+i);
	}
	*(b+i)='\0';
	printf("string a is:%s\n",a);                          //输出数组a的元素 
	printf("string b is:");
	for(i=0;b[i]!='\0';i++){
		printf("%c",b[i]);
	} 
	
	return 0; 
}

运行结果:

也可以用数组的方法输出b的值,如:

printf("string b is:%s\n",b);

?也可以用另一种方法----用指针变量访问字符串,通过改变指针变量的值使它指向字符串的不同字符,如下:

#include<stdio.h>
int main()
{
	char a[]="I am a boy.",b[20],*p1,*p2;                      //定义字符数组
	p1=a,p2=b;                                                 //p1,p2分别指向a,b数组的第一个元素
	for(;*p1!='\0';p1++,p2++){                                  //p1,p2自加 
		*p2=*p1;                                               //将p1指向的值赋值给p2   
	} 
	*p2='\0';
	printf("string a is:%s\n",a);
	printf("string b is:%s\n",b); 
	return 0; 
}

?运行结果:

2.字符指针作函数参数?

如果想把一个字符串从一个函数传递到另一个函数,可以用地址传递的方法,即用字符数组名作参数,也可以字符指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。

【例题】用函数调用实现字符串的复制

【1】用字符数组名作函数参数

#include<stdio.h>
void copy(char from[],char to[]);                       //函数声明 
int main()
{
	char a[]="I am a teacher.";
	char b[]="You are a student.";
	printf("string a = %s\nstring b = %s",a,b);
	printf("\ncopy string a to string b:\n");
	copy(a,b);                                          //用字符数组名作函数参数
	printf("string a = %s\nstring b = %s",a,b); 
	return 0; 
}
void copy(char from[],char to[])                        //形参为字符数组 
{
	int i;
	while(from[i]!='\0'){
		to[i]=from[i];
		i++;
	}
	to[i]='\0';
}

运行结果:

在调用copy函数时,将a和b的第一个字符的地址分别传递给形参数组名from和to。由于数组b原来的长度大于a数组,因此将a数组复制到b数组后,未能全部覆盖,在输出时按照%s输出,遇到'\0'就停止了,如果按照%c,则后面未被覆盖的还可以输出。?

【2】用字符型指针变量作实参

#include<stdio.h>
void copy(char from[],char to[]);                       //函数声明 
int main()
{
	char a[]="I am a teacher.";
	char b[]="You are a student.";
	char *from = a,*to =b;
	printf("string a = %s\nstring b = %s",a,b);
	printf("\ncopy string a to string b:\n");
	copy(from,to);                                          //用字符数组名作函数参数
	printf("string a = %s\nstring b = %s",a,b); 
	return 0; 
}
void copy(char from[],char to[])                        //形参为字符数组 
{
	int i;
	while(from[i]!='\0'){
		to[i]=from[i];
		i++;
	}
	to[i]='\0';
}

一样可以达到目的

【3】用字符指针变量作形参和实参

#include<stdio.h>
void copy(char *from,char *to);                                //函数声明 
int main()
{
	char *a="I am a teacher.";                                //a是char*型指针变量 
	char b[]="You are a student.";                            //b是字符数组 
	char *p = b;                                              //使指针变量p指向b数组首元素 
	printf("string a = %s\nstring b = %s",a,b);
	printf("\ncopy string a to string b:\n");
	copy(a,p);                                          //用字符数组名作函数参数
	printf("string a = %s\nstring b = %s",a,b); 
	return 0; 
}
void copy(char *from,char *to)                        //形参为字符数组 
{
	for(;*from!='\0';from++,to++){
		*to=*from;
	}
	*to='\0';
}

程序改进:

copy 函数还可以改写的更精炼一些,如下:
(1)
void copy(char * from,char * to)
{
	while((* to=*from)!='\0'){
		to++,from++;
	}
	
 } 
(2)
void copy(char *from,char* to)
{
	while(*from!='\0'){
		*to++=*from++;
	}
	*to='\0';
}
先将*from赋值给*to,然后自加
(3)
void copy(char * from,char * to)
{
	while((* to++=*from++)!='\0'){
		
	}
	
 }
(4)
还可以用ascll码来表示
{
	while(*from){                                  //与*from!='\0'等价 
		*to++=*from++;
	}
	*to='\0';
  }  
(5)
上述函数体还可以写成
while(*to++=*from++);
等价于:
while((*to++=*from++)!='\0');
(6)也可以用for循环语句
for(;(*to++=*from++)!='\0';);
或:
for(;*to++=*from++;);
(7)也可以用字符数组名作函数形参
void copy(char from[],char to[])
{
	char *p1,*p2;
	p1=from,p2=to;
	while((* p2++=*p1++)!='\0'){
		
	}
	
 }  

3.使用字符指针变量和字符数组的比较

用字符数组和字符指针变量都能实现字符串的存储和运算,但他们二者之间是有区别的:

(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第一个字符的地址),绝不是将字符串放到字符指针变量中。

(2)赋值方式。可以对字符指针变量赋值,但不能对数组名赋值:

可以用下面方法对字符指针变量赋值:
char *a;                        //a为字符指针变量
a = "I love Chian!"             //将字符串首元素地址赋给指针变量,合法
不能用以下办法对字符数组名赋值:
char str[14];
str[0]='I';                     //对字符数组元素赋值,合法;
str="I love China!";            //数组名是地址,是常量,不能被赋值 

(3)初始化的含义,对字符指针变量赋初值:

char * a="I love China!";                   //定义字符指针变量a,并把字符串第一个元素地址赋值给a
等价于:
char *a;                                    //定义字符指针变量a
a ="I love China!";                         //把字符串第一个元素地址赋值给a    
对数组初始化:
char str[14]="I love China!";               //定义字符数组并赋初值
不等价于:
char str[14];                               //定义字符数组
str[]="I love Chian!";                      //企图把字符串赋给数组中的各个元素 

数组可以在定义时对各个元素赋初值,但不能用赋值语句对字符数组中全部元素整体赋值

(4)储存单元的内容

编译时为字符数组分配若干储存单元,以存放各个元素的值,而对字符指针变量,只分配一个存储单元,例如下面的用法

char *a;              //定义字符指针变量
scanf("%s",a);        //企图从键盘中输入一个字符串,使a指向它,错误 

在编译时,给指针变量分配了存储单元,即a的地址已经指定了,但a的存储单元中是一个不可预料的值,在输入时可能导致系统出错,应当在定义指针变量后,及时指定其指向。如:

char *a,str[10];                //定义字符指针变量和字符数组
a=str;                          //使a指向str的首元素
scanf("%s",a);                  //从键盘中输入一个字符串存放到a所指向的一段储存单元中

先使a有确定的值,然后再输入。

(5)指针变量的值是可改变的,而字符数组名代表一个固定的值(数组首元素地址),不能改变

【例题】改变指针变量的值

#include<stdio.h>
int main()
{
	char *a="I love China!";   
	a=a+7;
	printf("%s",a);                    
	return 0;
}

运训结果是:“ China! ”

指针变量指向的初始值变了,所以最终输出结果变了,而数组名虽然代表地址,但它是常量,它的值是不能改变的,下面做法是错误的:

char str[]={"I love China!"};
str = str+7;
printf("%s",str);

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-05 21:32:58  更:2022-02-05 21:33:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:34:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码