当前位置: 首页 > news >正文

C/C++:程序环境和预处理/宏

程序的翻译环境和执行环境

在ANSI C的任何一种实现中,存在两个不同的环境。第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境,它用于实际执行代码。

编译和链接

一份源代码(比如test.c)需要通过编译,形成一份目标文件,然后与库连接起来,才能形成一份可执行程序test.exe。

编译的过程

编译的过程为:预处理(预编译)、编译、汇编。

预处理:在预处理阶段,源文件包含的头文件会被展开,注释会被去掉,宏会进行替换等等。注意此时还不算是运行了程序,因为还没形成可执行程序。

编译:在编译阶段会把C语言、C++语言等等翻译成汇编语言,会进行语法分析,词法分析,符号总汇,语义分析。其中的符号总汇,是把全局变量,函数名称总汇。

汇编:把汇编代码转化成二进制指令,形成符号表。符号表里面是函数名称和其对应的地址,如果该函数没有被定义,则会给一个无效地址。

链接

在此阶段,会合并段表,进行符号表的合并和重定位,将所有涉及的库链接起来。符号表的合并的作用是能够找到需要的函数、全局变量等等。

编译源文件的测试,我们可以在gcc下进行:

1. 预处理 选项 gcc -E test.c -o test.i
预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中。

2. 编译 选项 gcc -S test.c
编译完成之后就停下来,结果保存在test.s中。

3. 汇编 gcc -c test.c
汇编完成之后就停下来,结果保存在test.o中

程序的运行环境

程序执行的过程:

1. 程序必须先载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成

2. 程序的执行便开始。接着便调用main函数。

3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。

4. 终止程序。正常终止main函数;也有可能是意外终止

预处理

预定义符号

__FILE__
__LINE__
__DATE__
__TIME__
__STDC__

//进行编译的源文件
//文件当前的行号
//文件被编译的日期
//文件被编译的时间
//如果编译器遵循ANSI C,其值为1,否则未定义

这些预定义符号都是语言内置的。

#define

使用#define来定义标识符。语法为:

#define name stuff

#define MAX 1000
#define reg register //为 register这个关键字,创建一个简短的名字
#define do_forever for(;;) //用更形象的符号来替换一种实现
#define CASE break;case //在写case语句的时候自动把 break写上。
// 如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
date:%s\ttime:%s\n" ,\
__FILE__,__LINE__ , \
__DATE__,__TIME__ )

注意:在define定义标识符的时候,不要加上 ; 。

#define定义宏

#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。

宏的申明方式:#define name( parament-list ) stuff。其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中。

注意:

①参数列表的左括号必须与name紧邻。如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。

②在定义宏的时候,不要吝啬括号。

#include<stdio.h>
#define SQUARE(x) x*x  //(5+1) r = 5+1*5+1 == 11
#define SQUARE(x) (x)*(x) // (5+1)*(5+1) = 6*6 = 36
#define DOUBLE(x) (x)+(x)  //k == 6  s == 33
#define DOUBLE(x) ((x)+(x))//k == 60int main()
{int r = SQUARE(5+1);//宏是替换,不是计算再替换过去printf("%d\n", r);int k = DOUBLE(3);//6//这里需要括起来,因此,最好外面再括号一下int s = 10 * DOUBLE(3);//如果不括号 s = 10*(3)+(3)return 0;
}

#define替换规则

在程序中扩展#define定义符号和宏时,需要涉及几个步骤。

①在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。

②替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。

③最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程

注意:

①宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。

②当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

#define PRINT(N,X) printf("the value of "#N" is "#X"\n",N)
//#N,就是将a或b,转换成“a” “b”int main()
{int a = 2;PRINT(a,"%d");double b = 2.5;PRINT(b,"%.1lf");return 0;
}

 

##

##可以把位于它两边的符号合成一个符号。它允许宏定义从分离的文本片段创建标识符

利用##,我们可以将参数插入到字符串当中。

