怎么做网站下载链接,手机微信网站建设,用r语言 做网站点击热力图,公司网站维护教程变量名实质上是一段连续存储空间的别名#xff0c;是一个标号(门牌号)
通过变量来申请并命名内存空间.
通过变量的名字可以使用存储空间.
变量名#xff0c;本身是一段内存的引用#xff0c;即别名(alias). 引用可以看作一个已定义变量的别名。
引用的语法#xff…变量名实质上是一段连续存储空间的别名是一个标号(门牌号)
通过变量来申请并命名内存空间.
通过变量的名字可以使用存储空间.
变量名本身是一段内存的引用即别名(alias). 引用可以看作一个已定义变量的别名。
引用的语法Type name var; int a10; //c编译器分配4个字节内存, a内存空间的别名 int ba; //b就是a的引用 3.1.3 规则
1 引用没有定义,是一种关系型声明。声明它和原有某一变量(实体)的关系。故而类型与原类型保持一致,且不分配内存。与被引用的变量有相同的地址。
2 声明的时候必须初始化,一经声明,不可变更。
3 可对引用,再次引用。多次引用的结果,是某一变量具有多个别名。
4 符号前有数据类型时,是引用。其它皆为取地址。 const int a; int const b; //第⼀个第⼆个意思⼀样 代表⼀个常整形数 const int *c; //第三个 c是⼀个指向常整形数的指针(所指向的内存数据不能被修改但是本⾝可以修改) int * const d; //第四个 d 常指针指针变量不能被修改但是它所指向内存空间可以被修改 const int * const e ; //第五个 e⼀个指向常整形的常指针指针和它所指向的内存空间均不能被修改 const 常量是由编译器处理的提供类型检查和作用域检查 #define 宏定义由预处理器处理单纯的文本替换
引用作为函数参数 普通引用在声明时必须用其它的变量进行初始化引用作为函数参数声 明时不进行初始化
引用作为函数的返回值引用当左值
I. 当函数返回值为引用时, 若返回栈变量: 不能成为其它引用的初始值不能作为左值使用 若返回静态变量或全局变量 可以成为其他引用的初始值可作为右值使用也可作为左值使用 如果返回值为引用可以当左值 如果返回值为普通变量不可以当左值。
普通引用有自己的存储空间吗 1引用在C中的内部实现是一个常指针 Type name Type* const name 2C编译器在编译过程中使用常指针作为引用的内部实现因此引用所占 用的空间大小与指针相同。 3从使用的角度引用会让人误会其只是一个别名没有自己的存储空间。
这是C为了实用性而做出的细节隐藏。
从右向左看或*哪个离变量近 哪个便起主要作用。int*ap_a; 把int*看成类型
int b12;
int ab;
int* p_ab;
int* ap_a;
const引用
const 引用有较多使用。它可以防止对象的值被随意修改。因而具有一 些特性。
(1)const 对象的引用必须是 const 的,将普通引用绑定到 const 对象是不 合法的。这个原因比较简单。既然对象是 const 的,表示不能被修改,引用当然 也不 能修改,必须使用 const 引用。实际上, const int a1; int ba;
这种写法是不合法 的,编译不过。
(2)const 引用可使用相关类型的对象(常量,非同类型的变量或表达式)初 始化。这个是 const 引用与普通引用最大的区别。 const int a2; 是合法的。 double x3.14; const int ba;
也是合法的。
//int m 41; //error , 普通引⽤ 引⽤⼀个字⾯量 请问字⾯量有没有内存地址
const int m 43; //c编译器 会 分配内存空间
// int temp 43
// const int m temp;
#include iostream
using namespace std;
int main(void)
{
//1 ⽤变量 初始化 常引⽤
int x1 30;
const int y1x1; //⽤x1变量去初始化 常引⽤
//2⽤字⾯量 初始化 常量引⽤
const int a 40; //c编译器把a放在符号表中
//int m 41; //error , 普通引⽤ 引⽤⼀个字⾯量 请问字⾯量有没有内存地址
26
const int m 43; //c编译器 会 分配内存空间
// int temp 43
// const int m temp;
return 0;
} const引用的原理
const 引用的目的是,禁止通过修改引用值来改变被引用的对象。
结论
1const int e 相当于 const int * const e
2普通引用 相当于 int *const e
3当使用常量字面量对const引用进行初始化时C编译器会为常量值
分配空间并将引用名作为这段空间的别名
4使用字面量对const引用初始化后将生成一个只读变量 内存四区 1引用的基本语法
#if 1
#includeiostream
using namespace std;
//1 引用没有定义, 是一种关系型声明。声明它和原有某一变量(实体)的关
//系。故 而类型与原类型保持一致, 且不分配内存。与被引用的变量有相同的地
//址。
//2 声明的时候必须初始化, 一经声明, 不可变更。
//3 可对引用, 再次引用。多次引用的结果, 是某一变量具有多个别名。
//4 符号前有数据类型时, 是引用。其它皆为取地址。
void test01() {int a 10;int b a;cout a endl; //10b 20;cout a endl; //20cout b endl; //20a 30;{int *p a; *p 12;cout *p endl; //12cout a endl; //12}cout a endl; //12cout b endl; //12}
void test02() {int a 10;int *p a;*p 12;cout *p endl; //12cout a endl; //12
}void test03() {const int a 10;int *p (int *)a;*p 12;cout *p endl; //12cout a endl; //10
}void test04() {int a 10;int b a;int *p a;*p 30;p b;*p 20;int re a;re 50;cout a endl; //50cout b endl; //50cout re endl; //50int ff 10;re ff;cout a endl; //10cout b endl; //10cout re endl; //10}void test05() {int a1, b0;int r a;r b; //错误,不可更改原有的引⽤关系//float rr b; //错误,引⽤类型不匹配 coutarendl; //变量与引⽤具有相同的地址。int ra r; //可对引⽤更次引⽤,表⽰ a 变量有两个别名,分别是 r 和 ra
}
void test06() {int a 10;int b a;int c 20;b c;b 50;cout a endl; //50cout b endl; //50cout c endl; //20 b并不是c的引用}void test07() {int a 10;int b a;b 100;cout a endl; //100cout b endl; //100int c 20;b c;b 200;cout a endl; //200cout b endl; //200cout c endl; //20 c的值未更改 b并不是c的别名
}
int test08() {int a;return a; //返回的是a的别名函数调用完释放a那么a的引用将不知道指向何处所以test08()值会乱码
}
int test09() {int a0;return a; //返回的是a的别名函数调用完释放a那么a的引用将不知道指向何处所以test08()值会乱码const int a1 100;
}
int main() {//test01();//test02();//test03();//test04();//test05();//test06();//test07();int a 100;test08() a;//test08() a //修改局部变量的值 错误cout test08() endl; //-858993460cout test09() endl; //0 //不懂int a1 100;test09() a1;cout test09() endl; //0cout a1 endl; //100return 0;
}
#endif 2引用当函数参数
#if 1
#includeiostream
using namespace std;
void change_value1(int c) { //int ca; c是局部变量需要复制 重新开辟栈空间c 100;
}
void change_value2(int *c) {//int *ca; 指针c存放a的地址。改变*c就是改变a的值//不需要额外复制*c 200;
}
void change_value3(int c) { //int ca; 形参c是实参a的引用不需要额外复制c 300;
}void test01() {int a 0;change_value1(a);cout change_value1: a endl; //0a 0;change_value2(a);cout change_value2: a endl; //200a 0;change_value3(a);cout change_value3: a endl; //300
}struct student {int id;char name[64];
};
void PrintStudent1(student s) { //不建议使用 值拷贝cout s.id s.name endl;
}
void PrintStudent2(student *s) {cout s-id s-name endl;
}
void PrintStudent3(student s) {cout s.id s.name endl;
}
void test02() {student s1 { 10,sdsd };PrintStudent1(s1); //不建议使用PrintStudent2(s1);PrintStudent3(s1);
}
int main() {//test01();test02();return 0;
}
#endif
3引用的本质
#if 1
#includeiostream
using namespace std;//当研究引用时可以将引用当做一个常指针研究
//当使用引用编程时就把引用理解为变量的别名就OK了
struct typeA {int a;
};
struct typeB {int *a;
};
//引用的所占用的大小 跟指针相等
void test01() {cout sizeof(struct typeA): sizeof(typeA) endl; //4 32位系统cout sizeof(struct typeB): sizeof(typeB) endl; //4 32位系统
}
struct student {int id;char name[64];
};
//引用声明时必须初始化 常量声明时也必须初始化 引用可能是常量
//引用可能是常指针 int * const p;
void modify1(int *const a) { //int *const amain::a; 可以改变a的值但不能改变a指向*a 300;//a; 错误
}
void modify2(int a) { //int amain::a; //当我们将引用作为函数参数传递的时候编译器会替我们将实参取地址给引用a 200; //对一个引用操作 赋值时编译器替我们隐藏*操作
}
void modifyStudent(int *const a) { //int *const a 可以改变a的值但不能改变a指向*a 300;//a; 错误
}void test02() {int a 10;int re a;int *const p a;
}
int main(){test01();return 0;
}
#endif
4常量指针
#if 1
#includeiostream
using namespace std;
int main() {int const a 0; //在常量区int *const p1 NULL; //在常量区//p1; ERROR*p1 30;int const *p2 NULL; //在常量区p2;//*p2 40; ERRORreturn 0;
}
#endif
5引用作为函数返回值
#if 1
#includeiostream
using namespace std;int getA1() {int tempValue 10;return tempValue;
}
void getA2(int *a) {*a 20;
}int getA3() {int a 10;return a; //int tempa;将temp传到外部 返回的是别名
}
int getA4() {static int a 10;return a;
}
char *getmen(int num) {char *p NULL;p (char *)malloc(num);return p; //值拷贝
}int getmen2(char **pp, int num) {char *p NULL;p (char *)malloc(num);*pp p;return 0;
}void test01() {int a 0;a getA1(); //将返回值10拷贝给了a。要是有多个结构体会很浪费空间char *pp NULL;pp getmen(10);int main_a 0;main_a getA3(); //main_atemp; 值拷贝cout main_a endl; //10cout main_a endl; //10//引用作为返回值不要返回局部变量的引用。否则可能会出错 getA3函数被回收没有权限访问之前的变量覆盖//引用如果当函数返回值的话函数可以当左值int main_a_re getA3();cout main_a_re endl; //10cout main_a_re endl; //-858993460int main_a_re1 getA4(); cout main_a_re1 endl; //10cout main_a_re1 endl; //10cout main_a_re1 endl; //10getA4() 1000;
}int main() {test01();return 0;
}
#endif
6引用指针
#if 1
#define _CRT_SECURE_NO_WARNINGS
#includeiostream
using namespace std;struct teacher {int id;char name[64];
};
int get_mem(struct teacher** tpp) {teacher *tp NULL;tp (teacher*)malloc(sizeof(teacher));if (tp NULL) {return 0;}tp-id 100;strcpy(tp-name, li4);*tpp tp;return 0;
}
void Free_teacher(struct teacher **tpp) {if (tpp NULL) {return;}struct teacher *tp *tpp;if (tp ! NULL) {free(tp);*tpp NULL;}
}
void test01() {struct teacher *tp NULL;get_mem(tp);cout tp-id tp-name endl;Free_teacher(tp);}
int get_mem2(struct teacher * tp) { //struct teacher *为整体相当于inttp (struct teacher *)malloc(sizeof(struct teacher));if (tp NULL) {return -1;}tp-id 1000;strcpy(tp-name, wangwu);return 0;}
void Free_teacher2(struct teacher * tp) {if (tp ! NULL) {free(tp);tp NULL;}}
void test02() {struct teacher *tp NULL;get_mem2(tp);cout tp-id tp-name endl;Free_teacher2(tp);
}
int main() {test01();test02();return 0;
}
#endif
7const引用
#if 1
#includeiostream
using namespace std;
void test01() {//如果对一个常量进行引用则必须是一个const引用//相反 如果一个普通变量用一个const引用是可以的const int a 10; //安全性较高//int b a; //错误 将 int 类型的引用绑定到 const int 类型的初始值设定项时//限定符被丢弃 03C对C的拓展const int re a;int b 20; //安全性较低const int re2 b;// ret2 200; 错误b 30;cout b endl; //30cout re2 endl; //30 const引用的目的是,禁止通过修改引用值来改变被引用的对象。//但可以通过改变被引用的对象改变引用值}void test02() {//int ref 10; //错误 引用了不合法的内存 不可以const int ref 10; //加入const后编译器处理方式为int tmp10;const int reftmp;对临时变量的引用//ref 10; //错误int *p (int*)ref;*p 1000;cout ref endl; //1000
}//引用使用场景通常用来修饰形参
void showValue(int val) {val 1000; //如果只是想显示内容 而不进行修改就使用const进行修饰cout value: val endl;
}void showValue(const int val) {//val 1000; //编译错误cout value: val endl;
}void test03() {int a 10;showValue(a); //1010
}
int main() {test01();cout -------- endl;test02();cout ------------ endl;test03();return 0;
}
#endif