诚信网站认证怎么做,优化是什么工作,学生个人网页设计作品,免费建网站的app1、C概述
1 两大编程思想
c语言在c语言的基础上添加了面向对象编程和泛型编程的支持。c继承了c语言高效#xff0c;简洁#xff0c;快速和可移植的传统。
2 起源
与c语言一样#xff0c;c也是在贝尔实验室诞生的#xff0c;Bjarne Stroustrup(本贾尼斯特劳斯特卢普)在2…
1、C概述
1 两大编程思想
c语言在c语言的基础上添加了面向对象编程和泛型编程的支持。c继承了c语言高效简洁快速和可移植的传统。
2 起源
与c语言一样c也是在贝尔实验室诞生的Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)在20世纪80年代开发了这种语言。
3 移植性和标准
ANSI 在1998制定出C第一套标准2003年发布了c标准第二版(IOS/IEC 14882:2003)该版本对第一版修订了一些错误但并没有改变语言特性因此c98表示c98/c2003c不断发展。IOS标准委员会于2011年8月批准了新标准ISO/IEC 14882:2011该标准被称为c11与c98一样c11也新增了许多特性。也是非常常见的一个版本在C11基础上又出现了C14和C17
2、C初识
#include iostream //标准输入输出流 i - input 输入 o - output 输出 stream 流 相当于 stdio.h
using namespace std; //使用 标准 命名空间 //程序入口函数
int main()
{// cout 标准输出流对象// 左移 在C下有了新的寓意 用于在cout后拼接输出的内容 // endl --- end line 刷新缓冲区 并且换行 cout hello world endl;system(pause); //阻塞return EXIT_SUCCESS; //返回正常退出
}引入头文件 #include 标准输入输出流使用标准命名空间 using namespace std;标准输出流对象 cout hello world endl;面向对象三大特性封装、继承、多态
问题1c头文件为什么没有.h
在c语言中头文件使用扩展名.h将其作为一种通过名称标识文件类型的简单方式。但是c的用法改变了c头文件没有扩展名。但是有些c语言的头文件被转换为c的头文件这些文件被重新命名丢掉了扩展名.h(使之成为c风格头文件)并在文件名称前面加上前缀c(表明来自c语言)。例如c版本的math.h为cmath.
头文件类型约定示例说明c旧式风格以.h结尾iostream.hc程序可用c旧式风格以.h结尾math.hc/c程序可用c新式风格无扩展名iostreamc程序可用使用namespace std转换后的c加上前缀c,无扩展名cmathc程序可用可使用非c特性如namespace std
问题2using namespace std 是什么 ?
namespace是指标识符的各种可见范围。命名空间用关键字namespace 来定义。命名空间是C的一种机制用来把单个标识符下的大量有逻辑联系的程序实体组合到一起。此标识符作为此组群的名字。
问题3cout 、endl 是什么
cout是c中的标准输出流endl是输出换行并刷新缓冲区。
3、C对C的扩展
1 双冒号::作用域运算符
:: 代表作用域 如果前面什么都不添加 代表全局作用域
#define _CRT_SECURE_NO_WARNINGS
#includeiostream
//using namespace std;int atk 1000;
void test01()
{int atk 2000;std::cout atk atk std::endl;// ::代表作用域 如果前面什么都不添加 代表全局作用域std::cout 全局 atk ::atk std::endl;
}int main() {test01();system(pause);return EXIT_SUCCESS;
}2 namespace命名空间
准备函数
game1.h
#pragma once
#include iostream
using namespace std;namespace KingGlory
{void goAtk();
}game2.h
#pragma once
#include iostream
using namespace std;namespace LOL
{void goAtk();
}game1.cpp
#include game1.hvoid KingGlory::goAtk()
{cout 王者荣耀攻击实现 endl;
}game2.cpp
#include game2.hvoid LOL::goAtk()
{cout LOL攻击实现 endl;
}命名空间用途解决名称冲突
#define _CRT_SECURE_NO_WARNINGS
#includeiostream
using namespace std;
#include game1.h
#include game2.h//1、命名空间用途 解决名称冲突
void test01()
{KingGlory::goAtk();LOL::goAtk();
}
int main() {test01();system(pause);return EXIT_SUCCESS;
}命名空间下可以存放 变量、函数、结构体、类…
//2、命名空间下 可以放 变量、函数、结构体、类...
namespace A
{int m_A;void func();struct Person{};class Animal{};
}命名空间必须要声明在全局作用域 命名空间可以嵌套命名空
//4、命名空间可以嵌套命名空间
namespace B
{int m_A 10;namespace C{int m_A 20;}
}
void test03()
{cout B空间下的m_A B::m_A endl;cout C空间下的m_A B::C::m_A endl;
}命名空间是开放的可以随时将新成员添加到命名空间下
namespace B
{int m_A 10;
}namespace B
{int m_B 100;
}
void test04()
{cout B空间下的m_A B::m_A endl;cout B空间下的m_B B::m_B endl;
}命名空间可以匿名的
//6、命名空间可以是匿名的
namespace
{int m_C 1000;int m_D 2000;//当写的命名空间的匿名的相当于写了 static int m_C 1000; static int m_D 2000;
}void test05()
{cout m_C m_C endl;cout m_D ::m_D endl;
}命名空间可以起别名
//7、命名空间可以起别名
namespace veryLongName
{int m_E 10000;void func(){cout aaa endl;}
}void test06()
{namespace veryShortName veryLongName;cout veryShortName::m_E endl;cout veryLongName::m_E endl;}3 using声明以及using编译指令
using声明
using KingGlory::sunwukongId当using声明与 就近原则同时出现出错尽量避免
#define _CRT_SECURE_NO_WARNINGS
#includeiostream
using namespace std;namespace KingGlory
{int sunwukongId 1;
}void test01()
{int sunwukongId 2;//1、using声明//using KingGlory::sunwukongId ; //当using声明与 就近原则同时出现出错尽量避免cout sunwukongId endl;
}using编译指令
using namespace KingGlory;当using编译指令 与 就近原则同时出现优先使用就近当using编译指令有多个需要加作用域 区分
namespace KingGlory
{int sunwukongId 1;
}namespace LOL
{int sunwukongId 3;
}
void test02()
{//int sunwukongId 2;//2、using编译指令using namespace KingGlory;using namespace LOL;//当using编译指令 与 就近原则同时出现优先使用就近//当using编译指令有多个需要加作用域 区分cout KingGlory::sunwukongId endl;cout LOL::sunwukongId endl;
}注意使用using声明或using编译指令会增加命名冲突的可能性。也就是说如果有名称空间并在代码中使用作用域解析运算符则不会出现二义性。
4 检测增强
函数检测增强
函数的返回值形参类型函数调用参数个数
类型转换检测增强
char p (char )malloc(64) C下等号必须左右一致类型
//3、类型转换检测增强
void test02()
{char* p malloc(64);
}以上c代码c编译器编译可通过c编译器无法编译通过。
struct 增强
C可以在结构体中放函数创建结构体变量可以简化关键字struct
//1. 结构体中即可以定义成员变量也可以定义成员函数;;
struct Student {string mName;int mAge;void setName(string name) { mName name; }void setAge(int age) { mAge age; }void showStudent() {cout Name: mName Age: mAge endl;}
};//2. c中定义结构体变量不需要加struct关键字
void test01() {Student student;student.setName(John);student.setAge(20);student.showStudent();
}bool数据类型扩展
C才有bool类型代表真 --- 1 true 假 ---- 0 false。sizeof 1
//5、bool类型扩展 C语言下 没有这个类型 C有bool类型
bool flag true; // bool类型 代表 真和假 true ---- 真(1) false ---- 假(0)void test04()
{cout sizeof(bool) endl; //结果是1个字节//flag false;//flag 100; //将非0的数都转为1cout flag endl;
}// 结果
1
1三目运算符增强
//6、三目运算符增强
void test05()
{//?:int a 10;int b 20;printf(ret %d\n, a b ? a : b);(a b ? a : b) 100; // C下返回的是变量 a 100printf(a %d\n, a);printf(b %d\n, b);
}//结果
ret 20
a 100
b 205 const
const增强
C语言下
全局const 直接修改 失败 间接修改 语法通过运行失败局部 const 直接修改 失败 间接修改 成功 const int constA 10;int* p (int*)constA;*p 300;printf(constA:%d\n,constA);printf(*p:%d\n, *p);//结果
constA:300
*p:300C语言下
全局 const 和C结论一样局部 const 直接修改失败 间接修改 失败const可以称为常量可以用于数组内的常数。
void test05()
{const int constA 10;int* p (int*)constA;*p 300;cout constA: constA endl;cout *p: *p endl;
}//结果
constA:10
*p:300constA在符号表中当我们对constA取地址这个时候为constA分配了新的空间*p操作的是分配的空间而constA是从符号表获得的值。
对于基础数据类型如果用一个变量初始化const变量如果const int a b,那么也是会给a分配内存。 void test06()
{int b 10;const int constA b;int* p (int*)constA;*p 300;cout constA: constA endl;cout *p: *p endl;}//结果
constA:300
*p:300const 链接属性
1C语言下const修饰的全局变量默认是外部链接属性
同一个目录下两个文件
const int g_a 1000;
#define _CRT_SECURE_NO_WARNINGS
#includestdio.h
#includestring.h
#includestdlib.hint main() {extern const int g_a;printf(g_a %d\n, g_a);system(pause);return EXIT_SUCCESS;
}可以正常输出。
2C下const修饰的全局变量默认是内部链接属性
可以加extern 提高作用域
extern const int g_b 1000;//默认是内部链接属性 可以加关键字 extern 提高作用域
#define _CRT_SECURE_NO_WARNINGS
#includeiostream
using namespace std;int main(){extern const int g_b;cout g_b g_b endl;;system(pause);return EXIT_SUCCESS;
}const分配内存情况
对const变量 取地址 会分配临时内存使用普通变量 初始化 const变量const增强中已经举例对于自定义数据类型
//3、对于自定义数据类型
struct Person
{string m_Name;int m_Age;
};
void test03()
{const Person p;//p.m_Age 10;Person* pp (Person*)p;(*pp).m_Name Tom;pp-m_Age 10;cout 姓名 p.m_Name 年龄 p.m_Age endl;
}尽量用const代替define
define出的宏常量没有数据类型、不重视作用域
const和#define区别总结:
const有类型可进行编译器类型安全检查。#define无类型不可进行类型检查const有作用域而#define不重视作用域
6 引用
1简介
目的起别名语法 类型与原名类型必须一致 别名 原名引用必须要初始化引用一旦初始化后就不可以引向其他变量
void test02()
{int a 10;//int b; //引用必须要初始化int b a; //引用一旦初始化后就不可以引向其他变量int c 100;b c; // 赋值cout a a endl;cout b b endl;cout c c endl;
}//结果
a 100
b 100
c 1002建立对数组引用
①直接建立引用
int arr[10];
int(pArr)[10] arr;
②先定义出数组类型再通过类型 定义引用
typedef int(ARRAY_TYPE)[10];
ARRAY_TYPE pArr2 arr;
//对数组建立引用
void test03()
{//1、直接建立引用int arr[3];int(pArr)[3] arr;for (int i 0; i 3; i){arr[i] 100 i;}for (int i 0; i 3; i){cout pArr[i] endl;}printf(\n --------2------\n);//2、先定义出数组类型再通过类型 定义引用typedef int(ARRAY_TYPE)[3];//类型 别名 原名ARRAY_TYPE pArr2 arr;for (int i 0; i 3; i){cout pArr2[i] endl;}}3参数的传递方式
值传递地址传递引用传递
//1、值传递
void mySwap01(int a, int b)
{int temp a;a b;b temp;cout :::b b endl;*/
}//2、地址传递
void mySwap02(int* a, int* b)
{int temp *a;*a *b;*b temp;
}//3、引用传递
void mySwap03(int a, int b) // int a a; int b b;
{int temp a;a b;b temp;
}void test01()
{int a 10;int b 20;//mySwap01(a, b);//mySwap02(a, b);mySwap03(a, b);cout a a endl;cout b b endl;
}第一种其实没有实现交换功能。通过引用参数产生的效果同按地址传递是一样的。引用的语法更清楚简单
函数调用时传递的实参不必加“”符在被调函数中不必在参数前加“*”符
引用作为其它变量的别名而存在因此在一些场合可以代替指针。C主张用引用传递取代地址传递的方式因为引用语法容易且不易出错。
4注意事项
引用必须引一块合法内存空间不要返回局部变量的引用
int func()
{int a 10;return a;
}//引用注意事项
void test02()
{//int a 10; //1、引用必须引一块合法内存空间,这种就不能通过因为后面必须是变量名。//2、不要返回局部变量的引用int ref func();cout ref ref endl;cout ref ref endl;
}第一个能正常输出是因为程序做了优化保留实际这种做法是有潜在危险的。要想不取消需要就加上static,看下一个例子。
当函数返回值是引用时候那么函数的调用可以作为左值进行运算
int func2()
{static int a 10;return a;
}void test03()
{int ref func2();cout ref ref endl;cout ref ref endl;cout ref ref endl;cout ref ref endl;//当函数返回值是引用那么函数的调用可以作为左值func2() 1000;cout ref ref endl;
}5引用的本质
引用的本质在c内部实现是一个指针常量.
Type ref val; // Type* const ref val;c编译器在编译过程中使用常指针作为引用的内部实现因此引用所占用的空间大小与指针相同只是这个过程是编译器内部实现用户不可见。
void testFunc(int ref) {ref 100; // ref是引用转换为*ref 100
}
int main() {int a 10;int aRef a; //自动转换为 int* const aRef a;这也能说明引用为什么必须初始化aRef 20; //内部发现aRef是引用自动帮我们转换为: *aRef 20;cout a: a endl;cout aRef: aRef endl;testFunc(a);cout a: a endl;cout aRef: aRef endl;return EXIT_SUCCESS;
}6指针的引用
利用引用可以简化指针可以直接用同级指针的 引用 给同级指针分配空间
以下两个示例代码效果是一样的
struct Person
{int age;
};void allocateSpace(Person** p)
{//p指向指针的指针 *p 指针 指向的是person 本体 **p person本体*p (Person*)malloc(sizeof(Person));(*p)-age 10;
}void test01()
{Person* p NULL;allocateSpace(p);cout p.age p-age endl;
}
struct Person
{int age;
};void allocateSpace2(Person* pp) // Person * pp p;
{pp (Person*)malloc(sizeof(Person));pp-age 20;
}void test02()
{Person* p NULL;allocateSpace2(p);cout p.age p-age endl;
}7常量的引用
本质const int ref 10; // 加了const之后 本质 相当于写成 int temp 10; const int ref temp;当然一般不这么用。常量引用的使用场景修饰函数中的形参防止误操作
void test01()
{//int ref 10; //这种是不合法的const int ref 10; // 加了const之后 相当于写成 int temp 10; const int ref temp;int* p (int*)ref;*p 10000;cout ref endl; //可以被修改
}//常量引用的使用场景 修饰函数中的形参防止误操作
void showValue(const int a)
{//a 100000;cout a a endl;
}void test02()
{int a 100;showValue(a);
}//结果
1000
a 100推荐
MBA智库百科全球专业中文经管百科
中文维基百科 - 维基百科