上海网站建设公司指南,简单网页制作图片,湖南省建设厅纪检组长,抖音代运营策划方案文章目录 前言一、C关键字二、命名空间三、C输入输出四、缺省参数五、函数重载六、引用七、inline八、nullptr总结 前言 C是一种通用的、高级的、静态类型的编程语言#xff0c;它在20世纪80年代由丹尼斯里奇创建的C语言基础上发展而来。以下是C发展的一些重要里程碑。 1… 文章目录 前言一、C关键字二、命名空间三、C输入输出四、缺省参数五、函数重载六、引用七、inline八、nullptr总结 前言 C是一种通用的、高级的、静态类型的编程语言它在20世纪80年代由丹尼斯·里奇创建的C语言基础上发展而来。以下是C发展的一些重要里程碑。 1. 1983年Bjarne Stroustrup在贝尔实验室开发C语言最初命名为“C with Classes”。 2. 1985年第一个以C语言写成的编译器问世。 3. 1989年C语言的第一个正式标准发布其基础是C的前身“C with Classes”。 4. 1998年第二个C标准发布称为C98。这个标准引入了新的特性如命名空间namespace和异常处理exception handling。 5. 2003年第三个C标准发布称为C03。这个标准主要是修正了C98标准中的一些错误和缺陷。 6. 2011年第四个C标准发布称为C11。这个标准引入了许多新特性如自动类型推导auto、右值引用rvalue references和智能指针smart pointers。 7. 2014年第五个C标准发布称为C14。这个标准是C11的扩展添加了一些新特性如泛型lambda表达式generic lambdas和二进制字面量binary literals。 8. 2017年第六个C标准发布称为C17。这个标准进一步扩展了C14的功能包括结构化绑定structured bindings和模板参数推导template argument deduction。 9. 目前C20标准正在制定中预计将在2020年发布。这个标准包括一些重要的新特性如概念concepts和协程coroutines。 C的发展历程中越来越多的特性被添加进语言中使得C成为一种非常强大和灵活的编程语言。它在很多领域中都被广泛应用包括系统编程、嵌入式系统、游戏开发和科学计算等。 C兼容C语⾔绝⼤多数的语法所以C语⾔实现的hello world依旧可以运⾏C中需要把定义⽂件 代码后缀改为.cppvs编译器看到是.cpp就会调⽤C编译器编译linux下要用g编译不再是gcc #includeiostream
using namespace std;int main()
{cout hello world\n endl;return 0;
} 一、C关键字(C98)
C总计63个关键字C语言32个关键字 二、命名空间 在C/C中变量、函数和后面要学到的类都是大量存在的这些变量、函数和类的名称将都存 在于全局作用域中可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化 以避免命名冲突或名字污染namespace关键字的出现就是针对这种问题的 #include stdio.h
#include stdlib.h
int rand 10;
// C语言没办法解决类似这样的命名冲突问题所以C提出了namespace来解决
int main()
{printf(%d\n, rand);
return 0;
}
// 编译后后报错error C2365: “rand”: 重定义以前的定义是“函数” 1. 命名空间定义 定义命名空间需要使用到 namespace 关键字 后面跟 命名空间的名字 然 后接一对 { } 即可 { } 中即为命名空间的成员。 namespace shanshan
{// 命名空间中可以定义变量/函数/类型int rand 10;int Add(int left, int right){return left right;}struct Node{struct Node* next;int val;};
}//2. 命名空间可以嵌套
// test.cpp
namespace N1
{int a;int b;int Add(int left, int right){return left right;}namespace N2{int c;int d;int Sub(int left, int right){return left - right;}}
}//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
// ps一个工程中的test.h和上面test.cpp中两个N1会被合并成一个
// test.h
namespace N1
{int Mul(int left, int right){return left * right;}
} • 定义命名空间需要使⽤到namespace关键字后⾯跟命名空间的名字然后接⼀对{}即可{ }中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。 • namespace本质是定义出⼀个域这个域跟全局域各⾃独⽴不同的域可以定义同名变量所以下 ⾯的rand不在冲突了。 • C中域有函数局部域全局域命名空间域类域域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑所有有了域隔离名字冲突就解决了。局部域和全局域除了会影响 编译查找逻辑还会影响变量的声明周期命名空间域和类域不影响变量声明周期namespace只能定义在全局当然他还可以嵌套定义。 • 项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace不会冲突。 • C标准库都放在⼀个叫std(standard)的命名空间中。 2.命名空间使用
namespace shanshan
{// 命名空间中可以定义变量/函数/类型int a 0;int b 1;int Add(int left, int right){return left right;}struct Node{struct Node* next;int val;};
}int main()
{// 编译报错error C2065: “a”: 未声明的标识符printf(%d\n, a);return 0;
} 命名空间有以下三种使用方式 1.加命名空间名称及作用域限定符 2.使用 using 将命名空间中某个成员引入 3.使用 using namespace 命名空间名 int main()
{printf(%d\n, N::a);return 0;
}using N::b;
int main()
{printf(%d\n, N::a);printf(%d\n, b);return 0;
}using namespce N;
int main()
{printf(%d\n, N::a);printf(%d\n, b);Add(10, 20);return 0;
} 三、C输入输出 • iostream 是 Input Output Stream 的缩写 是标准的输⼊、输出流库定义了标准的输入、输出对象。 • std::cin 是 istream 类的对象它主要⾯向窄字符narrow characters (of type char)的标准输入流。 • std::cout 是 ostream 类的对象它 主要⾯向窄字符的标准输出流。 • std::endl 是⼀个函数流插⼊输出时相当于插⼊⼀个换⾏字符加刷新缓冲区。 • 是流插⼊运算符是流提取运算符。C语⾔还⽤这两个运算符做位运算左移/右移 • 使⽤C输⼊输出更⽅便不需要像printf/scanf输⼊输出时那样需要⼿动指定格式 C的输⼊ 输出可以⾃动识别变量类型(本质是通过函数重载实现的)其实最重要的是 C的流能更好的⽀持⾃定义类型对象的输入输出 。 • IO流涉及类和对象运算符重载、继承等很多⾯向对象的知识我们目前只能简单认识⼀下C IO流的⽤法。 • cout/cin/endl等都属于C标准库C标准库都放在⼀个叫std(standard)的命名空间中所以要 通过命名空间的使⽤⽅式去⽤他们。 • ⼀般⽇常练习中我们可以 using namespace std 实际项⽬开发中不建议using namespace std。 • 这⾥我们没有包含stdio.h也可以使⽤printf和scanf在包含iostream间接包含了。vs系列编译器是这样的其他编译器可能会报错。 四、缺省参数 • 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时如果没有指定实参 则采⽤该形参的缺省值否则使⽤指定的实参缺省参数分为全缺省和半缺省参有些地⽅把 缺省参数也叫默认参数 • 全缺省就是全部形参给缺省值半缺省就是部分形参给缺省值。C规定半缺省参数必须从右往左依次连续缺省不能间隔跳跃给缺省值。 • 带缺省参数的函数调⽤C规定必须从左到右依次给实参不能跳跃给实参。 • 函数声明和定义分离时缺省参数不能在函数声明和定义中同时出现规定必须函数声明给缺省值。 #include iostream
#include assert.h
using namespace std;
void Func(int a 0)
{cout a endl;
}
int main()
{Func(); // 没有传参时使⽤参数的默认值Func(10); // 传参时使⽤指定的实参return 0;
}
#include iostream
using namespace std;
// 全缺省
void Func1(int a 10, int b 20, int c 30)
{cout a a endl;cout b b endl;cout c c endl endl;
}
// 半缺省
void Func2(int a, int b 10, int c 20)
{cout a a endl;cout b b endl;cout c c endl endl;
}
int main()
{Func1();Func1(1);Func1(1,2);Func1(1,2,3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}
五、函数重载 C⽀持在同⼀作⽤域中出现同名函数但是要求这些同名函数的形参不同可以是参数个数不同或者 类型不同。这样C函数调⽤就表现出了多态行为使⽤更灵活。C语言是不⽀持同⼀作⽤域中出现同 名函数的。 #includeiostream
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout int Add(int left, int right) endl;return left right;
}
double Add(double left, double right)
{cout double Add(double left, double right) endl;return left right;
}
// 2、参数个数不同
void f()
{cout f() endl;
}
void f(int a)
{cout f(int a) endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{cout f(int a,char b) endl;
}
void f(char b, int a)
{cout f(char b, int a) endl;
}// 返回值不同不能作为重载条件因为调⽤时也⽆法区分
//void fxx()
//{}
//
//int fxx()
//{
// return 0;
//}
// 下⾯两个函数构成重载
// f()但是调⽤时会报错存在歧义编译器不知道调⽤谁
void f1()
{cout f() endl;
}
void f1(int a 10)
{cout f(int a) endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, a);f(a, 10);return 0;
} 六、引用
1.引用的概念与定义 引⽤不是新定义⼀个变量而是给已存在变量取了⼀个别名编译器不会为引⽤变量开辟内存空间 它和它引⽤的变量共⽤同⼀块内存空间。比如 孙悟空人称美猴王齐天大圣弼马翁孙行者斗战胜佛等。 类型 引⽤别名 引⽤对象; C中为了避免引⼊太多的运算符会复⽤C语⾔的⼀些符号比如前⾯的 和 这⾥引用也和取地址使用了同⼀个符号⼤家注意使⽤⽅法⻆度区分就可以。 #includeiostream
using namespace std;
int main()
{int a 0;// 引⽤b和c是a的别名int b a;int c a;// 也可以给别名b取别名d相当于还是a的别名int d b;d;// 这⾥取地址我们看到是⼀样的cout a endl;cout b endl;cout c endl;cout d endl;return 0;
}
2.引用的特性 • 引用在定义时必须初始化 • ⼀个变量可以有多个引用 • 引用⼀旦引用⼀个实体再不能引用其他实体 #includeiostream
using namespace std;
int main()
{int a 10;// 编译报错“ra”: 必须初始化引⽤//int ra;int b a;int c 20;// 这⾥并⾮让b引⽤c因为C引⽤不能改变指向// 这⾥是⼀个赋值b c;cout a endl;cout b endl;cout c endl;return 0;
} 3.引用的使用 • 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提⾼效率和改变引⽤对象时同时改变被引用对象。 • 引用传参跟指针传参功能是类似的引用传参相对更方便⼀些。 • 引用返回值的场景相对比较复杂我们在这⾥简单讲了⼀下场景还有⼀些内容后续类和对象章节 中会继续深⼊讲解。 • 引用和指针在实践中相辅相成功能有重叠性但是各有特点互相不可替代。C的引⽤跟其他 语⾔的引用(如Java)是有很⼤的区别的除了⽤法最⼤的点C引用定义后不能改变指向 Java的引⽤可以改变指向。 • ⼀些主要用C代码实现版本数据结构教材中使⽤C引⽤替代指针传参目的是简化程序 void Swap(int rx, int ry)
{int tmp rx;rx ry;ry tmp;
}
int main()
{int x 0, y 1;cout x y endl;Swap(x, y);cout x y endl;return 0;
} 七、inline • 用 inline 修饰的函数叫做内联函数编译时C编译器会在调⽤的地⽅展开内联函数这样调用内联 函数就需要建立栈帧了就可以提⾼效率。 • inline对于编译器而言只是⼀个建议也就是说你加了inline编译器也可以选择在调⽤的地方不展 开不同编译器关于inline什么情况展开各不相同因为C标准没有规定这个。inline适⽤于频繁 调⽤的短小函数对于递归函数代码相对多⼀些的函数加上inline也会被编译器忽略。 • C语⾔实现宏函数也会在预处理时替换展开但是宏函数实现很复杂很容易出错的且不⽅便调 试C设计了inline⽬的就是替代C的宏函数。 • vs编译器 debug版本下⾯默认是不展开inline的这样⽅便调试debug版本想展开需要设置⼀下 以下两个地⽅。 • inline不建议声明和定义分离到两个⽂件分离会导致链接错误。因为inline被展开就没有函数地 址链接时会出现报错。 八、nullptr NULL实际是⼀个宏在传统的C头⽂件(stddef.h)中可以看到如下代码 #ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif • C中NULL可能被定义为字⾯常量0或者C中被定义为⽆类型指针(void*)的常量。不论采取何种 定义在使⽤空值的指针时都不可避免的会遇到⼀些⿇烦本想通过f(NULL)调⽤指针版本的 f(int*)函数但是由于NULL被定义成0调⽤了f(int x)因此与程序的初衷相悖。f((void*)NULL); 调⽤会报错。 • C11中引⼊nullptrnullptr是⼀个特殊的关键字nullptr是⼀种特殊类型的字⾯量它可以转换 成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题因为nullptr只能被 隐式地转换为指针类型⽽不能被转换为整数类型。 总结 C与C语言之间有一些关键的区别 1. 类型支持C支持面向对象编程其中包含类、继承、多态等特性而C语言只支持过程化编程。这意味着C更加灵活和强大可以更好地组织和管理代码。 2. 标准库C提供了一个广泛的标准库包括容器、算法、输入输出、字符串处理等功能。C语言的标准库较小只包含一些基本的功能。 3. 异常处理C引入了异常处理机制可以捕获和处理程序运行中的异常。而C语言没有内置的异常处理机制需要使用传统的错误码和返回值来处理错误。 4. 函数重载C允许函数重载即在同一个作用域内可以定义多个同名函数但参数类型或参数个数不同。这使得C可以根据调用时的参数类型进行自动选择合适的函数。C语言不支持函数重载。 5. 名字空间C引入了命名空间的概念可以将变量和函数放在特定的命名空间中避免命名冲突。C语言没有命名空间的概念。 6. 构造函数和析构函数C中的类可以有构造函数和析构函数用于对象的初始化和清理。C语言没有类和对象的概念也没有构造函数和析构函数。 7. 引用C引入了引用的概念可以创建变量的别名。这使得C可以更方便地进行参数传递和对象引用。C语言没有引用的概念。 8. 模板C引入了模板的概念用于实现泛型编程。模板可以根据不同的类型生成相应的代码。C语言没有模板的概念。 总体上说C是在C语言的基础上扩展出来的增加了面向对象编程和其他一些功能。C可以兼容大部分C语言的代码但C语言无法兼容所有C的代码。