01从c到c++
1.1 C++的发展历史
80年代贝尔实验室 本贾尼
83年 正式命名C++
87年 GNU制定了C++标准
92年 微软和IBM分别制定了C++标准
98年 ANSI ISO 制定了标准 C++98
03 ISO C++03
11 ISO C++11 C++0x
编译时注意: 使用c99,则需要指明,gcc *.c -std=c99
1.2 C与C++的关系
- C++包含了整个C,C是建立C++的基础
- C++是强类型的语言,对类型检查更加的严格
- C++扩展了C:
- c++提供了面向对象的编程机制
- 运算符重载
- 异常处理机制
- 泛型 模板(STL)
1.3 第一个C++程序
include <iostream>
int main()
{
std::cout << "Hello C++ !" << std::endl;
// 输出信息不再使用printf函数,
// cout 是标准输出流对象,std是标准名字空间
// << 是插入运算符,表示将其后面的数据插入到其前面的对象中,同时返回其前面的对象
// 满足后面继续插入的需求
return 0;
}
1.3.1 头文件
标准C++头文件不带.h结尾,头文件在/usr/include/c++/4.6/,可以使用C的头文件
标准C头文件建议去尾加头的方式去使用,例如:
#include<stdio.h> --------> #include<cstdio>
#include<string.h> -------> #include<cstring>
非标准C头文件 该怎么用就怎么用,如:
#include<pthread.h>
1.3.2 源文件
源文件建议用.cpp后缀名,也可以是.cc .cxx .c++等
1.3.3 编译器
使用g++编译器,如果使用gcc需要加一个链接库 -lstdc++
如果使用.c文件编写C++代码,则编译用下面的命令:
gcc -x c++ xx.c -lstdc++
g++的编译选项和gcc相同:
-c 编译
-o 输出名
-On 优化
-S 生成汇编
-E 预处理
-I 指定头文件的位置
-L 指定库的位置
-l 指定库名
-std 指定编译标准
-g 生成调试信息
1.4 命名空间
1.4.1 定义
就是把一组逻辑上相关的数据组织到一起的逻辑名
- 便于模块化
- 防止命名冲突
1.4.2 语法
namespace 空间名
{
//数据
int age;
void fun(){}
}
1.4.3 如何使用命名空间
- 在数据前加命名空间::即可
- 使用using声明
using 空间名::数据名; - 使用using namespace 指令
using namespace 空间名
例子:
#include <iostream>
using namespace std;
namespace IBM
{
int age = 60;
double salary = 5555;
void show();
}
namespace IBM
{
void show()
{
cout << "the age of IBM is " << age << ",the salary is "<< salary
<< endl;
}
}
namespace NJUST
{
int age = 50;
double salary = 4444;
void show()
{
cout << "the age of NJUST is " << age << ",the salary is " << salary << endl;
}
}
// using namespace IBM;
using IBM::show; // 易错
int main()
{
show();
NJUST::show();
return 0;
}
1.4.4 无名命名空间
如果一个数据没有定义在任何命名空间,则这个数据属于无名命名空间
namespace {
// 防止跨文件访问
int age = 23;
}
::数据;
例子:
#include <iostream>
using namespace std;
int g_data = 100;
namespace ns1
{
int g_data = 200;
void foo(void)
{
cout << ::g_data << endl;
}
//int g_data = 200;
}
int main()
{
using namespace ns1;
foo();
// cout << g_data << endl; // error
cout << ns1::g_data << endl; // 200
cout << ::g_data << endl; // 100
return 0;
}
1.4.5 命名空间嵌套
#include<iostream>
using namespace std;
namespace ns1
{
int a = 1;
namespace ns2
{
int a = 2;
void show()
{
cout << a <<endl;
}
namespace ns3
{
int a = 3;
void show()
{
cout << "this is ns3!" <<endl;
}
}
}
}
namespace ns4 = ns1::ns2::ns3;
int main()
{
ns1::ns2::show();
// ns1::ns2::ns3::show();
ns4::show();
return 0;
}
1.5 c++中的结构 联合 枚举
1.5.1 结构体
- 结构体的定义和C中的完全相同
- C++ 中使用结构体做为类型时,可以省略关键字 struct
- C++ 中的结构体中是可以定义函数的
例子:
#include<iostream>
#include<cstdio>
using namespace std;
/* 定义一个结构体表达 日期 */
struct Date
{
/* 成员变量 */
int year;
int month;
int day;
/* 成员函数 */
void show()
{
printf("%04d-%02d-%02d\n",year,month,day);
}
};
/* 设计一个函数 可以表现 一个日期变量的数据 */
void show_date(Date date)
{
printf("%04d-%02d-%02d\n",date.year,date.month,date.day);
}
int main()
{
Date date = {2016,2,4};
show_date(date);
date.year = 2020;
show_date(date);
date.show();
return 0;
}
1.5.2 联合体
- 联合体的定义和C中的完全相同
- C++ 表达联合这个类型时,可以省略union
- C++ 中支持匿名联合
例子:
#include<iostream>
using namespace std;
int main()
{
union
{
char data[4];
int x;
};
/* '0'----> 48 'A'--->65 'a'---->97*/
x = 0x31323334;
// x = 41424344; D C B A
//小端存储
for(int i =0;i<4;i++)
cout << data[i] <<" ";
// 4 3 2 1
return 0;
}
注:用这个程序可以查看大端字节或者小端字节序。
1.5.3 枚举类型
- C++表达枚举类型时可以省略关键字enum
- 可以把枚举赋值给整数,整数不可以赋值给枚举变量 (C++不允许,这里体现了C++对类型检查的严格)
枚举的例子:
#include<iostream>
using namespace std;
enum Direction
{
D_UP = 3,D_DOWN,D_LEFT,D_RIGHT
};
int main()
{
Direction dire = D_LEFT;
int x = dire;
cout << x << endl;
// dire = 2; // 不能把整数赋值给枚举类型的变量
// dire = (Direction)2;
return 0;
}
1.6 c++中的布尔类型 bool
- 取值有 false true
- C语言中需要导入一个头文件 #include<stdbool.h>
- 定义一个变量,除了下面的四个值之外,结果都是真的
- 0 '\0' NULL false - 有时候用bool 类型 表达整数 真就是1 假就是0
1.7 函数重载
1.7.0 C++中的函数
- C++中的函数的参数列表严格匹配无参代表没有任何参数,void依然可以用
int foo(void){}// c++ 可以去掉void - C++中不再支持函数的隐式声明调用函数, 必须提前声明或者定义
- 函数的返回值类型不能省略,main函数除外
1.7.1 在同一作用域中,函数名相同,参数列表不同的函数,构成重载(overload)关系
参数列表不同:参数的个数、类型、顺序
1.7.2 举例
使用函数指针,调用重载的函数
#include <iostream>
using namespace std;
int add (int x, int y )
{
cout << "add(int ,int )"<< endl;
return x + y;
}
double add(int x, double y)
{
cout << "add(int ,double )" << endl;
return x + y;
}
int main()
{
int x = 3;
double y = 4.0;
add(x, y);
int (*p) (int ,int );
p = add;
p(2,3);
return 0;
}
1.7.3 函数重载的原理
- C编译器生成函数调用名时只考虑函数名
- C++编译器生成函数名时不但考虑函数名,而且考虑参数列表
1.7.4 解决跨编译器调用的问题
extern "C" int getmax(int x,int y);
例子:
func.c
#include<stdio.h>
int getmax(int x,int y)
{
printf("getmax is c function!\n");
return x>y?x:y;
}
extern.cpp
#include<iostream>
using namespace std;
// 告诉g++ 编译器 按照C语言编译器生成调用函数名
extern "C" int getmax(int x,int y);
// 分别用gcc 编译func,g++编译extern.c
// gcc -c func.c
// g++ -c extern.c
// g++ func.o exten.o
// ./a.out
int main()
{
// _Z6getmaxii
getmax(20,30);
return 0;
}
1.8 内联函数
1.8.1 可以把函数的二进制代码直接复制到调用位置
这样减少了开栈和清理栈的开销
1.8.2 如何实现
#define GETMAX(X,Y) ((X)>(Y)?(X):(Y))
inline int getmax(int x,int y)
{
return x>y ?x:y;
}
1.8.3
小函数 频率调用 适合内联
大函数 稀少调用 不适合内联
递归函数 不能内联
inline 只是一种请求 请求成功就按照内联调用 请求不成功 就按照普通函数调用
1.9 参数哑元
1.9.1 如果一个参数只有类型 没有参数名 则叫哑元
1.9.2 作用
让参数列表匹配更加严格
保持函数的向前兼容
void encode(int pkey);
void decode(int skey);
void decode(int ); // 新函数
区分函数
++ 默认前++;
operator++();
operator++(int);
1.10 参数的默认值
1 如果一个函数的参数设定了默认值,则调用这个函数时,这个参数可以不传值,如果对这个参数传入值,则传入的值会改变为这个值
2 语法
// void foo(int a = 1,int b,int c = 0); // error
参数的默认值必须靠右
函数声明和实现分开时 默认值在声明时指定
举例:
/* 设计一个函数 打印一个整数数组 默认打印整数数组的前5个数据 分割符号默认使用逗号 */
#include<iostream>
using namespace std;
void print_array(int* a,int n = 5,char c = ',')
{
for(int i=0;i<n;i++)
{
if(i == (n-1))
cout << a[i]<<endl;
else
{
cout << a[i] << c ;
}
}
}
int main()
{
int a[] = {34,23,55,321,54,67,34,45};
print_array(a);
return 0;
}
c++中的动态内存分配
new delete
类型 *指针名 = new 类型;
int *p = new int ;
int *p2 = new int(100);
申请多个对象的空间
new[] delete[]
类型 *p = new 类型[n] 申请n个
定位内存分配
int *p = new(data)int[23];
c++中的类型转换运算符
static_cast<类型>(变量)
在某一个方向上 可以做隐式类型转换
int* pi;
void* pv = pi;
dynamic_cast<类型>(变量)
适合具有多态性的父子类之间
const_cast<类型>(变量)
用来去掉const修饰
reinterpret_cast<类型>(变量)
重新解释内存 最接近C语言的强制类型转换
整数变指针
指针变整数
c++之父给c程序员的建议
1、尽量少使用宏 const enum(定义常量)
2、用inline代替带参的宏
3、用namespace 避免命名冲突
4、变量随时用随时定义 以保证变量的初始化
5、尽量避免使用强制类型转换 如果要进行强制类型转换 尽量使用
6、多用new delete 少使用malloc free
7、少使用c 风格字符串 多使用string 类型;
8、逐渐建立面向对象的编程思想
01从c到c++的更多相关文章
- 01.SQLServer性能优化之----强大的文件组----分盘存储
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...
- 用Kotlin创建第一个Android项目(KAD 01)
原文标题:Create your first Android project using Kotlin (KAD 01) 作者:Antonio Leiva 时间:Nov 21, 2016 原文链接:h ...
- Java企业实训 - 01 - Java前奏
前言: 虽然个人专攻.NET方向,不过由于个人是干教育行业的,方方面面的东西,不能说都必须精通,但肯定多少都会涉及到. 一个菜鸟学员,从啥都不会,经过一步步学习,最后到企业上手掌管一个模块甚至一个项目 ...
- Node.js 教程 01 - 简介、安装及配置
系列目录: Node.js 教程 01 - 简介.安装及配置 Node.js 教程 02 - 经典的Hello World Node.js 教程 03 - 创建HTTP服务器 Node.js 教程 0 ...
- 0042 MySQL学习笔记-入门--01
基本概念: 数据库DB(database): 数据的仓库,数据的集合,是数据的一种结构化的存储 数据库管理系统DBMS(database management system): 管理数据库的一套软件 ...
- Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录
一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...
- ArtifactTransferException: Failure to transfer org.apache.openejb:javaee-api:jar:5.0-1
最近在myeclipse上创建maven类型的web项目的时候,出现了一个错误. ArtifactTransferException: Failure to transfer org.apache.o ...
- Python学习--01入门
Python学习--01入门 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.和PHP一样,它是后端开发语言. 如果有C语言.PHP语言.JAVA语言等其中一种语言的基础,学习Py ...
- 异步编程系列第01章 Async异步编程简介
p { display: block; margin: 3px 0 0 0; } --> 2016.10.11补充 三个月过去了,回头来看,我不得不承认这是一系列失败的翻译.过段时间,我将重新翻 ...
- 【干货分享】前端面试知识点锦集01(HTML篇)——附答案
一.HTML部分 1.浏览器页面有哪三层构成,分别是什么,作用是什么? 构成:结构层.表示层.行为层分别是:HTML.CSS.JavaScript作用:HTML实现页面结构,CSS完成页面的表现与风格 ...
随机推荐
- JAVAWEB学习总结 SERVLET开发(二)
一.ServletConfig对象 1.1.配置servlet初始化参数 在servlet的配置文件中web.xml中,可以使用一个或多个<init-param>标签为servlet配置一 ...
- oracle xmltype导入并解析Excel数据 (一)创建表与序
表说明: T_EXCEL_IMPORT_DATASRC: Excel数据存储表,(使用了xmltype存储Excel数据) 部分字段说明: BUSINESSTYPE: Excel模板类型,一个Exce ...
- OD调试17
程序先出现一个nag 然后出现主窗口 然后出现第二个nag窗口 我们查个壳 没有壳 那就载入OD看看,继续用调用堆栈的方法 发现一直执行用的都是这一个call,最后执行到程序结束.之 ...
- web页面放到手机页面,缩放问题
有时候写页面样式不规范,很多页面元素写死尺寸时,web页面尺寸比较大放到移动端访问时,就背缩放了,div或者按钮变得好小 可以加段js,效果会好点 <script> ! function( ...
- C# BackgroundWorker的使用
文章摘自:http://www.cnblogs.com/tom-tong/archive/2012/02/22/2363965.html BackgroundWorker 可以用于启动后台线程. 主要 ...
- magento的url中 去掉多余的目录层级
有时我们需要仅仅显示一层目录的URL路径.而不要出现多个路径的现实,我们可以用以下方法修改: Edit /app/code/core/Mage/Catalog/Model/Url.php 找到632 ...
- mybatis调用视图和存储过程
现在的项目是以Mybatis作为O/R映射框架,确实好用,也非常方便项目的开发.MyBatis支持普通sql的查询.视图的查询.存储过程调用,是一种非常优秀的持久层框架.它可利用简单的XML或注解用语 ...
- 前端开发薪资之各地区对比(图文分析)(share)
发现最近大家都在关注有关前端开发的薪资问题,不同地方各有差异,今天我就总结一下发出来方便大家的查阅.(2014年) 前面给大家介绍了关于前端开发需要学习的东西,根据你掌握的技能程度,薪水是不一样的.d ...
- datatables增删改查的实现
学习可参考:http://www.guoxk.com/node/jquery-datatables http://yuemeiqing2008-163-com.iteye.com/blog/20069 ...
- oracle数据迁移、备份等
exp db 或者数据泵. 或者ETL工具