C/C++入门学习
C++博客
C++小白笔记:
1.简单的c++程序
1.1简单的C++程序helloworld #include "iostream"
//Iostream时iostream.h的加强版本,是为了与C语言做区别去掉了.h
using namespace std; //使用命名空间 std 标准的命名空间 (在这个命名空间中定义了很多标准定义)
void main01()
{
//printf(“hello….\n”); C语言实现
//cout 标准输出 黑屏幕,
//<< 左移操作符 在c++里面 功能的改造(增强)===>C++ 语言操作符重载
//endl = \n
cout << “hello….”<
#include<iostream>
using namespace std;//c++的命名空间
class circle //程序扫描到这儿是初始化变量,然后会对变量直接拿值
{
public:
double r;
double pi = 3.1415926;
double area = pi*r*r;
};
// 2010编译不通过 但是在2013编译器能编译通过,但是乱码
int main()
{
circle c1;
cout << “please input your r” << endl;
cin >> c1.r;
cout << c1.area << endl; //乱码
system("pause");
return 0;
}
分析:
总结:
从内存四区的角度,解释为什么会出现乱码
理解为什么需要成员函数:既然定义变量只能拿值,就定义成员函数,重新计算,调用啊
2程序设计方法的发展历程
1.>面向过程的结构化程序设计方法
设计思路
–自顶向下、逐步求精。采用模块分解与功能抽象,自顶向下、分而治之。
优点:
有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。
缺点:可重用性差、数据安全性差、难以开发大型软件和图形界面的应用软件
–把数据和处理数据的过程分离为相互独立的实体。
–当数据结构改变时,所有相关的处理过程都要进行相应的修改。
–每一种相对于老问题的新方法都要带来额外的开销。
–图形用户界面的应用程序,很难用过程来描述和实现,开发和维护也都很困难。
举例图形界面:比如菜单,打开有好多选项,需求随机,天生存在,用面向过程很难完成,用c++的多态容易做
2>面向对象的方法
将数据及对数据的操作方法封装在一起,作为一个相互依存、不可分离的整体——对象。
对同类型对象抽象出其共性,形成类。
类通过一个简单的外部接口,与外界发生关系。
对象与对象之间通过消息进行通信。
面向对象的基本概念 :封装,继承,多态
对象:根据现实社会的事物,抽象出一个类,然后把类实例化,变成对象
类
–
封装
也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
多态
多态是指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在一般类及其各个特殊类中具有不同的语义。
面向对象的软件工程
面向对象的软件工程是面向对象方法在软件工程领域的全面应用。它包括:
–面向对象的分析(OOA)
–面向对象的设计(OOD)
–面向对象的编程(OOP)
–面向对象的测试(OOT)
–面向对象的软件维护(OOSM)
总结:
面向过程程序设计:数据结构 + 算法
主要解决科学计算问题,用户需求简单而固定
特点:
分析解决问题所需要的步骤
利用函数实现各个步骤
依次调用函数解决问题
问题:
软件可重用性差
软件可维护性差
构建的软件无法满足用户需求
3 .C语言和C++语言关系
C语言是在实践的过程中逐步完善起来的
没有深思熟虑的设计过程
使用时存在很多“灰色地带”
残留量过多低级语言的特征
直接利用指针进行内存操作
C语言的目标是高效
最终程序执行效率的高效
当面向过程方法论暴露越来越多的缺陷的时候,业界开始考虑在工程项目中引入面向对象的设计方法,而第一个需要解决的问题就是:高效的面向对象语言,并且能够兼容已经存在的代码。
C语言 + 面向对象方法论===》Objective C /C++
C语言和C++并不是对立的竞争关系
C++是C语言的加强,是一种更好的C语言
C++是以C语言为基础的,并且完全兼容C语言的特性
总结:
学习C++并不会影响原有的C语言知识,相反会根据加深对C的认知;
学习C++可以接触到更多的软件设计方法,并带来更多的机会。
1)C++是一种更强大的C,通过学习C++能够掌握更多的软件设计方法
2)C++是Java/C#/D等现代开发语言的基础,学习C++后能够快速掌握这些语言
3)C++是各大知名软件企业挑选人才的标准之一
问题:学出C/C++的人,做底层,容易故步自封;Java程序员经常调用,学习速度快;如果c/c++程序员思想转过来,效率将特别高,势如破竹。
简单分析一个公司的产品开发需要的技术。
4 C++对C的加强
4.1 namespace命名空间
1 C++命名空间基本常识
所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
一 :和
#include "iostream"
using namespace std;//命名空间将全局作用域分成不同的部分
//1文件中iostream 没有引入标准的 std ; 需要我们程序员手工的写
//2 如果不写 using namespace std; 需要显示的引入std
void main31()
{
std::cout<<”namespace test”<
#include <iostream>
usi//C语言中的变量都必须在作用域开始的位置定义!!
//C++中更强调语言的“实用性”,所有的变量都可以在需要使用时再定义。
void main41()
{
int i;
printf("hello...\n");
int k;
i = 10;
k = 11;
printf("i:%d k:%d \n", i, k);
system("pause");
}
4.3 register关键字增强
void main42()
{
register int a = 0;
printf(“&a: %d \n”, &a); //不能在寄存器变量上取地址
for (int i=0; i<1000; i++) //不使用register也可能做优化
{
printf("i:%d \n", i);
}
system("pause");
}
4.4变量检测增强
/*
在C语言中,重复定义多个同名的全局变量是合法的
在C++中,不允许定义多个同名的全局变量
C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上
int g_var;
int g_var = 1;
C++直接拒绝这种二义性的做法。
*/
int g_a = 100;
//int g_a ;
void main()
{
printf(“hello…g_a:%d \n”, g_a);
}
4.5 struct类型加强
#include <iostream>
using namespace std;
//struct 关键字 class关键字 完成的功能是一样的
//区别后面介绍 抛砖
class c1
{
public:
protected:
private:
};
struct Teacher
{
public:
char name[32];
int age;
protected:
int a;
};
void main51()
{
Teacher t1; //
t1.age = 10;
printf(“hello…\n”);
system("pause");
}
4.6c++类型类型检查加强
/*
C++中所有的变量和函数都必须有类型
C语言中的默认类型在C++中是不合法的
函数f的返回值是什么类型,参数又是什么类型?
函数g可以接受多少个参数?//特别多个
*/
/*
//更换成.cpp试试
f(i) //C语言的灰色地带
{
printf(“i = %d\n”, i);
}
g() //C语言的灰色地带
{
return 5;
}
int main(int argc, char *argv[])
{
f(10);
printf(“g() = %d\n”, g(1, 2, 3, 4, 5)); //C语言的灰色地带
getchar();
return 0;
}
*/
//C语言中的这些灰色地带在大项目中容易出错。
4.7新增bool关键字
#include <iostream>
using namespace std;
void main()
{
bool b1 = true; //告诉c++编译器给我分配 1个字节的内存
bool b2, b3, b4, b5;
//
cout<<”sizeof(bool)”<
#include <iostream>
using namespace std;
//在C语言中 表达式的结果 放在什么地方 寄存器
//1
// 在C语言中, 表达式的返回值 是变量的值不能作为左值使用
// 在C++中, 表达式返回的是变量的本身 因此可以出现在程序的任何地方
//2 如何做到的
//让表达式返回一个内存空间 ..内存首地址 指针
//在C语言中 如何 实现 c++的效果
//3 本质
//c++编译器 帮我们程序员完成了 取地址的工作
int main()
{
int a = 10;
int b = 20;
int var = 100;
var = 101;
//回一个最小数 并且给最小数赋值成3
//三目运算符是一个表达式 ,表达式不可能做左值
(a < b ? a : b )= 30;
//int z = (a < b ? a : b );
printf("a = %d, b = %d\n", a, b);
//思考:如何让C中的三目运算法当左值呢?
//(a < b ? &a :& b )
system("pause");
return 0;
}
5 C/C++中的const
1 const基础知识(用法、含义、好处)
初级理解:const是定义常量==》const意味着只读
Const好处
//合理的利用const,
//1指针做函数参数,可以有效的提高代码可读性,减少bug;
//2清楚的分清参数的输入和输出特性
1233
using namespace std;
//0 const的基础知识
struct Teacher
{
char name[64];
int age;
};
//指针所指向的内存空间,不能被修改
int operatorTeacher01(const Teacher *pT)
{
//pT->age = 10;
return 0;
}
//指针变量本身不能被修改
int operatorTeacher02( Teacher * const pT)
{
pT->age = 10;
//pT = NULL; //
return 0;
}
int operatorTeacher03( const Teacher * const pT)
{
//pT->age = 10;
//pT = NULL; //
printf(“age:%d”, pT->age);
return 0;
}
void main81()
{
// const int a;
// int const b; //第一个第二个意思一样 代表一个常整形数
//
// const int *c; //const修饰的是指针所指向的内存空间,不能被修改 但是本身可以修改
// int * const d; // d 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
// const int * const e ;// e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改
cout<<”hello…”<
#define d 20
void main84()
{
//int a = 10;
//int b = 20;
//int array[a+b]; //linux内核里面是成立的;原因 编译linux内核的gcc编译器支持.
//c和c++编译器 不支持这种语法现象
const int c = 10;
//const int d = 20;
int array2[c+d];
system(“pause”);
}
//5 const定义的变量,由编译器处理的,提供类型检查和作用域检查
void fun1()
{
#define a 10
const int b = 20;
//#undef a
//# undef
}
void fun2()
{
printf(“a = %d\n”, a);
printf(“b = %d\n”, b);
}
int main()
{
fun1();
fun2();
return 0;
}
对比加深
C++中的const常量类似于宏定义
const int c = 5; ≈ #define c 5
C++中的const常量与宏定义不同
const常量是由编译器处理的,提供类型检查和作用域检查
宏定义由预处理器处理,单纯的文本替换
6引用专题
1引用(普通引用)
变量名回顾
变量名实质上是一段连续存储空间的别名,是一个标号(门牌号)
程序中通过变量来申请并命名内存空间
通过变量的名字可以使用存储空间
问题1:对一段连续的内存空间只能取一个别名吗? 可以,就是引用
#include <iostream>
using namespace std;
//1 引用的概念
//2 属于C++编译器对C的扩展,不能用c语言的语法去思考它
void main91()
{
int a = 10;
//引用的语法:Type& name = var;
int &b = a;
b = 100; //相当于把a修改成100了.
printf(“b:%d \n”, b);
printf(“a:%d \n”, a);
a = 200;
printf(“b:%d \n”, b);
printf(“a:%d \n”, a);
cout<<"hello..."<<endl;
system("pause");
return ;
}
void main92()
{
int a = 10;
int &b = a;
//int &c ; //03普通引用 必须要初始化
system(“pause”);
}
//基础类型的引用
void myswap(int a, int b)
{
int c = 0;
c = a;
a = b;
b = c;
}
void myswap02(int *a, int *b)
{
int c = 0;
c = *a;
*a = *b;
*b = c;
}
//04 引用作为函数参数声明时不进行初始化
void myswap03(int &a, int &b)
{
int c = 0;
c = a;
a = b;
b = c;
}
void main93()
{
int x, y ;
x = 10;
y = 20;
myswap(x, y);
printf(“x:%d , y:%d \n”, x, y);
myswap02(&x, &y); //引用做参数声明时不进行初始化
printf("x:%d , y:%d \n", x, y);
//a就是x的别名 b就是y的别名
myswap03(x, y);
printf("x:%d , y:%d \n", x, y);
//int &c ; //普通引用 必须要初始化
system("pause");
}
//05复杂数据类型 的引用
struct Teacher
{
char name[64];
int age ;
};
void printfT(Teacher *pT)
{
cout<age<
#include <iostream>
using namespace std;
//1 第一点 单独定义的引用时,必须初始化;说明很像一个常量
void main01()
{
//
const int c1 = 10;
int a = 10;
int &b = a; //b很想一个常量
printf("&a:%d \n", &a);
printf("&b:%d \n", &b); //===> a 和 b就是同一块内存空间的门牌号
cout<<"hello..."<<endl;
system("pause");
return ;
}
//2 普通引用有自己的空间吗? 有
struct Teacher
{
char name[64]; //64
int age; //4
int &a; //4 0 //很像指针 所占的内存空间大小
int &b; //4 0
};
//3 引用的本质
void modifyA(int &a1)
{
a1 = 100;
}
void modifyA2(int * const a1)
{
a1 = 200; //实参的地址 ,去间接的修改实参的值
}
void main1001()
{
int a = 10;
//1
modifyA(a); //指向这个函数调用的时候,我们程序员不需要取a的地址
printf("a:%d \n", a);
//
a = 10;
modifyA2(&a); //如果是指针 需要我们程序员手工的取实参的地址
printf("a:%d \n", a);
printf("sizeof(Teacher):%d \n", sizeof(Teacher));
system("pause");
}
void modifyA3(int *p)
{
*p = 200; //*p 3*p形参去间接修改实参的值
}
//间接赋值
void main()
{
int a = 10;
int *p = NULL; //间接赋值成立的三个条件 1 定义两个变量
p = &a;
*p = 100;
{
*p = 200;
}
modifyA3(&a); //2 建立关联
}
// 123 写在一块
// 12 3
//1 23
结论:
1)引用在实现上,只不过是把:间接赋值成立的三个条件的后两步和二为一
//当实参传给形参引用的时候,只不过是c++编译器帮我们程序员手工取了一个实参地址,传给了形参引用(常量指针)
2)当我们使用引用语法的时,我们不去关心编译器引用是怎么做的
当我们分析奇怪的语法现象的时,我们才去考虑c++编译器是怎么做的
7函数返回值是引用(引用当左值)
#include <iostream>
using namespace std;
int getAA1()
{
int a ;
a = 10;
return a;
}返回a的一个副本 10
//返回a的本身 就是a的地址
int& getAA2() //临时变量,调用后就释放地址
{
int a ; //如果返回栈上的 引用, 有可能会有问题
a = 10;
return a;
}
int* getAA3()
{
int a ;
a = 10;
return &a;
}
void main1101()
{
int a1 = 0;
int a2 = 0;
a1 = getAA1();
a2 = getAA2(); //10
int &a3 = getAA2(); //若返回栈变量 不能成为其它引用的初始值 ,内存空间的值已经释放了,返回可能是乱码
printf("a1:%d \n", a1);
printf("a2:%d \n", a2);
printf("a3:%d \n", a3); // *a3
cout<<"hello..."<<endl;
system("pause");
return ;
}
//变量是static 或者是 全局变量
int j1()
{
static int a = 10;
a ++ ;
return a;
}
int& j2()
{
static int a = 10;
a ++ ;
return a;
}
//若返回静态变量或全局变量
// 可以成为其他引用的初始值
// 即可作为右值使用,也可作为左值使用
void main1112()
{
int a1 = 10;
int a2 = 20;
a1 = j1();
a2 = j2();
int &a3 = j2();
printf("a1:%d \n", a1);
printf("a2:%d \n", a2);
printf("a3:%d \n", a3);
system("pause");
}
//////////////////////////////////////////////////////////////////////////
//— 函数当左值
//返回变量的值
int g1()
{
static int a = 10;
a ++ ;
return a; //
}
//返回变量本身 ,
int& g2()
{
static int a = 10;
a ++ ;
printf(“a:%d \n” , a);
return a;
}
void main()
{
// g1() = 100;
//11 = 100;
g2() = 100; //函数返回值是一个引用,并且当左值
g2();
int c1 = g1(); //函数返回值是一个引用,并且当右值
int c2 = g2(); //函数返回值是一个引用,并且当右值
//a = 100;
system("pause");
}
上一篇: python学习笔记八(模块)