1.c+±>c plus plus
#include<iostream>//输入输出流
using namespace stu;
命名空间
namespace Type
{
typedef int INT;
typedef char CHAR;
};
using namespace Type;//可以访问namespace Type内所有成员
using Type::INT;//仅访问namespace Type内INT
输入输出
cout<<a<<endl;//输出
cin>>a;//输入
2.函数的区别
<1>函数参数默认值:
(1)必须从右向左依次赋值,不可以跳过;在同一作用域下,默认值只能赋值一次
(2)通过生成入栈指令传入,编译期确定默认值
(3)默认值的作用域只在当前文件
<2>函数重载
(1)c语言中函数编译生成的函数符号依赖函数名;c++中函数编译生成的函数符号依赖函数名+参数列表
(2)函数名相同,参数列表不同
<3>内联函数【在函数调用的地方,将函数按照逻辑展开】
有类型安全校验,可以调试
在debug版本,内联函数和静态函数表现一致 ;在release版本和宏函数表现基本一致
在debug版本会生成符号,release不生成符号
inline函数【作用域只在本文件】
inilne int fun(int a,int b)
{
int c=a+b;
return c;
}
递归函数不可以被处理成内联函数,原因是递归终结条件是因为某一个变量,内联函数按逻辑展开时(即编译时期),按逻辑无法确定合适终止递归。
inline函数仅在本文件定义,原因为按照逻辑展开,即在编译时期进行处理。
①local符号
inline函数和static函数都是local符号,即本地符号,仅在本文件有效
②global符号
<4>宏函数
没有类型安全校验,不能调试,不生成符号
#define Fun(a,b) a+b*a;
int main()
{
int a = 10;
int b = 20;
int c = 30;
//#define FUN(a,b)a+b*a
int d = FUN(FUN(3,4),2);
//int d = 3 + 4 * 3 + 2 * 3 + 4 * 3;
cout << d << endl;
return 0;
}
<5>静态函数
有类型安全校验,可以调试,会生成local符号
<6>普通函数
有类型安全校验,可以调试,会生成global符号
3.c语言和c++链接
extern【c++调用c语言】
extern "c"//c++中使用,编译下列函数名按照c语言模式编译
{
void fun_c(int a,int b);
}
void fun_c(int a,int b);//c++中编译:fun_c_int_int
//c中编译:fun_c
【c语言调用c++】
加一个中介,即新建立一个.cpp文件
int fun_cpp(int a,int b);
extern "c"//c++中使用,编译下列函数名按照c语言模式编译
{
int fun_cpp_tmp(int a,int b)
{
return func_cpp(a,b);
}
}
4.指针、地址、数组名、函数名区别
指针:指针是变量,且有类型,可以存放地址
地址:地址是常量
数组名:数组名就是一个地址
函数名:函数名是一个地址
【访问变量,就会有一次解引用的过程】
//int arr[]={1,2,3,4,5,6,7,8,9,10};
extern int *arr;
int main()
{
cout<<arr<<endl;//1 arr本质是常量,在 extern int *arr; 中我们将其看成一个变量,也就是相当与对arr进行解引用,输出为1
//cout<<arr[0]<<endl;//对常量1解引用,程序崩溃
//cout<<*arr<<endl;//对常量1解引用,程序崩溃
return 0;
}
5.申请空间
c语言中:malloc 和free
一维数组申请:
int main()
{
int *ip=(int*)malloc(sizeof(int)*50);
free(ip);
ip=NULL;
return 0;
}
二维数组申请
int main()
{
int **ip=(int**)malloc(sizeof(int)*5);
for(int i=0;i<5;i++)
{
ip[i]=(int*)malloc(sizeof(int)*10);
}
for(int i=0;i<5;i++)
{
free(ip[i]);
}
free(ip);
ip=NULL;
return 0;
}
c++中:new和delete
int main()
{
int *q=new int();//默认值为0
delete q;
int *iq=new int[10];//申请一个数组
delete[]iq;
int **ip=new int*[5];//申请一个二维数组
for(int i=0;i<5;i++)
{
ip[i]=new int[10];
}
for(int i=0;i<5;i++)
{
delete[]ip[i];
}
delete[]ip;
}
6.const与常量
C语言
int main()
{
const int a=10;//const仅限制a不能作为左值
int *p=&a;
*p=999;
printf("a=%d *p=%d\n");//a=999 *p=999//代码层修改
return 0;
}
c++
int main()
{
const int a=10;//const修饰的值为常量
int *p=(int*)&a;
*p=20;
cout<<"a="<<a<<endl;//10//编译期就已经将a替换为10
cout<<"*p="<<*p<<endl;//20
int c=10
const int a1=c;//const修饰的值为常量
int *p2=(int*)&a1;
*p2=20;
cout<<"a1="<<a1<<endl;//20
cout<<"*p2="<<*p2<<endl;//20
const int d;//如果不初始化,后期无法复制
return 0;
}
常量会在编译期把使用到该常量的地方,替换为该常量的值。
如果使用变量初始化常量,常量会退化为常变量。
const修饰的值必须初始化
7.const与一级指针
int main()
{
int c=10;
int *p=&c;
const int *p1=&c;
int const* p2=&c;
int *const p3=&c;
int *q=&c;
const int *q1=&c;
int const* q2=&c;
int *const q3=&c;
}
ok: p=q; p=q3; p1=q; p1=q1; p1=q2; p1=q3; p2=q; p2=q1; p2=q2; p2=q3;
error:p=q1; p=q2; p3=q; p3=q1; p3=q2; p3=q3;
注意const修饰的内容
8.&引用
int main()
{
int a=10;
int &b=a;//b是a的别名 就像是人有姓名也有外号
int a1=10;
int &b1=a1;
int *p=&a;
int c;
c=a;
c=b;// *ptr
c=*p;
return 0;
}
引用的底层就是指针【从汇编角度,引用的代码与指针的代码相似】
所有使用该引用的地方,在编译期会自动替换为底层指针的解引用,所有必须进行初始化,且后期无法改变引用的目标
int main()
{
const int c=10;
//int& f=c;
const int& f=c;//常引用
//不能引用常量,但是可以用const对引用进行修饰,再进行引用
const int& b=10;//给10一个临时量,为了引用临时量,可以加const进行引用
return 0;
}
临时量:临时量都具有常属性;生命周期仅在当前指令;如果被引用,生命周期随引用一起
void Swap1(int* p,int* q)
{
int tmp=*p;
*p=*q;
*q=tmp;
}
void Swap2(int& ip,int& iq)
{
int tmp=ip;
ip=iq;
iq=tmp;
}
引用与函数
int fun(int& a,int& b)
{
int c=a+b;
return 10;
}
int main()
{
//int &w=fun(10,20);
const int &w=fun(10,20);
return 0;
}