#define CAT(Class,num) Class##num
int main()
{int Class106 = 100;printf("%d\n", CAT(Class, 106));return 0;
}

 带副作用的宏参数

当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。

//有副作用的宏参数//什么副作用?
int main()
{int a = 10;int b = a + 1;int c = ++a;//副作用:导致a的值也变了return 0;
}#define MAX(a,b) ((a)>(b)?(a):(b))
int main()
{//int m = MAX(2, 3);int a = 5;int b = 4;int m = MAX(a++, b++);//   ((a++)>(b++)?(a++):(b++))//(5,4) ((5,使用后++,变6)>(4,使用后++,变为5)?(6,使用后++,7):(b,没使用))printf("%d\n", m);//6printf("%d\n", a);//7printf("%d\n", b);//5return 0;
}

宏和函数对比

宏通常被应用于执行简单的运算。比如在两个数中找出较大的一个:

//宏
#define MAX(a,b) ((a)>(b)?(a):(b))
//函数
int MAX(int a, int b)
{return (a > b ? a : b);
}

其实对于这样简单的任务,用宏来进行,会比使用函数的效率高。

原因有二:

①用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜一筹。

②更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏可以适用于整形、长整型、浮点型等可以用于>来比较的类型。宏是类型无关的。

宏有时候可以做函数做不到的事情。比如:宏的参数可以出现类型,但是函数做不到。
 

#define MALLOC(num, type) (type *)malloc(num * sizeof(type))
//使用宏MALLOC,灵活地使用不同的类型
MALLOC(10, int);//类型作为参数
MALLOC(10, double);//类型作为参数
//预处理器替换之后:
(int*)malloc(10 * sizeof(int));
(double*)malloc(10 * sizeof(double));//原本的malloc的使用,需要分开写
(int*)malloc(10 * sizeof(int)); 
(double*)malloc(10 * sizeof(double));

宏相对函数的缺点:

① 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。

②宏是没法调试的。

③宏由于类型无关,也就不够严谨。这一点,是宏的一把双刀刃,即使优点也是缺点。

④宏可能会带来运算符优先级的问题,导致程容易出现错。因此,不能吝啬括号。

总结宏和函数的对比:

属 性#define定义宏函数
代 码 长 度每次使用时,宏代码都会被插入到程序中。除了非常小的宏之外,程序的长度会大幅度增长函数代码只出现于一个地方;每
次使用这个函数时,都调用那个
地方的同一份代码
执 行 速 度更快存在函数的调用和返回的额外开
销,所以相对慢一些
操 作 符 优 先 级宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议宏在书写的时候多些括号。函数参数只在函数调用的时候求
值一次,它的结果值传递给函
数。表达式的求值结果更容易预
测。
带 有 副 作 用 的 参 数参数可能被替换到宏体中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果。函数参数只在传参的时候求值一
次,结果更容易控制。
参 数 类 型宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型。函数的参数是与类型有关的,如
果参数的类型不同,就需要不同
的函数,即使他们执行的任务是
不同的。
调 试宏是不方便调试的函数是可以逐语句调试的
递 归宏是不能递归的函数是可以递归的

宏命名的约定:

一般来说,一般都是英文全大写来命名宏。不过也有会采用小写,我们需要懂得分辨。

#undef

这条指令用于移除一个宏定义.

#define MAX 100
int main()
{printf("%d\n", MAX);
#undef MAXprintf("%d\n", MAX);//MAX被移除了,这里报错return 0;
}

条件编译

在编译一个程序的时候我们如果要将一条语句(一组语句)编译或者放弃是很方便的。因为我们有条件编译指令。

