C语言各种符号的使用介绍上篇

目录
  • 1、注释符号
    • 1.1 注释的基本注意事项
    • 1.2 如何写出好的注释
  • 2、接续符和转移符
    • 2.1 续行功能
    • 2.2 转义字符
  • 3、单引号和双引号
    • 3.1 基本概念
    • 3.2 特殊情况
  • 4、逻辑操作符
    • 4.1 && (逻辑与)
    • 4.2 || (逻辑或)
    • 4.3 逻辑与和逻辑或的笔试题

1、注释符号

1.1 注释的基本注意事项

为了更好的演示我们下面的代码会在 Linux 平台下演示( \ 为续行符):

这段代码,哪一行是有问题的呢?

这里可能有小伙伴就有疑问了,为什么只有这一行出了问题呢?我们知道注释在预处理阶段就被编译器识别出来了,这里我们可以用 Linux 的一个指令:gcc -E test.c -o test.i这样就是对test.c 程序进行翻译,最终把预处理的结果保留下来,接着就可以用 vim 打开我们的预处理结果文件了。

最终我们可以得出这样一个结论:注释被替换本质上是被替换成空格!

这里我们要再提一个简单的点,C语言注释无法被嵌套,/* 总是与最近的 */ 匹配,感兴趣的小伙伴可以去测试下:

int main()
{
    /*
    /*printf("hello world");
    printf("hello world");*/
    */
    return 0;
}

这里还有一个有趣的代码,如果用C语言的注释的话,如果只出现了一个 /* 找不到下面的 */ 的话,那么他就会默认下面所有代码都被注释!

