2024-07-23 笔记 - 5
作者(Author): 仟濹(网名)
字符指针
① 定义指针的时候也赋值字符串
为什么给一个指针赋值字符串的时候也可以打印出来整个字符串???
//eg:
char* p = "abcdefg";
printf("%s", p);//abcdefg
puts( p );//同理
printf("%s", p + 1);//bcdefg
puts(p + 1);//同理
首先明白一点,给一个指针赋值字符串的时候,相当于将第一个字符的地址赋值给了该指指针,而这几个字符串又是连续的,在打印字符串的时候,就是根据地址连续性打印的,从前往后打印,只要遇到 \0
就会停止打印。abcdefg
是常量字符串。
可以更改字符串 abcdefg
中的字符吗???
不可以,不会报错,但是编译器会挂掉(就是编译器会突然停止工作),因为这个字符串是不可更改的存在
char* p = "abcdefg";
*p = 'm';?//不报错,但是编译器停止运行
如果想让它会报错,用来提示不可更改,可以如下操作~
这样操作就会变得严谨一些
const char* p = "abcdefg";
//Or
const char const *p = "abcdefg";
*p = 'm';//如果是以上这两种定义,下面进行赋值的时候就会报错了
疑惑点:
-
用%s打印p的时候,打印的是字符串,如果是用%c打印*p,是否可以打印出第一个字符???
可以
-
如果用字符串的形式打印出来某个字符,格式为
printf("%s\n", &ch2);
,是否可以打印出来这个字符??可以,但是这种方式是不正确的,可能会出问题,只是疑惑,试一下能否这样打印。
-
如果两个字符变量的地址是连续的,用%s的形式打印出第一个字符,格式为
printf("%s", &ch);
,是否可以将第二个字符也打印出来???可以,但是这种方式是不正确的,可能会出问题,只是疑惑,试一下能否这样打印。
下面进行详细的解释和说明,也为了自己更深一步的理解~
//疑惑点,打印用%s打印p的时候,打印的是字符串
//如果用%c打印*p,能否打印出a
#include <stdio.h>
int main()
{
char* p = "abcdefg";
printf("%s\n", p);//abcdefg
printf("%c\n", *p);//a
char ch = 'm';//ch和ch2字符的地址连续的
char ch2 = 'n'; //测试如果两个变量是连续定义的(地址是连续的),将m按照字符串的形式打印的时候,能否将n打印出来???
printf("%s\n", &ch);//mn
//测试如果用%s打印出一个字符的地址(后面没有连续的字符),可以打印出字符串吗???
printf("%s", &ch2);//n
return 0;
}
总结:
① 字符地址是连续的,存储的是 a b c d e f g \0
② p 中存储的是第一个字符的地址,即首字符 a 的地址。
③ p中可不是存储的整个字符传的地址
④ abcdefg
是存储在常量区(只读数据段),所以是不可更改的。
② 字符指针的坑
const char* p1 = "abcdefg";
const char* p2 = "abcdefg";
if(p1 == p2)
printf("p1 和 p2 存储的地址相同");
else
printf("p1 和 p2 存储的地址不同");
char arr1[] = "abcdefg";
char arr2[] = "abcdefg";
if(arr1 == arr2)
printf("arr1 和 arr2 存储的地址相同");
else
printf("arr1 和 arr2 存储的地址相同");
答案可不是都不相同,我刚开始以为是都不相同,是我想错了
p1 和 p2 中存储的地址是相同的。
arr1 和 arr2 的地址是不相同的。
为什么呢???
p1 和 p2 要赋值abcdefg
,这的 abcdefg
是存储在【常量区】中的,所以这的 'a'
的地址都是相同的,所以p1 和 p2 中的地址都是这里 'a'
的地址所以是相同的。
arr1 和 arr2 是分别开辟了两块内存空间,而在这两个内存空间中分别存入了两个字符串,所以地址肯定是不一样的。
在我知道答案之前,我还以为p1 和 p2也是分别开辟了两个内存空间, 然后分别将两个在不同空间存储的'a'
的地址存储在p1 和 p2当中,实则不是这样子的。
其实他俩存储的地址是一样,是我理解错了哈哈哈