const链接方式
在C语言中const默认是外部链接
//test.c
const int a = 10; //C语言中const默认是外部链接
//a.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
extern const int a; //告诉编译器a在外部
printf("a = %d \n",a);
return 0;
}
在C++语言中const默认是部内部链接
//test.cpp
extern const int a = 10; //C++中的const默认内部链接 extern 提高作用域
//a.cpp
#include <iostream>
using namespace std;
int main()
{
extern const int a;
cout<<"a = "<<a<<endl;
return 0;
}
const内存分配情况
1.取地址会临时分配内存
2.加extern 编译器也会给const变量分配内存
3.用变量初始化 const变量
4.自定义分配类型 加const也会分配内存
#include <iostream>
#include <string>
using namespace std;
//const分配内存
//1.取地址会临时分配内存
void test01()
{
const int m_A = 10;
int *p = (int *)&m_A; //会分配临时内存
}
//2.extern 编译器也会给const变量分配内存
//3.用变量初始化 const变量
void test02()
{
int a = 10;
const int b = a; //会分配内存
int *p = (int *)&b;
*p = 20; //如果分配内存可以通过指针改变数值
cout<<"b = "<<b<<endl;
}
//4.自定义分配类型 加const也会分配内存
struct Person
{
string m_Name; //姓名
int m_Age;
};
void test03()
{
const Person p1 = {"li",22};
Person *p = (Person *)&p1;
p->m_Name = "wang";
(*p).m_Age = 18;
cout<<"name = "<<p1.m_Name<<endl;
cout<<"age = "<<p1.m_Age<<endl;
}
int main()
{
//test02();
//test03();
return 0;
}
引用的基本语法
1.引用必须初始化
2.一旦初始化后不可以修改
3.对数组建立引用
#include <iostream>
#include <string>
using namespace std;
//1.引用的基本语法 Type &别名 = 原名
int test01()
{
int a = 10;
int &b = a;
b = 20;
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
}
//2.引用必须q初始化
int test02()
{
//int &a; 必须初始化
int a = 10;
int &b = a; //引用初始化后不可以修改
int c = 20;
b =c; //赋值!
}
//3.对数建立引用
int test03()
{
int array[10];
for(int i = 0; i < 10; i++)
{
array[i] = i;
}
//给数组起别名
int (&pArray)[10] = array;
for(int i = 0; i < 10; i++)
{
cout << pArray[i] <<" ";
}
cout << endl;
//第二种方式取别名
typedef int(ARRAY)[10]; //一个具有10个元素的int类型的数组
ARRAY &pArray2 = array;
for(int i = 0; i < 10; i++)
{
cout << pArray2[i] <<" ";
}
cout << endl;
}
int main()
{
//test01();
test03();
return 0;
}
参数的传递方式
1.值传递
2.地址传递
3.引用传递
#include <iostream>
#include <string>
using namespace std;
void mySwap(int a,int b)
{
int temp = a;
a = b;
b = temp;
cout << "mySwap::a= " << a << endl;
cout << "mySwap::b= " << b << endl;
}
void test01()
{
int a = 10;
int b = 20;
mySwap(a,b); //值传递
cout << "a= " << a << endl;
cout << "b= " << b << endl;
}
//地址转递
void mySwap2(int * a,int * b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void test02()
{
int a = 10;
int b = 20;
mySwap2(&a,&b); //址传递
cout << "a= " << a << endl;
cout << "b= " << b << endl;
}
//引用传递 类似地址传递
void mySwap3(int &a,int &b) //&a = a &b = b
{
int temp = a;
a = b;
b = temp;
}
void test03()
{
int a = 10;
int b = 20;
mySwap3(a,b);
cout << "a= " << a << endl;
cout << "b= " << b << endl;
}
int main()
{
//test01();
//test02();
//test03();
return 0;
}
引用的注意事项
1.不要返回局部变量的引用
2.如果函数的返回值是引用,那么函数的引用可以作为左值
#include <iostream>
#include <string>
using namespace std;
//引用的注意事项
//引用必须引用一块合法的内存空间
//1.不要返回局部变量的引用
int& doWork()
{
int a = 10;
return a;
}
void test01()
{
//int &a = 10; //引用必须引用一块合法的内存空间
int &ret = doWork(); //不要返回局部变量的引用
cout<<"ret = " <<ret<<endl;
cout<<"ret = " <<ret<<endl;
}
int& doWork2()
{
static int a = 10;
return a;
}
//2.如果函数的返回值是引用,那么函数的引用可以作为左值
void test02()
{
int &ret = doWork2();
cout<<"ret = " <<ret<<endl;
cout<<"ret = " <<ret<<endl;
//如果函数的返回值是引用,那么这个函数的x调用可以作为左值
doWork2() = 100; //相当于 a = 100;
}
int main()
{
//test01();
//test02();
return 0;
}
引用的本质
引用的本质在C++内部实现是一个常量指针
#include <iostream>
#include <string>
using namespace std;
//引用的本质:在C++内部实现是一个常量指针
//发现是引用,转换为 int *const temp = &b
void testfunc(int& temp)
{
temp = 100; //temp是引用,转换为 *temp = 100;
}
void test01()
{
int a = 10;
int &b = a; //自动转换为 int* const b = &a; (指针常量必须初始化)
//这也能说明引用为什么必须初始化
b = 20; //内部发现b是引用,自动转换为 *b = 20;
cout << "a = "<<a<<endl;
cout << "b = "<<b<<endl;
testfunc(a);
cout << "change a = "<<a<<endl;
cout << "change b = "<<b<<endl;
}
int main()
{
test01();
return 0;
}
指针的引用
1.用一级指针代替二级指针
#include <iostream>
#include <string>
using namespace std;
//指针的引用
struct Person
{
int m_Age;
};
void allocatMemory(Person **p) //**p:具体的Person对象 *p:对象的指针 p:指针的指针
{
*p = (Person *)malloc(sizeof(Person));
(*p)->m_Age = 15;
}
void test01()
{
Person *p = NULL;
allocatMemory(&p);
cout<<"age="<<p->m_Age<<endl;
}
//利用指针引用来开辟空间
void allocatMemorybyRef(Person* &p) //指针的引用
{
p = (Person *)malloc(sizeof(Person));
p->m_Age = 20;
}
void test02()
{
Person *p = NULL;
allocatMemorybyRef(p);
cout<<"age="<<p->m_Age<<endl;
}
int main()
{
//test01();
//test02();
return 0;
}
常量的引用
1.使用场景,修饰形参为只读(可以通过指针进行修改)
2.用const修饰,会分配空间
#include <iostream>
#include <string>
using namespace std;
//常量的引用
void test01()
{
//int &ref = 10; //引用了不合法的内存
const int &ref = 10; //加入const后,编译器处理方式: int temp = 10; const int &ref = temp;会分配内存
//ref = 20;
int *p = (int *)&ref;
*p = 30;
cout<<"ref = "<<ref<<endl;
}
//常量引用的使用场景 用来修饰形参
void showValue(const int &val)
{
//val += 10; //如果只是想显示而不修改内容,就需要const修饰形参
cout<<"val = "<<val<<endl;
}
void test02()
{
int a = 10;
showValue(a);
cout<<"a = "<<a<<endl;
}
int main()
{
//test01();
//test02();
return 0;
}