#include <stdio.h>
#define __DEBUG__  //当把这条宏定义注释掉,那么就不会执行printf
int main()
{int i = 0;int arr[10] = { 0 };for (i = 0; i < 10; i++){arr[i] = i; 
#ifdef __DEBUG__   printf("%d\n", arr[i]);//为了观察数组是否赋值成功。
#endif //__DEBUG__}return 0;
}

常见的条件编译指令:

#if //常量表达式
//...
#endif
//常量表达式由预处理器求值。
//如:
#define __DEBUG__ //1
#if __DEBUG__
//..
#endif//2.多个分支的条件编译
#if //常量表达式
//...
#elif //常量表达式
//...
#else
//...
#endif//3.判断是否被定义
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol//4.嵌套指令
#if defined(OS_UNIX)
#ifdef OPTION1
unix_version_option1();
#endif
#ifdef OPTION2
unix_version_option2();
#endif
#elif defined(OS_MSDOS)
#ifdef OPTION2
msdos_version_option2();
#endif
#endif

文件包含

 #include 指令可以使另外一个文件被编译。就像它实际出现于 #include 指令的地方一样。这种替换的方式很简单,那就是预处理器先删除这条指令,并用包含文件的内容替换。这样一个源文件被包含10次,那就实际被编译10次。很显然,这样是很不好的,如果不小心包含了多个同样的头文件,每个头文件里面有几千行代码,那么重复的代码就会非常的多。

因此,我们可以在头文件中加入条件编译:

#ifndef __TEST_H__
#define __TEST_H__
//头文件的内容
#endif //__TEST_H__

或者是:#pragma once

这样一来,就不会编译多次同样的源文件了。

对于头文件来说,有以下两种形式:

①#include <......>  :以<>来包含头文件名的,直接去标准路径下查找头文件、

②#include "......"    以""来包含头文件名的,先是去源文件的路径下寻找,找不到再去标准路径中找。这种效率比较低。

相关文章:

C/C++:程序环境和预处理/宏

程序的翻译环境和执行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境&#xff0c;它用于实际执行代码。 编译和链接 一份源代码(比如test.c)需要通过编译&#xf…...

什么是死锁?死锁产生的四个必要条件是啥?如何避免和预防死锁的产生?

点个关注&#xff0c;必回关 文章目录什么是死锁死锁产生的原因&#xff1a;1、系统资源的竞争2、进程运行推进顺序不当引起死锁产生死锁的四个必要条件&#xff1a;死锁的避免与预防什么是死锁 死锁是指两个或两个以上的线程在执行过程中&#xff0c;由于竞争资源或者由于彼此…...

工程管理系统源码-物料管理-工程项目管理系统-建筑施工管理软件

如今建筑行业竞争激烈&#xff0c;内卷严重&#xff0c;发展趋势呈现两极分化&#xff0c;中小微企业的生存空间被逐步压缩&#xff0c;利润逐年减少。事实证明&#xff0c;工地上粗放式的人管人管理模式已经落于时代&#xff0c;劳动力纠纷和物料浪费现象尤其普遍&#xff0c;…...

Roboguide与TIA V16通讯

软件需求:1. roboguide;2. TIA V16;3. KEPServer; 在之前的文章中介绍过KEPServer与TIA V16的通讯,此处不再介绍。接下来,介绍roboguide与KEPServer的仿真通讯。 创建一个roboguide项目。选择【外部设备】➡【添加外部设备】 选择【OPC Server】➡【OK】 OPC服务器名称命…...

利用PyTorch深度学习框架进行多元回归

目录前言数据加载数据转换模型定义模型训练模型评估模型保存与加载完整代码讨论参考文献前言 大多数数据科学家以往经常常是利用传统的机器学习框架sklearn搭建多元回归模型&#xff0c;随着深度学习和强化学习越来越普及&#xff0c;很多数据科学家尝试使用深度学习框架来进行…...

EBS常用接口开发

整理了一些工作中常用的Oracle EBS接口和API&#xff0c;最早是看着大神黄建华文档起来的&#xff0c;格式内容参考他的文档&#xff0c;加上一些自己开发的程序和经历而已。 PO PO接收、检验、入库、退货-InterfaceAPI_刘文钊1的博客-CSDN博客 基础数据 EBS物料、bom、工艺导入…...

【完整】UR机械臂逆运动学求解过程及c++代码实现

有任何问题请在评论区留言&#xff0c;我尽可能的回复大家 一. 逆运动学的求解需要以下数学运算 利用DH参数得到每个关节的变换矩阵&#xff1b;利用变换矩阵求出机械臂整个链的变换矩阵&#xff1b;求出末端位姿&#xff1b;利用已知末端位姿和整个链的变换矩阵&#xff0c;…...

68. Python的相对路径

68. Python的相对路径 文章目录68. Python的相对路径1. 知识回顾2. 什么是相对路径3. 相对路径的语法4. 查看相对路径的方法5. 写出所有txt文件的相对路径5.1 同目录5.2 上级目录6. 用相对路径读取txt文件6.1 读取旅游.txt6.2 读取旅游经费.txt6.3 读取笔记.txt和new.txt6.4 读…...

java数据类型

数据类型 类型分类&#xff0c;存储范围&#xff0c;字面量&#xff0c;默认值&#xff0c;类型转换 类型分类 存储范围 数据类型字节数表示范围byte1-128~127short2-32768~32767&#xff0c;正负3万左右int4-2147483648~2147483647&#xff0c;正负21亿左右long8-922337203…...

Kotlin 替换非空断言的几种方式

Kotlin 出现断言的两种情形 IDE java 与 kotlin 自动转换时&#xff0c;自动添加非空断言的代码Smart Cast 失效 代码展示&#xff1a; class JavaConvertExample {private var name: String? nullfun init() {name ""}fun foo() {name null;}fun test() {if (…...

2023年了,来试试前端格式化工具

在大前端时代&#xff0c;前端的各种工具链穷出不断&#xff0c;有eslint, prettier, husky, commitlint 等, 东西太多有的时候也是trouble&#x1f602;&#x1f602;&#x1f602;,怎么正确的使用这个是每一个前端开发者都需要掌握的内容&#xff0c;请上车&#x1f697;&…...

spring cloud 企业工程项目管理系统源码+项目模块功能清单

工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff1a;实现对数据字典标签的增删改查操作 2、编码管理&#xff1a;实现对系统编码的增删改查操作 3、用户管理&#xff1a;管理和查看用户角色 4、菜单管理&#xff1a;实现对系统菜单的增删改查操…...

TCP分片解析

本文目录什么是IP分片为什么会产生IP分片为什么要避免IP分片如何避免IP分片什么是IP分片 IP协议栈将TCP/UDP传输层要求它发送的&#xff0c;但长度大于发送端口MTU的一个数据包&#xff0c;分割成多个IP报文后分多次发送。这些分成多次发送的多个IP报文就是IP分片。 为什么会…...

开发了一款基于 Flask 框架的在线电影网站系统(附 Python 源码)

文章目录前言项目介绍源码获取运行环境安装依赖库项目截图首页展示图视频展示页视频播放页后台管理页整体架构设计图项目目录结构图前台功能模块图后台功能模块图本地运行图前言 今天我给大家分享的是基于 Python 的 Flask 框架开发的在线电影网站系统&#xff0c;大家平时需要…...

如何获得CSM--敏捷教练证书

1、什么是CSM&#xff1f;CSM即Certified Scrum Master,Scrum Master负责确保所有人都能正确地理解并实施Scrum&#xff0c;确保Scrum团队遵循Scrum的理论、实践和规则。Scrum Master是Scrum团队中的服务型领导&#xff0c;帮助Scrum团队外的人员了解他们如何与Scrum团队交互是…...

Java面试数据库

目录 一、关系型数据库 数据库权限 表设计及创建 表数据相关 数据库架构优化 二、非关系型数据库 redis 今天给大家稍微整理了一下&#xff0c;内容有数据表设计的三大范式原则、sql查询如何优化、redis数据的击穿、穿透、雪崩等...&#xff0c;以及相关的面试题&#xff0…...

关于进行vue-cli过程中的解决错误的问题

好久没发文章了&#xff0c;直到今天终于开始更新了&#xff0c;最近想进军全端&#xff0c;准备学习下vue&#xff0c;但是这东西真的太难了&#xff0c;我用了一天的时间来解决在配置中遇到的问题&#xff01;主要问题&#xff1a;cnpm文件夹和vue-cli文件夹的位置不对并且vu…...

Rockchip Linux USB Gadget

一:概述 USB Gadget 是运行在 USB Peripheral 上配置 USB 功能的子系统,正常可被枚举的 USB 设备至少有 3 层逻辑层,有些功能还会在用户空间多跑一层逻辑代码。Gadget API 就是具体功能和硬件底层交互的中间层。从上到下,逻辑层分布为: USB Controller: USB上最底层的软…...

Linux -文件系统操作与帮助命令

1、Linux -文件系统操作 df — 查看磁盘的容量 df -h —以人类可以看懂的方式显示磁盘的容量&#xff0c;易读 du 命令查看目录的容量 # 默认同样以块的大小展示 du # 加上 -h 参数&#xff0c;以更易读的方式展示 du -h-d 参数指定查看目录的深度&#xff1a; # 只查看 1…...

UMI 创建react目录介绍及配置

UMI 生成react项目目录介绍及配置 react项目目录介绍umi多种配置方案运行时配置app.ts 的使用 1、umi创建的项目目录大致如下 ├─package.json 配置依赖以及启动打包所需的命令 ├─.umirc.ts 配置文件&#xff0c;包含 umi 内置功能和插件的配置 ├── dist 打包后生成的…...

基于matlab使用机器学习和深度学习进行雷达目标分类

一、前言此示例展示了如何使用机器学习和深度学习方法对雷达回波进行分类。机器学习方法使用小波散射特征提取与支持向量机相结合。此外&#xff0c;还说明了两种深度学习方法&#xff1a;使用SqueezeNet的迁移学习和长短期记忆&#xff08;LSTM&#xff09;递归神经网络。请注…...

Protocol Buffers V3语法全解

目录protobuf介绍protobuf使用protoc命令语法定义消息类型指定字段类型分配字段编号指定字段规则添加更多消息类型注释保留字段从.proto文件生成了什么&#xff1f;值类型默认值枚举使用其他消息类型导入定义嵌套类型更新消息类型未知字段any任意类型oneofoneof 特性兼容性问题…...

MediaPipe之人体关键点检测>>>BlazePose论文精度

BlazePose: On-device Real-time Body Pose tracking BlazePose&#xff1a;设备上实时人体姿态跟踪 论文地址&#xff1a;[2006.10204] BlazePose: On-device Real-time Body Pose tracking (arxiv.org) 主要贡献: &#xff08;1&#xff09;提出一个新颖的身体姿态跟踪解决…...

CSS从入门到精通专栏简介

先让我们来欣赏几个精美的网站&#xff1a; Matt Brett - Freelance Web Designer and WordPress Expert ‎2022 Year in Review • Letterboxd NIO蔚来汽车官方网站 小米官网 Silk – Interactive Generative Art 大屏数据可视化 你是否也有过这样的“烦恼”&#xff1a; * …...

day01常用DOS命令

day01课堂笔记&#xff08;第一章 Java开发环境的搭建&#xff09; 1、常用的DOS命令 1.1、怎么打开DOS命令窗口 win键 r &#xff08;组合键&#xff09;&#xff1a;可以打开“运行”窗口 在运行窗口文本框中输入: cmd 然后回车 1.2、什么是DOS命令呢&#xff1f; 在DOS命令…...

Java设计模式-生成器模式(建造模式)

1.1定义 维基百科定义 生成器模式&#xff08;英&#xff1a;Builder Pattern&#xff09;是一种设计模式&#xff0c;又名&#xff1a;建造模式&#xff0c;是一种对象构建模式。 它可以将复杂对象的建造过程抽象出来&#xff08;抽象类别&#xff09;&#xff0c;使这个抽象…...

ansible的常用模块介绍

ansible 常用命令/usr/bin/ansible  #Ansibe AD-Hoc 临时命令执行工具&#xff0c;常用于临时命令的执行/usr/bin/ansible-doc #Ansible 模块功能查看工具/usr/bin/ansible-galaxy  #下载/上传优秀代码或Roles模块 的官网平台&#xff0c;基于网络的/usr/bin/ansible-playbo…...

你不会还不知道如何监测用户的网络是否在线吧?

我最近遇到一个需求&#xff0c;要给网站添加一个用户网络离线提醒。要求我们要实时监测用户的网络状态&#xff0c;当用户断网了&#xff0c;我们要立马给用户弹出一个断网提醒。 那你可能会问&#xff0c;为什么要做这么一个需求呢&#xff1f;用户断网了&#xff0c;网页不…...

ASM Quorum FailGroup RAC on Extended Distance Clusters

法定容错组&#xff0c;和它失去联系也不影响集群运行 参考&#xff1a; How to Manually Add NFS voting disk to an Extended Cluster using ASM in 11.2 (Doc ID 1421588.1) Mount Options for Oracle files when used with NFS on NAS devices (Doc ID 359515.1) RAC: Fre…...

VHDL语言基础-时序逻辑电路-触发器

目录 触发器&#xff1a; D触发器&#xff1a; 触发器的VHDL描述&#xff1a; 触发器的仿真波形如下&#xff1a;​编辑 时钟边沿检测的三种方法&#xff1a; 方法一: 方法二&#xff1a; 方法三&#xff1a; 带有Q非的D触发器&#xff1a; 带有Q非的D触发器的描述&am…...

做网站有没有前途/怎么去推广自己的网站

加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号&#xff1a;96933959 文件读取 os.File 封装了文件相关操作 os.File Pkg Doc 读写参数 文件打开模式&#xff1a; const (O_RDONLY int syscall.O_RDONLY // 只读模式打开文件O_WRONLY int syscall.O_WRONLY // 只写模式…...

南昌建站系统外包/今日小说搜索百度风云榜

最新的 Firefox 2 版本为 Firefox 2.0.0.14&#xff0c; Firefox 3 版本为 Firefox 3.0rc1。主流依然是 Firefox 2.0.0.14&#xff0c;但由于在不久的将来 Firefox 2 会升级到 Firefox 3&#xff0c;对于我们前端是好消息&#xff08;更好更优的功能&#xff09;&#xff0c;也…...

上海建网站制/教育机构退费纠纷找谁

第一个JSP实际上&#xff0c;JSP只是简单地将Java放到HTML网页中去而已。你可以将现有的HTML网页将它们的扩展名由“.html”改为“.jsp”&#xff0c;这是一个创建第一个JSP最好的方法。我们可以将上一个练习中的文件将它的扩展名由“.html”改为“.jsp”。然后在浏览器中装载新…...

专业做网站开发费用/怎么卸载windows优化大师

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼一股令楼主都战栗的气息压塌了苍穹&#xff0c;本屌丝来了&#xff01;本屌深邃的双眼中有无尽日月星辰&#xff0c;举手投足间竟有大道在共鸣。只见本屌动了&#xff0c;一只古朴的大手横跨无数楼层&#xff0c;直压楼主而来。2楼…...

电子商务知名网站/关键词整站优化

其实应该是两个神奇的工具一个是脑图&#xff0c;也叫思维导图&#xff0c;对于像我这样收不住思维的人再合适不过了而另一个就是他的得力工具FreeMind&#xff0c;还是开源的。文章来源:http://herald.seu.edu.cn/blog/shiningray/archive/2005/06/08/20613.aspx转载于:https:…...

贵州省兴义市建设局网站/网络推广的工作好做吗

前言 当代码中出现多重if-else语句或者switch语句时。弊端之一&#xff1a;如果这样的代码出现在多处&#xff0c;那么一旦出现需求变更&#xff0c;就需要把所有地方的if-else或者switch代码进行更改&#xff0c;要是遗漏了某一处&#xff0c;那么程序就会出错。弊端之二&…...