我是靠谱客的博主 酷炫高山,最近开发中收集的这篇文章主要介绍【C语言进阶剖析】14、单引号和双引号,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

C 语言中的单引号用来表示字符字面量
C 语言中的双引号用来表示字符串字面量

举例说明:

  • ‘a’ 表示字符自变量,在内存中占 1 字节,‘a’ + 1 表示 ‘a’ 的 ASCII 码加 1,结果为 ‘b’
  • “a” 表示字符串字面量,在内存中占 2 个字节,“a”+1 表示指针运算,结果指向 “a” 结束符 ‘’

1 实验一:单引号和双引号的本质

//14-1.c
#include<stdio.h>
int main(){
    char* p1 = 1;
    char* p2 = '1';
    char* p3 = "1";
    printf("p1 = %s, p2 = %s, p3 = %s", p1, p2, p3);
    printf('n');
    printf("n");
    return 0;
}

1、编译运行结果如下:
在这里插入图片描述
可以看出程序第 4、5、8 行给出警告,运行,有段错误。

2、注释第 8、9 行,再次编译运行

//14-1.c
#include<stdio.h>
int main(){
    char* p1 = 1;
    char* p2 = '1';
    char* p3 = "1";
    printf("p1 = %s, p2 = %s, p3 = %s", p1, p2, p3);
    // printf('n');
    // printf("n");
    return 0;
}

在这里插入图片描述
程序第 4、5 行给出警告,运行,段错误。

3、注释第 7、9 行,再次编译运行

//14-1.c
#include<stdio.h>
int main(){
    char* p1 = 1;
    char* p2 = '1';
    char* p3 = "1";
    // printf("p1 = %s, p2 = %s, p3 = %s", p1, p2, p3);
    printf('n');
    // printf("n");
    return 0;
}

在这里插入图片描述
程序第 4、5、8 行给出警告,运行,段错误。

4、注释第 7、8 行,再次编译运行。

//14-1.c
#include<stdio.h>
int main(){
    char* p1 = 1;
    char* p2 = '1';
    char* p3 = "1";
    // printf("p1 = %s, p2 = %s, p3 = %s", p1, p2, p3);
    // printf('n');
    printf("n");
    return 0;
}

在这里插入图片描述
可以看出程序第 4、5 行给出警告,运行,没有问题。

由上可以看出,程序第 4、5、8 行给出警告,程序第 7、8 行会引起段错误,下面我们就来分析一下原因,在此之前补充一个小贴士:

小贴士

  1. 字符字面量被编译为对应的 ASCII 码
  2. 字符串字面量被编译为对应的内存地址
  3. printf 的第一个参数被当作字符串内存地址
  4. 内存的低地址空间不能在程序中任意访问

带着上面的小贴士,将 p1, p2, p3 变量对应的地址空间画出来,如下图所示:
在这里插入图片描述
打印的 ‘n’ 和 “n” 在内存中地址如下:
在这里插入图片描述
p1 的数字 1 和 p2 的字符 ‘1’(对应ASCII 为 0x31),都被当作地址值,直接指向内存;而字符串 “1” 是一个字符串,p3 是该字符串在内存中的地址。地址 0x08048000 是个特殊的地址空间,低于该地址空间的地址都不能任意访问,所以编译语句 char* p1 = 1; char* p2 = ‘1’ 和 printf(’n’) 都给出警告,运行语句 printf(“p1 = %s, p2 = %s, p3 = %s”, p1, p2, p3) 和 printf(’n’) 给出段错误的提示,因为低地址空间不能在程序中任意访问。

2 实验二:混淆概念的代码

再看一个例子,直接看代码。这段代码的本意是如果输入Tab 键、空格、回车,就继续输入。

//14-2.c
#include<stdio.h>
int main(){
    char c = " ";
    while((c == "t") || (c == " ") || (c == "n")){
        scanf("%c", &c);
    }
    return 0;
}

在这里插入图片描述
编译,出现警告,运行,没有任何输入,程序直接退出了,说明 while 循环没有执行。

下面我们来分析一下 char c = “string”; 到底发生了什么?

  • 编译后的字符串 “string” 的内存地址被赋值给变量 c
  • 内存地址占用 4 个字节,而变量 c 只占用 1 个字节
  • 由于类型不同,赋值后产生截断

所以判断循环的三个条件均不满足,while 循环没有执行,如何修改上述代码呢,很简单,把双引号变成单引号即可。

#include<stdio.h>
int main(){
    char c = ' ';
    while((c == 't') || (c == ' ') || (c == 'n')){
        scanf("%c", &c);
    }
    return 0;
}

3 小结

1、单引号括起来的单个字符代表整数
2、双引号括起来的字符代表字符指针
3、C 编译器接受字符和字符串的比较,无任何意义
4、C 编译器允许字符串对字符变量赋值,只能得到错误

最后补充一下程序的地址空间分布
在这里插入图片描述

最后

以上就是酷炫高山为你收集整理的【C语言进阶剖析】14、单引号和双引号的全部内容,希望文章能够帮你解决【C语言进阶剖析】14、单引号和双引号所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部