广州最好的商城网站制作,三合一网站什么意思,贵州小城镇建设网站,创意网站建设设计如果你也是从C语言一路过来的#xff0c;那么请一起看下去吧#xff01; 文章目录 面型对象程序设计C基础C和C一些语法区别C在非对象方面对C语言的扩充C的一些标准#xff08;兼容旧标准#xff09; 首先#xff0c;在C的学习中#xff0c;我们要时刻清醒一点#xff1…如果你也是从C语言一路过来的那么请一起看下去吧 文章目录 面型对象程序设计C基础C和C一些语法区别C在非对象方面对C语言的扩充C的一些标准兼容旧标准 首先在C的学习中我们要时刻清醒一点虽然C与C语言有很大区别但C是C语言的扩充
说到C和C语言的区别那也是面向对象和面向过程的区别这时你的老师可能会这么给你讲 可是学了C语言没学过C的人发问了我们在学面向过程设计的时候说“数据和操作往往都是分离的”数据是米饭操作是米饭上盖的菜既然如此面向过程那不应该是盖饭吗而面向对象具有封装的特点更是炒饭呀老师气的脸都绿了
只有当你亲口尝了这两种饭菜你才会知道盖饭中的菜是什么米是什么炒饭中的菜是什么米是什么以及他们的口味。所以当你正确的理解了这个比喻你便能真正认识C语言与C面向过程和面向对象那么请跟随我一起去寻找我们的答案吧~
面型对象程序设计
面向过程是这样的 一个程序是一道菜面向过程这道菜的特点是先从整体角度全面看待问题然后列出解决问题需要的步骤再逐步去完善。
面向对象是这样的 面向对象这道菜有两个主要的结构特点①程序一般由类的定义属性和类的使用行为两部分组成②程序中的一切都是通过向对象发送消息来实现的对象接收到消息后启动有关方法完成相应的操作。 对象描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体。对象可认为是数据操作。类类是具有相同的数据和相同的操作的一组对象的集合。消息传递对象之间的交互。**方法**对象实现的行为称为方法 面向对象程序设计的基本特征抽象、封装、继承、多态。 理清了面向对象和面向过程之间的区别后然我们来了解一下——从C语言到C~
C基础 C的产生和特点 C是美国贝尔实验室的Bjarne Stroustrup博士在C语言的基础上弥补了C语言存在的一些缺陷增加了面向对象的特征于1980年开发出来的一种面向过程性与面向对象性相结合的程序设计语言。最初他把这种新的语言称为“含类的C”到1983年才取名为C。
相比C语言C的主要特点就是增加了面向对象机制 一个简单的C示例程序 #includeiostream //编译预处理命令
using namespace std; //使用命名空间void Log(const char* message) { //函数定义cout message endl;
}int main() {Log(Hello World!);cin.get();
}C和C一些语法区别
1.三目运算符在C语言中返回的是一个常量是不能被赋值的而C中返回的是变量可以被赋值
2.C中的函数必须要写返回值类型
3.在全局下C不允许int a;和int a10;等这种重定义二义性操作
4.在C中不要返回局部变量或临时变量的地址虽然C能够运行变量出作用域之后再使用一次即C允许在代码块中的任何地方声明局部变量。
5.C语言中const修饰的变量不能定义数组大小而C中可以
const int a10;
float arr[a];
126.C中定义结构体类型变量可以不用写结构体类型名
7.关于C语言有没有bool类型C语言的布尔类型bool
C在非对象方面对C语言的扩充
1输入和输出
int i;
float f;
cin i;
cout f;
------------
scanf(%d, i);
printf(%f, f);
----------------
连续读入
cin a b c;【cin】
在默认情况下运算符“”将跳过空白符然后读入后面与变量类型相对应的值。因此给一组变量输入值时可用空格符、回车符、制表符将输入的数据间隔开。当输入字符串即类型为string的变量时提取运算符“”的作用是跳过空白字符读入后面的非空白字符直到遇到另一个空白字符为止并在串尾放一个字符串结束标志‘\0’。
2const修饰符
在C语言中习惯使用#define来定义常量例如#define PI 3.14C提供了一种更灵活、更安全的方式来定义常量即使用const修饰符来定义常量。例如const float PI 3.14
const可以与指针一起使用它们的组合情况复杂可归纳为3种指向常量的指针、常指针和指向常量的常指针。 指向常量的指针一个指向常量的指针变量。 const char* pc abcd;
该方法不允许改变指针所指的变量即pc[3] ‘x; 是错误的
但是由于pc是一个指向常量的普通指针变量不是常指针因此可以改变pc所指的地址例如pc ervfs;
该语句付给了指针另一个字符串的地址改变了pc的值。
123456常指针将指针变量所指的地址声明为常量 char* const pc abcd;
创建一个常指针一个不能移动的固定指针可更改内容如pc[3] x;
但不能改变地址如pc dsff; 不合法
12345指向常量的常指针这个指针所指的地址不能改变它所指向的地址中的内容也不能改变。 const char* const pc abcd;
内容和地址均不能改变
12说明 如果用const定义整型常量关键字可以省略。即 const in bufsize 100 与 const bufsize 100等价常量一旦被建立在程序的任何地方都不能再更改。与#define不同const定义的常量可以有自己的数据类型。函数参数也可以用const说明用于保证实参在该函数内不被改动。 3void型指针
void通常表示无值但将void作为指针的类型时它却表示不确定的类型。这种void型指针是一种通用型指针也就是说任何类型的指针值都可以赋给void类型的指针变量。
需要指出的是这里说void型指针是通用指针是指它可以接受任何类型的指针的赋值但对已获值的void型指针对它进行再处理如输出或者传递指针值时则必须再进行显式类型转换否则会出错。 void* pc;int i 123;char c a;pc i;cout pc endl; //输出指针地址006FF730cout *(int*)pc endl; //输出值123pc c;cout *(char*)pc endl; //输出值a4内联函数
在函数名前冠以关键字inline该函数就被声明为内联函数。每当程序中出现对该函数的调用时C编译器使用函数体中的代码插入到调用该函数的语句之处同时使用实参代替形参以便在程序运行时不再进行函数调用。引入内联函数主要是为了消除调用函数时的系统开销以提高运行速度。
说明
内联函数在第一次被调用之前必须进行完整的定义否则编译器将无法知道应该插入什么代码在内联函数体内一般不能含有复杂的控制语句如for语句和switch语句等使用内联函数是一种空间换时间的措施若内联函数较长较复杂且调用较为频繁时不建议使用
#include iostream
using namespace std;inline double circle(double r) //内联函数
{double PI 3.14;return PI * r * r;
}int main()
{for (int i 1; i 3; i)cout r i area circle(i) endl;return 0;
}使用内联函数替代宏定义能消除宏定义的不安全性
5带有默认参数值的函数
当进行函数调用时编译器按从左到右的顺序将实参与形参结合若未指定足够的实参则编译器按顺序用函数原型中的默认值来补足所缺少的实参。
void init(int x 5, int y 10);
init (100, 19); // 100 19
init(25); // 25, 10
init(); // 5 10
1234在函数原型中所有取默认值的参数都必须出现在不取默认值的参数的右边。 如 int fun(int a, int b, int c 111);
1在函数调用时若某个参数省略则其后的参数皆应省略而采取默认值。不允许某个参数省略后再给其后的参数指定参数值。
6函数重载
在C中用户可以重载函数。这意味着在同一作用域内只要函数参数的类型不同或者参数的个数不同或者二者兼而有之两个或者两个以上的函数可以使用相同的函数名。
#includeiostream
//以下函数均构成重载
int plus(int a, int b) {return a b;
}
int plus(int a, int b, int c) {return a b c;
}
double plus(double a,double b) {return a b;
}
double plus(int a, double b) {return a b;
}
double plus(double a, int b) {return a b;
}
int main() {std::cout plus(2, 3) std::endl;std::cout plus(1,2,3) std::endl;std::cout plus(2.5, 5.3) std::endl;std::cout plus(3,4.5) std::endl;std::cout plus(3.3,6) std::endl;
}说明 调用重载函数时函数返回值类型不在参数匹配检查之列。因此若两个函数的参数个数和类型都相同而只有返回值类型不同则不允许重载。 int mul(int x, int y);
double mul(int x, int y);
12函数的重载与带默认值的函数一起使用时有可能引起二义性。 int fun(int a){};
int fun(float a){};从函数重载的重载条件来看构成重载编译不会有问题但在调用时如果调用方式如fun(2.3);
由于在C/C中的浮点型常量默认是double类型而double类型既可以给int型变量赋值又可以给float型变量赋值
赋值兼容(隐式类型转换)所导致的函数重载二义性问题 →解决方法 int fun(double a){}加入新的重载函数使得类型有确定的调用方式不存在赋值兼容
fun((int)2.3);明确函数调用时的参数类型可以使用强制类型转换
7作用域标识符::
通常情况下如果有两个同名变量一个是全局的另一个是局部的那么局部变量在其作用域内具有较高的优先权它将屏蔽全局变量。
如果希望在局部变量的作用域内使用同名的全局变量可以在该变量前加上“::”此时::value代表全局变量value“::”称为作用域标识符。
#include iostream
using namespace std;int value; //定义全局变量valueint main()
{int value; //定义局部变量valuevalue 100;::value 1000;cout local value : value endl;cout global value : ::value endl;return 0;
}8强制类型转换
可用强制类型转换将不同类型的数据进行转换。例如要把一个整型数int转换为双精度型数double可使用如下的格式
int i 10;
double x (double)i;
或
int i 10;
double x double(i);
12345以上两种方法C都能接受建议使用后一种方法。
9new和delete运算符
程序运行时计算机的内存被分为4个区程序代码区、全局数据区、堆和栈。其中堆可由用户分配和释放。C语言中使用函数malloc()和free()来进行动态内存管理。C则提供了运算符new和delete来做同样的工作而且后者比前者性能更优越使用更灵活方便。
指针变量名 new 类型int *p;p new int;
delete 指针变量名delete p;
12345下面对new和delete的使用再做一下几点说明 用运算符new分配的空间使用结束后应该用也只能用delete显式地释放否则这部分空间将不能回收而变成死空间。 在使用运算符new动态分配内存时如果没有足够的内存满足分配要求new将返回空指针NULL。 使用运算符new可以为数组动态分配内存空间这时需要在类型后面加上数组大小。 指针变量名 new 类型名[下标表达式];
int *p new int[10];
12释放动态分配的数组存储区时可使用delete运算符。 delete []指针变量名;
delete p;
12new 可在为简单变量分配空间的同时进行初始化 指针变量名 new 类型名(初值);
int *p;
p new int(99);
···
delete p;10引用
引用reference是C对C的一个重要扩充。变量的引用就是变量的别名因此引用又称别名。
真实的数据类型 引用名 已定义的变量名引用与其所代表的变量共享同一内存单元系统并不为引用另外分配存储空间。实际上编译系统使引用和其代表的变量具有相同的地址。 引用并不是一种独立的数据类型它必须与某一种类型的变量相联系。在声明引用时必须立即对它进行初始化不能声明完成后再赋值。 为引用提供的初始值可以是一个变量或者另一个引用。 引用的类型必须和其所对应的变量的类型相同 对引用的操作和对引用对应的变量的操作是完全等价的 不允许建立void类型的引用 不能建立引用的数组 可以用const对引用加以限定不允许改变该引用的值但是它不阻止引用所代表的变量的值。
#includeiostream
using namespace std;
int main() {int a 8;int ref_a a;ref_a;cout a endl;//9
}
//上面代码输出a和ref_a的值相同地址也相同。引用就是指针的语法糖syntax sugar 我们为什么要使用引用呢我们干嘛要起个别名而不直接用真名呢 假设我们想通过调用一个函数来实现一个整型变量的自增有下面3种传递方式 值传递形参的改变无法改变实参的值
void fun(int x) {x;
}
int main() {int a 8;fun(a);cout a endl;//8
}地址传递形参的改变可以改变实参的值
void fun(int* x) {(*x);//不加括号就会先自增再解引用
}
int main() {int a 8;fun(a);cout a endl;//9
}引用传递形参的改变可以改变实参的值
void fun(int x) {x;
}
int main() {int a 8;fun(a);cout a endl;//9
}是不是比使用指针更简洁些呢
那么可不可以给引用取别名呢答案是可以的
int a 8;
int a1 a;
int a2 a1;//给引用取别名(引用的嵌套)
int a3 a;//同一个对象或变量可以取多个别名引用和指针的区别 指针是另一个变量而引用是自己本身指针会占用额外存储空间但引用不会占用额外存储空间也就是说别名和真名是同一个东西共享同一块内存。指针可以不用初始化赋值但是引用必须初始化赋值指针可以有多级指针但是引用没有多级引用指针可以改变指向但是引用不能改变其所指代的变量或对象指针是间接访问引用是直接访问
另外可以将引用的地址赋值给一个指针此时指针指向的是原来的变量。
引用作为函数参数、使用引用返回函数值
#include iostream
using namespace std;void swap(int a, int b)
{int t a;a b;b t;
}int a[] {1, 3, 5, 7, 9};int index(int i)
{return a[i];
}int main()
{int a 5, b 10;//交换数字a和bswap(a, b);cout a a b b endl;cout index(2) endl; //等价于输出元素a[2]的值index(2) 100; //等价于将a[2]的值赋为100;cout index(2) endl;return 0;
}关于指针的更多内容【C语言】指针
C的一些标准兼容旧标准
1.以初始化列表的方式赋值
int c{2};
int d{(int)3.3};
int arr1[6]{1,2,3};2.空指针
int *pNULL;//旧标准
int *p1nullptr;//新标准3.自动类型
auto x10.6;//根据初始化赋值的类型决定变量的类型4.decltype的使用可以理解为 复制类型
int n123;
decltype(n) m100;//定义一个和变量n一样类型的变量m
decltype((n)) kn;//给变量n取一个别名k类似于引用 int kn;
1235.给数据类型取别名
typedef int HP;//旧
using MP int;//新
typedef void(*pFun)();//旧
using PFun void(*)();//新
typedef char str[10];//旧
using Str char[10];//新
1234566.新的for循环语法规则
#includeiostream
int main() {int arr2[10] { 1,2,3,4,5,6,7,8,9,0 };for (int i 0; i 10; i) {std::cout arr2[i] \t;}std::coutstd::endl;//新for (auto i : arr2) {std::cout i \t;}
}这个方法只能用来遍历数组或者容器i所代表的是里面存储的数据元素。指针不能这样遍历。 好啦下面我们就进入C的系统学习吧笔者会陆续更新哦
三大特点
①封装——类和对象
②继承与派生
③多态性与虚函数
运算符重载
函数模版与类模版
C的输入和输出
异常处理和命名空间
STL标准模板库