字符串与指针的爱恨情仇

本文详细介绍了C语言中字符串的表示方式,包括字符串常量、字符数组和字符指针的使用。重点讲解了字符串I/O操作,如puts()函数的特性,以及字符串在内存中的存储和不同形式(数组和指针)的区别。还探讨了字符串常量的静态存储和动态内存的差异,以及如何正确处理字符数组和指针的修改操作。
摘要由CSDN通过智能技术生成

表示字符串和字符串I/O

字符串是以空字符’\0’结尾的char类型数组,字符串在我们的编程生活中特别常用,因此C提供了许多专门用于处理字符串的函数。接下来我们将从字符串的I/O开始探讨。

#include "stdio.h"
#define MSG "I am a symbolioc string constant"   //1.字符串常量
#define MAXLENGTH 81

int main(){
	char words[MAXLENGTH]="I am a string in an array";    //2.用字符数组存储
	const char *pt1="Something is pointing at me";       //3.用字符类型指针指向
	puts("Here are some strings:");
	puts(MSG);
	puts(words);
	puts(pt1);
	words[8]='p';
	puts(words);
	
	return 0; 
} 

结果如下:
在这里插入图片描述
puts() 函数与printf()函数一样,都输入stdio.h头文件中定义的输入/输出函数,但是puts()与众不同的地方在于,puts()函数只显示字符串,而且自动在显示的字符串末尾加上换行符,相信大家在输出的结果中也能看到。

在程序中定义字符串

1.字符串字面量(字符串常量)

用双引号括起来的内容称为字符串字面量,也叫做字符串常量。值得注意的是,双引号中的字符和编译器自动加入末尾的\0字符,都作为字符串储存在内存中。这里有两个需要注意的小细节。

1.如果字符串字面量之间没有间隔,或者用空白字符分割,C会将其视为串联起来的字符串字面量.

#include "stdio.h"
#define MSG "I am a symbolioc string constant"
#define MAXLENGTH 81

int main(){
	char words[MAXLENGTH]="I am a string in an array";   
	char word[MAXLENGTH]="I am a string"" in an"" array"; 
	printf("\nwords=");
	puts(words);
	printf("\nword=");
	puts(word);
	return 0; 
} 

2.如果要在字符串内部使用双引号,必须在双引号前面加上一个反斜杠(\)

	printf(" \" i love you \", he say");

结果如下
在这里插入图片描述最后不妨一提的是,字符串常量属于静态存储类别 ,这说明如果在函数中使用字符串常量,该字符只会被存储一次,在整个程序的生命周期内存在,即使函数被调用多次。

2.数组和指针

字符串的数组形式和指针形式有何不同? 我们直接开门见山。

#define MSG "I am special"
#include "stdio.h"

int main(){
	
	char ar[] =MSG;
	const char *pt=MSG;
	printf("\n address of \"I am special \"   : %p","I am special");
	printf("\n                     address ar:%p",ar);
	printf("\n                     address pt:%p",pt);
	printf("\n                 address of MSG:%p",MSG);
	printf("\n address of \"I am special \"   : %p\n","I am special");
	
	return 520;
} 

输出结果如下
在这里插入图片描述从这个结果中我们可以得到以下几点结论:

  • pt 与MSG的地址相同,而ar的地址不同
  • 字符串面量"I am special"在程序的两个printf 函数中出现两次,但是编译器只使用了一个存储位置,而且与MSG的地址相同。
  • 静态数据使用的内存与ar使用的动态内存不同。不仅值不同,特定编译器甚至使用不同的位数表示两种内存

综上所述,初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针只是把字符串的地址拷贝给指针。

字符串的指针表示

在这里我们仅探讨一个小细节,不管是复习指针概念也好,还是提高编程细节也好。

char *word="frame";
word[1]='l';

这样是否被允许呢?在我认为,编译器可能允许这样做,但是对当前C语言标准而言,这样的行为是未定义,比如这样的语句可能导致内存访问错误。

#include "stdio.h"

int main(){
	char *pl="Kinggon";
	pl[0] = 'F';     //OK?
	printf("Kinggon");
	printf(":Beware the %ss!\n","Kinggon");
	return 520; 
}

这会导致什么样的结果呢? 有的编译器可以用相同的地址替换每个“Kinggon”。输出结果为:
Finggon: Beware the Finggon!

当然,一些编译器会由于这方面的原因,其行为难以捉摸,另一些编译器会导致程序异常中断(在我实验的C-Free5编译器以及DEV-C++中便是如此)
在这里插入图片描述因此,推荐用法如下:

const char *p1="Kinggon";
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值