C语言学习

您所在的位置:网站首页 c语言字符串数组和字符数组 C语言学习

C语言学习

2024-05-28 09:57| 来源: 网络整理| 查看: 265

🌈在C Primer Plus 第六版中第11章的字符串和字符串函数讲的很好~ 对于字符串和字符串指针的用法又更深入了解了一些~

🐬 本blog为 C Primer Plus 的记录~ ☘️对于字符串指针和数组更加深入了解~ 🌺省流:1️⃣字符串常量被储存在静态内存中;2️⃣字符串数组则储存着字符串字面量的副本,相当于拷贝~ 所以每个字符串都被储存了两次,指针则指向了字符串的地址。3️⃣字符串数组名是一个常量 🍭加油加油~ (●ˇ∀ˇ●)

字符串数组和字符串指针

文章目录 字符串数组和字符串指针在程序中定义字符串字符串字面量(字符串常量)字符串数组和初始化数组和指针数组和指针的区别未使用const限定符的指针初始化 字符串数组

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

puts();

和printf()函数一样,puts()函数也属于stdio.h系列的输入/输出函数。但是,与printf()不同的是,puts()函数只显示字符串,而且自动在显示的字符串末尾加上换行符。

在程序中定义字符串 字符串字面量(字符串常量)

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

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

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

字符串数组和初始化

定义字符串数组时,必须让编译器知道需要多少空间。

1️⃣一种方法是用足够空间的数组储存字符串。

在这里插入图片描述

注意最后的空字符。没有这个空字符,这就不是一个字符串,而是一个字符数组。

(●ˇ∀ˇ●) 一般写完循环 最后结束的时候 需要赋值‘\0’ 以表示结束了。

让编译器计算数组的大小只能用在初始化数组时。如果创建一个稍后再填充的数组,就必须在声明时指定大小。声明数组时,数组大小必须是可求值的整数。

字符数组名和其他数组名一样,是该数组首元素的地址。因此,假设有下面的初始化:

char car[10] = "Tata";

那么,以下表达式都为真:

car == &car[0]、*car == 'T'、*(car+1) == car[1] == 'a'。

还可以使用指针表示法创建字符串。例如,程序清单11.1中使用了下面的声明:

const char * pt1 = "Something is pointing at me.";

该声明和下面的声明几乎相同:

const char ar1[] = "Something is pointing at me.";

以上两个声明表明,pt1和ar1都是该字符串的地址。在这两种情况下,带双引号的字符串本身决定了预留给字符串的存储空间。尽管如此,这两种形式并不完全相同。

数组和指针

🍶数组形式

数组形式(ar1[])在计算机的内存中分配为一个内含29个元素的数组(每个元素对应一个字符,还加上一个末尾的空字符’\0’),每个元素被初始化为字符串字面量对应的字符。

通常,字符串都作为可执行文件的一部分储存在数据段中。当把程序载入内存时,也载入了程序中的字符串。**字符串储存在静态存储区(static memory)中。但是,程序在开始运行时才会为该数组分配内存。**此时,才将字符串拷贝到数组中(第 12 章将详细讲解)。注意,此时字符串有两个副本。一个是在静态内存中的字符串字面量,另一个是储存在ar1数组中的字符串。

此后,编译器便把数组名ar1识别为该数组首元素地址(&ar1[0])的别名。❗️ 这里关键要理解,在数组形式中,ar1是地址常量。不能更改ar1,如果改变了ar1,则意味着改变了数组的存储位置(即地址) 。可以进行类似ar1+1这样的操作,标识数组的下一个元素。但是不允许进行++ar1这样的操作。递增运算符只能用于变量名前(或概括地说,只能用于可修改的左值),不能用于常量。

对于上述的表述,其实就是说,数组名是一个常量,不能被修改。就和1=2一样,这样是不合规的。

如果不理解可以继续往下面看。

🌵指针形式

指针形式(*pt1)也使得编译器为字符串在静态存储区预留29个元素的空间。另外,一旦开始执行程序,它会为指针变量pt1留出一个储存位置,并把字符串的地址储存在指针变量中。该变量最初指向该字符串的首字符,但是它的值可以改变。 因此,可以使用递增运算符。

指针是一个变量,因此可以进行递增运算。

字符串字面量被视为const数据。 由于pt1指向这个const数据,所以应该把pt1声明为指向const数据的指针。这意味着不能用pt1改变它所指向的数据,但是仍然可以改变pt1的值(即,pt1指向的位置)。如果把一个字符串字面量拷贝给一个数组,就可以随意改变数据,除非把数组声明为const。

举个 🌰

#define MSG "I'm special" #include int main(){ char ar[] = MSG; const char *pt = MSG; printf("address of \"I'm special\": %p \n", "I'm special"); printf(" address ar: %p\n", ar); printf(" address pt: %p\n", pt); printf(" address of MSG: %p\n", MSG); printf("address of \"I'm special\": %p \n", "I'm special"); return 0; }

🤔想想他们输出是什么?

address of "I'm special": 0x100000f10 address ar: 0x7fff5fbff858 address pt: 0x100000f10 address of MSG: 0x100000f10 address of "I'm special": 0x100000f10

该程序的输出说明了什么?1️⃣pt和MSG的地址相同,而ar的地址不同,这与我们前面讨论的内容一致。2️⃣虽然字符串字面量"I’m special"在程序的两个 printf()函数中出现了两次,但是编译器只使用了一个存储位置 ,而且与MSG的地址相同。编译器可以把多次使用的相同字面量储存在一处或多处。 另一个编译器可能在不同的位置储存3个"I’m special"。3️⃣静态数据使用的内存与ar使用的动态内存不同。 不仅值不同,特定编译器甚至使用不同的位数表示两种内存。

🌿总之,初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针只把字符串的地址拷贝给指针。

数组和指针的区别 char heart[] = "I love Tillie!"; const char *head = "I love Millie!";

🌺数组名heart是常量,而指针名head是变量。

1️⃣首先,两者都可以使用数组表示法:

for (i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3