C++Notes03_数据类型(Data Type)
来源:互联网 发布:域名解析隐藏端口号 编辑:程序博客网 时间:2024/06/06 01:40
C++Notes03_数据类型(Data Type)
- CNotes03_数据类型Data Type
- 一struct
- 二namespace
- 三string
- 四vetor
- 五void
- 六类型转换
- 七运行时内存布局Runtime memory layout
- 八指针与引用Reference
- 九全局数据Global Data
- 十静态数据Static Data
C++数据类型新增或升级
一.struct
c形式1
变量声明时需加struct关键字
#include <stdio.h>#include <string.h>struct SStudent { char cName[ 20 ]; int nAge; void (*pfnShowInfo)(struct SStudent s);};void showName(struct SStudent s){ printf("----%s----\n",s.cName);}void showAge(struct SStudent s){ printf("----%d----\n",s.nAge);}void main(){ struct SStudent s1; memset(s1.cName , 0 , sizeof( s1.cName) ); strcat( s1.cName , "SE0600"); s1.nAge = 15 ; s1.pfnShowInfo = showName; s1.pfnShowInfo(s1); s1.pfnShowInfo = showAge; s1.pfnShowInfo(s1);}
c形式2
使用typdef重定义类型
#include <stdio.h>#include <string.h>typedef struct SS{ char cName[ 20 ]; int nAge; void (*pfnShowInfo)(struct SS); //Type redefine not to take effect }SStudent;void showName(SStudent s){ printf("----%s----\n",s.cName);}void showAge(SStudent s){ printf("----%d----\n",s.nAge);}void main(){ SStudent s1; memset(s1.cName , 0 , sizeof( s1.cName) ); strcat( s1.cName , "SE0600"); s1.nAge = 15 ; s1.pfnShowInfo = showName; s1.pfnShowInfo(s1); s1.pfnShowInfo = showAge; s1.pfnShowInfo(s1);}
C++形式
#include <iostream>#include <cstring>using namespace std;struct SStudent { char cName[20]; int nAge; void (*pfnShowInfo)(SStudent); void show(char *pcName); void show(int nAge){ cout<<"[Struct Function Call]Age : "<<nAge<<endl;}};void show(SStudent s){ cout<<"[Function Pointer Call]Name : "<<s.cName<<endl;}void showAge(SStudent s){ cout<<"[Function Pointer Call]Age : "<<s.nAge<<endl;}void SStudent::show(char *pcName){ cout<<"[Struct Function Call]Name : "<<cName<<endl;}int main(){ SStudent s1; memset( s1.cName , 0 , sizeof( s1.cName )); strcat( s1.cName , "SE0600"); s1.nAge = 15; s1.show(s1.cName); s1.show(s1.nAge); s1.pfnShowInfo = show; s1.pfnShowInfo(s1); s1.pfnShowInfo = showAge; s1.pfnShowInfo(s1); return 0;}
C++ stuct特性
C++ struct与C++ class极为类似,区别:
成员的默认访问权限
struct 默认是public
class 默认是 private
默认的继承
struct 默认是public
class默认是private
建议struct成员只包含基本数据类型,其它特性用class实现.
二.namespace
作用
组织和重用代码,制定标识符的使用范围,解决同名冲突。
使用
在声明一个命名空间时,花括号内不仅可以包括变量,而且还可以包括以下类型:
- 变量(可以带有初始化)
- 常量
- 函数(可以是定义或声明)
- 结构体
- 类
- 模板
- 命名空间(在一个命名空间中又定义一个命名空间,即嵌套的命名空间)。
namespace nsl{ const int RATE=0.08; //常量 doublepay; //变量 doubletax() //函数 {return a*RATE;} namespacens2 //嵌套的命名空间 {int age;}} 如果想输出命名空间nsl中成员的数据,可以采用下面的方法:cout<<nsl::RATE<<endl;cout<<nsl::pay<<endl;cout<<nsl::tax()<<endl;cout<<nsl::ns2::age<<endl; //需要指定外层的和内层的命名中间名
Sample
#include <iostream>namespace NSBus{ const int nMAX_CAPCITY = 50; int nCurTripDistance = 0; void setTripDistance(int nTripDistance); int getTripDistance(){ return nCurTripDistance ; }}void NSBus::setTripDistance(int nTripDistance){ nCurTripDistance = nTripDistance;}namespace NSCar{ const int nMAX_CAPCITY = 5; int nCurTripDistance = 0; void setTripDistance(int nTripDistance); int getTripDistance(){ return nCurTripDistance ; }}void NSCar::setTripDistance(int nTripDistance){ nCurTripDistance = nTripDistance;}namespace //匿名命名空间,作用域为当前文件作用域,可解决多文件类型重定义.相当于static{ int nPersons = 100;}using namespace std;int main(){ const int nMAX_CAPCITY = 100; cout<<"[NSBus] Max Capacity "<<NSBus::nMAX_CAPCITY<<endl; cout<<"[NSCar] Max Capacity "<<NSCar::nMAX_CAPCITY<<endl; cout<<"[Main] Max Capacity "<<nMAX_CAPCITY<<endl; namespace NSAutoMobile = NSCar; //set namespace alias cout<<"[NSAutoMobile] Max Capacity "<<NSAutoMobile::nMAX_CAPCITY<<endl; using namespace NSBus; //set NSBus globle use nCurTripDistance = 5000; cout<<"[NSBus] TripDistance "<<NSBus::nCurTripDistance<<endl; return 0;}
三.string
四.vetor
vector是C++标准模板库中的部分内容,属于std命名域,头文件vector
参考链接 http://blog.chinaunix.net/uid-26000296-id-3785610.html
声明(构造)
vector // 创建一个空的vector。vector c1(c2) // 复制一个vectorvector c(n) // 创建一个vector,含有n个数据,数据均已缺省构造产生vector c(n, elem) // 创建一个含有n个elem拷贝的vectorvector c(beg,end) // 创建一个含有n个elem拷贝的vector
成员函数
c.assign(beg,end) //将[begin; end)区间中的数据赋值给cc.assign(n,elem) //将n个elem的拷贝赋值给c。c.at(idx) //传回索引idx所指的数据,如果idx越界,抛出out_of_range。c.back() // 传回最后一个数据,不检查这个数据是否存在。c.begin() // 传回迭代器中的第一个数据地址。c.capacity() // 返回容器中数据个数。c.clear() // 移除容器中所有数据。c.empty() // 判断容器是否为空。c.end() // 指向迭代器中末端元素的下一个,指向一个不存在元素。c.erase(pos) // 删除pos位置的数据,传回下一个数据的位置。c.erase(beg,end) //删除[beg,end)区间的数据,传回下一个数据的位置。c.front() // 传回第一个数据。get_allocator // 使用构造函数返回一个拷贝。c.insert(pos,elem) // 在pos位置插入一个elem拷贝,传回新数据位置。c.insert(pos,n,elem) // 在pos位置插入n个elem数据。无返回值。c.insert(pos,beg,end) // 在pos位置插入在[beg,end)区间的数据。无返回值。c.max_size() // 返回容器中最大数据的数量。c.pop_back() // 删除最后一个数据。c.push_back(elem) // 在尾部加入一个数据。c.rbegin() // 传回一个逆向队列的第一个数据。c.rend() // 传回一个逆向队列的最后一个数据的下一个位置。c.resize(num) // 重新指定队列的长度。c.reserve() // 保留适当的容量。c.size() // 返回容器中实际数据的个数。c1.swap(c2)swap(c1,c2) // 将c1和c2元素互换。同上操作。operator[] // 返回容器中指定位置的一个引用。
遍历
循环控制
for( int i = 0 ; i < v.size() ; i++ ){ cout<<v[i]<<" "; //不做越界检查 cout<<v.at(i)<<" "; //越界抛出out_of_range异常}
迭代器
for( vector<int>::iterator it != v.begin() ; i < v.end() ; i++ ) cout<<*it<<" ";
Sample
//=====================================// f0311.cpp// 若干个向量按长短排序//=====================================#include<iostream>#include<fstream>#include<sstream>#include<vector>using namespace std;//-------------------------------------typedef vector<vector<int> > Mat;Mat input();void selectionSort(Mat& a);void print(const Mat& a);void bubbleSort(Mat &a);//-------------------------------------int main(){ Mat a = input(); cout<<"File Content : "<<endl; print(a); selectionSort(a); cout<<"selectionSort Result(ASC) : "<<endl; print(a); cout<<"bubbleSort Result(DESC) : "<<endl; bubbleSort(a); print(a); return 0;}//------------------------------------Mat input(){ ifstream in("aaa.txt"); Mat a; for(string s; getline(in, s); ){ vector<int> b; istringstream sin(s); //包含在SStream头文件中,流操作 for(int ia; sin>>ia; ) b.push_back(ia); a.push_back(b); } return a;}//------------------------------------void bubbleSort( Mat &a ){ for( int i = 0 ; i < a.size() ; i++ ){ for ( int j = 0; j < a.size() - i - 1 ; j++) { if( a.at( j ).size() < a.at( j + 1 ).size() ) swap( a.at( j + 1 ) , a.at( j ) ); } }}void selectionSort(Mat &a){ for (int i = 0; i < a.size() - 1 ; i++) { int nMinSize = i ; for (int j = i + 1 ; j < a.size(); j++) { if( a.at( nMinSize ).size() > a.at( j ).size() ) nMinSize = j; } if( nMinSize != i ) swap( a.at( nMinSize ) , a.at( i ) ); }}void print(const Mat& a){ for(int i=0; i<a.size(); ++i){ for(int j=0; j<a.at(i).size(); ++j) cout<<a.at(i).at(j)<<" "; cout<<endl; }}
五.void *
void*表示“空类型指针”,与void不同,void*表示“任意类型的指针”或表示“该指针与一地址值相关,但是不清楚在此地址上的对象的类型”.
为什么不用void表示任意类型的数据呢?
大家都知道,C/C++是静态类型的语言,定义变量就会分配内存,然而,不同类型的变量所占内存不同,如果定义一个任意类型的变量,如何为其分配内存呢?
所以,C、C++中没有任意类型的变量。但是,所有指针类型的变量,无论是int*、char*、string*、Student*等等,他们的内存空间都是相同的,所以可以定义“任意类型的指针”。void*指针只支持几种有限的操作:
与另一个指针进行比较;向函数传递void指针或从函数返回void*指针;
给另一个void*指针赋值。不允许使用void*指针操作它所指向的对象,例如,不允许对void*指针进行解引用。不允许对void*指针进行算术操作
#include <iostream>int main(){ using namespace std; void *pc = 0 ; //声明void(无类型或叫通用性)指针pc int i = 123; char c = 'a'; pc = &i; //将存放整型数123的变量i的地址赋给void型指针pc cout << *(int *) pc << endl; //输出指针值123,要进行整型数类型转换 pc = &c; //将存放字符a的变量c的地址赋给void型指针pc cout << *(char *) pc <<endl; //输出指针值a,要进行字符型数类型转换 return 0;}
六.类型转换
类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,而这样的东西在c++程序里一大堆.所以c++为了克服这些缺点,引进了4新的类型转换操作符。
static_cast
编译期的转化,不能转换掉expression的const、volitale、或者__unaligned属性
所有内建类型对象之间的隐式转换都可用static_cast.
把空指针转换成目标类型的空指针用static_cast。
把任何类型的表达式转换成void类型用static_cast。
类层次间的上行转换和下行转换也可以用static_cast,但下行转换即当把基类指针或引用转换成子类表示时,由于没有动态类型检查,所以是不安全的.反之是安全的.
const_cast
编译期的转化,去除类型中的const 属性
dynamic_cast
运行期的转换,类层次间的上行转换和下行转换
dynamic_cast具有类型检查的功能,下行转换的效果跟static_cast是一样的,但下行转换比static_cast更安全。
dynamic_cast还支持交叉转换,两个类如果有共同的祖先,他们的指针就可以用dynamic_cast.
reinterpret_cast
任何指针都可以转换成其它类型的指针,可用于如char* 到 int*,或者One_class* 到 Unrelated_class* 等的转换,因此可能是不安全的。
七.运行时内存布局(Runtime memory layout)
一般而言,操作系统将程序装入内存后,将形成一个随时可以运行的进程空间,将进程空间分四个区域:
八.指针与引用(Reference)
指针限定
指针常量:相对于指针常量而言,指针值不能修改,如 int const *p;
常量指针:指向常量的指针的简称。如 const int *p;
const int a = 78;int b = 10;int c = 18;const int *ip = &a; //const修饰指向的实体类型---常量指针int *const cp = &b; //const修饰指针*cp-----指针常量int const *dp = &b; //指针常量const int* const icp = &c; //常量指针常量*ip = 87; //错:常量指针不能修改指向的常量,*ip只能做右值ip = &c; //ok:常量指针可以修改制针织*cp = 81; //ok:指针常量可以修改指向的实体cp = &b; //错:指针常量不能修改指针值,即便是同一个地址*icp = 33; //常量指针常量不能修改指向的常量icp = &b; //常量指针常量不能修改指针值int d = *icp; //ok
引用(Reference)
从逻辑上理解,引用就是一个别名(alias),引用定义时必须初始化.引用相当于一个隐形指针。
int someInt = 5;int &rInt = someInt;sample://=====================================// f0315.cpp// 引用及其地址//=====================================#include<iostream>using namespace std;//-------------------------------------int main(){ int int1 = 5; int& rInt = int1; cout<<"&int1: "<<&int1<<" int1: "<<int1<<endl; cout<<"&rInt: "<<&rInt<<" rInt: "<<rInt<<endl; int int2 = 8; rInt = int2; cout<<"&rInt: "<<&rInt<<" rInt: "<<rInt<<endl; //rInt的值改变,但是地址没变}//====================================
九.全局数据(Global Data )
全局数据就是在任何函数的外部声明或者定义的,起到所有函数都可以访问它的作用.
“一次定义原则”。.多次声明,但是只有有一次定义,声明形式是在定义形式前加extern.
全局数据在程序启动时初始化为0,如果定义时未初始化,默认为0.
十.静态数据(Static Data)
静态全局数据(Static Global Data)
内部链接性:只在本文件内可见,在其它程序文件中不可见.
静态局部数据(static Local Data)
静态局部变量驻留在全局数据区,默认初始值为0,仅在第一次调用时被初始化.
sample
//=====================================// f0709.cpp// 静态局部数据//=====================================#include<iostream>using namespace std;void func();int n = 1;int main(){ int a = 0 , b = -10; cout<<"a="<<a<<",b="<<b<<",n="<<n<<endl; func(); cout<<"a="<<a<<",b="<<b<<",n="<<n<<endl; func();}void func(){ static int a = 2; int b = 5; a += 2; b += 5; n += 12; cout<<"a="<<a<<",b="<<b<<",n="<<n<<endl;}/*outout:a=0,b=-10,n=1a=4,b=10,n=13a=0,b=-10,n=13a=6,b=10,n=25*/
- C++Notes03_数据类型(Data Type)
- data type : 数据类型
- MFC数据类型(Data Type)
- MFC数据类型(Data Type)
- MFC数据类型(Data Type)
- MFC数据类型(Data Type)
- MFC数据类型(Data Type)
- java 数据类型(data type)
- 抽象数据类型(Abstract Data Type)
- (C/C++)Windows Data Type
- Oracle 12C 新特性之扩展数据类型(extended data type)
- 第二节:原生数据类型 Primitive Data Type
- [Ant][StartWithAnt] 第六章 数据类型Data Type
- ADT(Abstract Data Type)抽象数据类型
- MySQL_数据库数据类型(data type)介绍
- Java基础:数据类型(Data type)
- 原生数据类型(Primitive Data Type)
- R tutorial 01 - Data type 数据类型
- VS Code --第二大React Native 编辑器
- PHP处理密码的几种方式
- 【LeetCode】476. Number Complement
- 文件倒排索引算法及其hadoop实现
- mysql诡异问题
- C++Notes03_数据类型(Data Type)
- Thread.interrupt 快速解读
- cell的线不贴边
- URL中 中文转码
- 欢迎使用CSDN-markdown编辑器
- 一个简单的本地存储操作,直接操作模型的方式操作缓存
- PHP 对象的存储与传输(序列化 serialize 对象)
- HTTP 1.1与HTTP 1.0的比较
- 使用pm2部署nodejs