字符串和字符I/O

169 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

字符串

字符串是以空白字符(\0)结尾的char类型数组

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

使用双引号括起来的内容称为字符串字面量,也叫做字符串常量,双引号中的字符和编译器自动加入末尾的\0字符,都作为字符串存储在内存中。

/*
从ANSI C标准起,如果字符串字面量之间没有间隔,或者使用空白字符分隔,C会将其视为串联起来的字符串字面量
*/
char txt[50]="Hello,how""are you""today";
// 等价于
char txt[50]="Hello,how are you today";

//使用双引号
printf("my name is \Jack\."); //my name is "Jack".

字符串常量属于静态存储类别,这说明如果在函数中使用字符串常量,该字符只会被存储一次,在整个程序的生命期存在,即使函数被调用多次。用双引号括起来的内容被视为指向该字符串存储位置的指针;这类似于把数组名作为指向该数组位置的指针

/*
初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针只把字符串的地址拷贝给指针
*/
#define TXT "hello"
int main()
{
	char arr[] = TXT;
	const char* p = TXT;
	printf("str1=%p\n", "hello");  //打印字符串1
	printf("TXT=%p\n", &TXT);
	printf("arr=%p\n", arr);
	printf("p=%p\n", p);
	printf("str2=%p", "hello");    //打印字符串2
	return 0;
}
/*返回结果
str1=003D7BD4
TXT=003D7BD4
arr=00B8F9D8
p=003D7BD4
str2=003D7BD4
得出结论:
1、p和arr的地址一样,验证了“初始化指针只把字符串的地址拷贝给指针”
2、字符串字面量”hello“在printf函数中使用了两次,但是地址都一致且和TXT的地址一样;说明:编译器可以把多次使用的相同字面量存储在一处或者多处
*/

数组与指针

//初始化指针尽量使用const限定符修饰
const char* p="Hello";
p[1]='K';

编译器可以使用内存中的一个副本来表示所有完全相同的字面量,如果修改指针指向的值,可能导致后续字面量发生改变,或者引发内存错误如果需要修改字面量,就不要将指针指向字面量。

字符串数组

int main(void)
{
	const char* p[] = {"Apple","Pear","Orange"};
	char arr[][10] = { "Apple","Pear","Orange" };
	printf("%zd %zd", sizeof(p), sizeof(arr));
	return 0;
}

p中的指针指向初始化时使用的字面量位置,这些字面量被存储在静态内存中;而arr存储字面量的副本,也就是每个字符串被存储两次。arr所使用的元素大小必须统一,而且必须是最长字符串的大小。 不规则数组和矩形数组