int main()
{
    int x = 10;
    int y = 5;
    int ret = 0;
    int* p = &y;
    ret = y/*p;
    return 0;
}

那么如何解决上面这种情况呢?

在 / 与 * 中加上空格: ret = y / *p;

把 *p 用括号括起来: ret = y / (*p);

推荐第二种,因为看起来会更直观

1.2 如何写出好的注释

[ 建议1 ] 注释应该准确易懂,不能有争议性,错误的注释反而有害。

[ 建议2 ] 要保证注释与代码的一致性,没用的注释及时删除。

[ 建议3 ] 对于全局数据 (全局变量、常量定义)必须要加注释。

[ 建议4 ] 一目了然的语句可以不加注释,比如:i++; // i 自增1。

[ 建议5 ] 注释的位置应与被描述的代码相邻,可以与语句同一行,不放在下方。

[ 建议6 ] 当代码比较长,特别是有多重其那套时,应当在一些段落的结束处加注释。

[ 建议7 ] 注释的缩进要与代码的缩进一致。

[ 建议8 ] 注释代码应当注重,“ 为何做 ” ,而不是 “ 怎么做 ”。

[ 建议9 ] 数值的单位一定要给上注释。

[ 建议10 ] 复杂的函数中,在分支语句、循环语句结束之后需要适当的注释,方便区分各个分支或循环体。

2、接续符和转移符

2.1 续行功能

C语言里用反斜杠( \ )表示断航。编译器会将反斜杠剔除掉,跟在反斜杠后面的字符自动续接到前一行。但是注意:反斜杠之后不能有空格,感兴趣的小伙伴可以下来测试下:

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    if (1 == a && \
        2 == b && \
        3 == c)
    {
        printf("You can see me!\n");
    }
    else
    {
        printf("You can not see me!\n");
    }
    return 0;
}

可能有的小伙伴会好奇,明明我不用 \ 也可以换行不会报错啊,那为什么还要用 \ 表示换行呢?我们作为一个程序员,别人可能也会去阅读我们的代码,如果不带 \ 直接换行可能会出现奇异,在一个也可以告诉编译器这个地方是续行,语义更强!

2.2 转义字符

C语言中,有一些字符,就是他的字面意思,比如 'n','b','t'。 也有一些字符,本身就是特殊含义的,比如:" , ', \ 转义的本质含义是:字面转特殊,或者特殊转字面。

\ 有两种用途:

  1. 当续行符使用
  2. 转义字符使用 (a. 字面转特殊 b. 特殊转字面)

这里我们重点讲一下 \n 和 \r可能小伙伴们都听过换行和回车吧!那么他们本质上的意思是不一样的!但是现在很多编译器让换行( \n )里面也包含了回车( \r ) 的功能!那他们俩究竟有什么样的区别呢?

换行:让光标移动到下一行

回车:光标回到当前行的最开始

这里小伙伴可以试一下用C语言写一个简单的倒计时功能,就能很明显的区分换行和回车的区别了!

这里我们也可以来看一道笔试题:

//以下程序输出什么?
#include <string.h>
#include <stdio.h>
int main()
{
    printf("%d\n", strlen("abcdef"));
    // \62被解析成一个转义字符
    printf("%d\n", strlen("c:\test\628\test.c"));
    return 0;
}

这里第一个打印函数,我们如果有了解,strlen() 函数是求字符串中 \0 之前的字符个数,所以第一个打印的是 6 , 第二个打印函数,首先是 \t 被解析成一个转义字符, \62 也被解析成一个转义字符 (8进制) 所以第二个打印的应该是 14 !

3、单引号和双引号

3.1 基本概念

对于C语言有了解的小伙伴都知道,单引号引起来的都是字符常量,双引号引起来的都是字符串常量,但其实对于初学者来说还是容易出错,比如 'a',和 "a" 是完全不一样的概念,在字符串中,以 \0 为结尾,他本质上不属于字符串的元素内容,只能说他是字符串结束标识符,但是它会占用空间!也就是 'a' 会占一个字节而 "a",则会占两个字节。

有了上面简单的概念我们来看一个例子:

这里可能就有小伙伴有疑问了,前两个和最后一个 printf打印结果我还能理解,可是第三个为啥是占四个字节呢?这明明不是一个字符常量吗?(C++ 中第三个大小为 1 个字节,因为这里是讲C语言所以我们不讨论其他语言)

其实在 C99 标准的规定,'1' 叫做整型字符常量(integer character constant),被看成是 int 类型。

光是用 “ 标准规定 ” 用来证明是不可行的,我们再用一个实例来证明:

看到这个结果不要惊讶,我刚刚说过,标准规定,整型字符常量被看成是 int 类型,所以他会有四个字节的空间,而且我当前电脑是小端存储,所以低字节序放在低地址处,在者,将一个4字节的数据放入 char 类型的变量中是会发生数据截断的,会将低地址的一个字节内容放入 char 类型的变量中,所以其实最终 c 变量里放的只是一个 'd' 字符!

但是我不推荐上面这种写法!!!我们明白其中道理就好。

那这里有的小伙伴又开始下去实验了,于是写出了这样的代码:

因为一个整型字符常量只有 4 个字节空间,他如何能放得下 5个字节甚至更多呢?

3.2 特殊情况

显而易见,是不能出现空整型字符常量的,但是可以出现空字符串,因为字符串结束标识符 \0 虽然不能算字符串元素内容,但是它也是占大小的。

4、逻辑操作符

4.1 && (逻辑与)

概念:级联两个(多个)逻辑表达式,必须同时为真,结果才为真。

例子:

对于逻辑与的短路现象,因为我们编译器是从左往右扫描的,所以如果当表达式左边为假的话,它就不会去执行逻辑与右边的表达式,这也就是我们所称的短路现象:

4.2 || (逻辑或)

概念:级联两个(多个)逻辑表达式,必须至少一个为真,结果才为真。

例子:

上面这个例子同时也包含了逻辑或的短路现象,在逻辑或中,因为编译器是从左往右扫描代码的,所以只要表达式左边为真,则不需要进行右边的判断。

4.3 逻辑与和逻辑或的笔试题

因为对于前置++和后置++我还没有讲,所以有基础的同学可以先看看,没基础的可以等我下期出了符号第二期在回来看这道题。

第一个逻辑与表达式,a 变量的初始值是 0 ,而且是后置++,先使用表达式的值,在进行自增,而逻辑与必须满足表达式两边的值都为真,但凡有一个为假都不会执行后面的表达式,所以只有 a 变量发生了变化。第二个逻辑或表达式,逻辑或只要表达式两边有一个为真即可,a++ 判断为假,会接着判断 ++b, 前置++ 是先自增在使用,所以 ++b 表达式为真,也就不会去执行后面表达式了,也就是说,只有 a和b变量的值发生了变化。

到此这篇关于C语言各种符号的使用介绍上篇的文章就介绍到这了,更多相关C语言符号内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言中无符号数和有符号数之间的运算

    C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了. unsigned int和int进行运算 直接看例子来说明问题吧 #include <iostream> using namespace std; int main() { int a = -1; unsigned int b = 16; if(a > b) cout<<"负数竟然大于正数了!\n";

  • 举例讲解C语言链接器的符号解析机制

    1. 符号分类 (1)全局符号:非静态全局变量,非静态函数 (2)外部符号:定义于其它模块,而被本模块引用的全局变量和函数 (3)本地符号:静态变量(包括全局和局部),静态函数 对于静态局部变量,编译器会为其生成唯一的名字.如x.fun1,x.fun2.本地符号对链接器来说是不可见的. 2. 符号决议 当编译器遇到一个不是本模块定义的符号时,会假设该函数由其它模块定义,并生成一个链接器符号表条目,交由链接器处理.如果链接器在它的任何输入模块都没有找到该符号,会给出一个类似undefined re

  • 详解C语言中的符号常量、变量与算术表达式

    C语言中的符号常量 在结束讨论温度转换程序前,我们再来看一下符号常量.在程序中使用 300.20 等类似的"幻数"并不是一个好习惯,它们几乎无法向以后阅读该程序的人提供什么信息,而且使程序的修改变得更加困难.处理这种幻数的一种方法是赋予它们有意义的名字.#define 指令可以把符号名(或称为符号常量)定义为一个特定的字符串: #define 名字 替换文本 在该定义之后,程序中出现的所有在 #define 中定义的名字(既没有用引号引起来,也不是其它名字的一部分)都将用相应的替换文本

  • C语言详细讲解注释符号的使用

    目录 一.注释规则 二.注释中一个有趣的问题 三.教科书型注释 四.迷惑型的注释 五.忽悠型注释 六.搞笑型注释 七.漂亮的程序注释 八.小结 一.注释规则 编译器在编译过程中使用空格替换整个注释 字符串字面量中的 // 和 /*...*/ 不代表注释符号 /*......*/ 型注释不能被嵌套 下面看一下这样一段代码: #include <stdio.h> int main() { int/*...*/i; char* s = "abcdefgh //hijklmn";

  • C语言中弱符号与弱引用的实际应用

    最近在学习<程序员的自我修养--链接.装载与库>时,get到了一个新的知识点:弱符号与弱引用.书中简短的介绍,让我了解到弱符号的含义以及使用方式.了解我的朋友,应该知道我喜欢将知识点与我们实际工作结合起来,在工作中利用起来,正所谓学以善用.根据我的理解,觉得利用弱符号的特性可以帮组我们在工作中编写出更加稳定,可复用,可组合的优秀代码.在此向大家分享. 符号重定义错误 在编码过程中,我们经常遇到符号重定义的错误.编译器会报如下错误: multiple definition of `xxx'; 这

  • C语言中无符号与有符号及相加问题

    C语言中无符号与有符号问题 unsigned char a[5] = { 12,36,96,128,182 }; a[]范围为0~256. 数组中数都有效. char a[5] = { 12,36,96,128,182 }; a[]范围为-128~127. 数组中128和182均无效. C语言中无符号数和有符号数相加问题 看个题: #include<stdio.h> int main() { unsigned int a=6; int b=-20; printf("%d\n"

  • C语言特殊符号的补充理解

    续接符 反斜杠"",他有两种最常见的功能,一就是续航功能,二就是我们提到反斜杠就会很敏感的转义字符. if("1==a&&2==b&&3==c) { printf("hello\n"); } 有以上的代码我们可以等价于 if("1==a&&\ 2==b&&\ 3==c) { printf("hello\n"); } 这里反斜线就起到了一个连接上下两行的代码,在咱看

  • C语言各种符号的使用介绍下篇

    目录 1.按位运算符 1.1 按位或( | )和按位与( & ) 1.2 按位异或( ^ ) 1.3 一个关于整型提升的问题 2.移位操作符 2.1 左移<< 右移>>操作符 2.2 习题练习 3.++和--的操作 3.1 基本操作 3.2 从汇编角度深入理解a++ 1.按位运算符 1.1 按位或( | )和按位与( & ) 上期我们讲到过逻辑或和逻辑与,他们得到的结果是真假值,但我们一定要区分清楚,按位运算符 "|" 和 "&

  • C语言详细解析有符号数与无符号数的表示

    目录 一.计算机中的符号位 二.有符号数的表示法 三.无符号数的表示法 四.signed 和 unsigned 五.小结 一.计算机中的符号位 数据类型的最高位用于标识数据的符号 最高位为1,表明这个数为负数 最高位为0,表明这个数为正数 下面看一段代码,用于判断数据的符号: #include <stdio.h> int main() { char c = -5; short s = 6; int i = -7; printf("%d\n", ( (c & 0x80

  • C语言各种符号的使用介绍上篇

    目录 1.注释符号 1.1 注释的基本注意事项 1.2 如何写出好的注释 2.接续符和转移符 2.1 续行功能 2.2 转义字符 3.单引号和双引号 3.1 基本概念 3.2 特殊情况 4.逻辑操作符 4.1 && (逻辑与) 4.2 || (逻辑或) 4.3 逻辑与和逻辑或的笔试题 1.注释符号 1.1 注释的基本注意事项 为了更好的演示我们下面的代码会在 Linux 平台下演示( \ 为续行符): 这段代码,哪一行是有问题的呢? 这里可能有小伙伴就有疑问了,为什么只有这一行出了问题呢?

  • C语言零基础彻底掌握预处理上篇

    目录 1.#define的深度认识 1.1 数值宏常量 1.2 字符串宏常量 1.3 用宏充当注释符号 1.4 用宏替换多条语句 1.5 宏定义的使用建议 2.#undef 撤销宏 2.1 宏的定义位置和有效范围 2.2 宏的取消 2.3 一道笔试题 1.#define的深度认识 1.1 数值宏常量 宏定义数值常量相信大家都不陌生,相信很多小伙伴用过,这里我们就简单的提一下,我们前面也讲过,#define 本质上是替换,它可以出现在代码的任何地方,也可以把任何东西都定义成宏,编译器会在预编译的时

  • C语言超详细文件操作基础上篇

    目录 一.为什么使用文件 二.什么是文件 1.什么是数据文件 2.什么是程序文件 3.文件名 三.文件的打开和关闭 1文件指针: 2.打开和关闭文件函数 (1)打开文件函数: (2)关闭文件函数 四.文件的顺序读写 1.写文件(fputc,操作一个字符) 2.读文件(fgetc,操作一个字符) 3.写文件(fputs,操作字符串) 4.读文件(fgets,操作字符串) 一.为什么使用文件 为了更好的把信息记录下来,对数据进行持久化的保存,这个时候我们就可以把数据写到文件里面去,使用文件我们可以将

  • C语言超详细讲解排序算法上篇

    目录 1.直接插入排序 2.希尔排序(缩小增量排序) 3.直接选择排序 4.堆排序 进入正式内容之前,我们先了解下初阶常见的排序分类 :我们今天讲前四个! 1.直接插入排序 基本思想:当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排 序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移! 直接插入排序的特性总结: 1. 元素集

  • C语言由浅入深讲解文件的操作上篇

    目录 为什么使用文件 什么是文件 文件名 关于文件的一些概念 文件函数 fopen fclose 实例代码 绝对路径 文件的打开方式 文件操作流程 为什么使用文件 前面写的通讯录,增加人数退出程序后,数据就会消失.此时数据是存放在内存中,下次运行通讯录程序的时候,数据又得重新录入,如果使用这样的通讯录就很难受. 所以文件操作就应运而生.数据持久化的方法有两种:1.把数据存放在磁盘文件2.存放到数据库使用文件我们们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化. 什么是文件 但是在程序设计中

  • C语言设计模式之命令模式介绍

    目录 介绍: 传统方式: 命令模式: 总结 介绍: ​ 命令模式是一种行为模式,它可以使代码解耦,便于维护: 假设我们现在要设计一个命令解析的模块: 传统方式: void func1(void) { printf("func1\r\n"); } void func2(void) { printf("func2\r\n"); } void func3(void) { printf("func3\r\n"); } void prase_cmd(cha

  • C语言二叉树的遍历示例介绍

    在本算法中先利用先序遍历创建了树,利用了递归的算法使得算法简单,操作容易,本来无printf("%c的左/右子树:", ch);的语句,但由于计算机需要输入空格字符来判断左右子树,为了减少人为输入的失误,特地加入这条语句,以此保证准确率. #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW 3 typedef int Status; typedef

  • C语言之循环语句详细介绍

    目录 前言 while语句 do...while语句 for语句 结语 前言 C语言中的循环结构是程序中的一个基本结构. 循环结构可以使我们写很少的语句,让计算机反复执行某一过程. C语言提供了while语句,do......while语句和for语句,可以组成各种不同形式的循环结构. while语句 while语句又称当型循环控制语句 while(表达式) 语句 表达式式循环条件 ,语句是循环体 当表达式的值为真(非0)时,执行循环体语句,否则终止循环.其特点是先判断,再执行. 例如:计算1+

  • C语言实现二叉树层次遍历介绍

    目录 什么是层次遍历? 那我们如何来实现这个算法呢? 主体代码: 总结 什么是层次遍历? 对于一颗二叉树来说,从根节点开始,按从上到下.从左到右的顺序访问每一个结点. 注:每一个结点有且访问一次. 那我们如何来实现这个算法呢? 实现原理: 对于二叉树来说,它是一个递归的定义,我们要实现层次遍历必然要满足从上到下.从左到右这个要求,从根结点出发,我们可以将所有意义上的根结点都存储在队列之中,那我们可以使用队列先进先出的特点来实现要求的遍历. 这里我们需要引用队列来实现. 主体代码: BiTree

随机推荐