C语言基础
最近在写C语言,指针忘得干干净净,理一篇博客回忆一下咯。
关于指针
int a
:一个int类型,名称叫aint* a
:一个整形的指针,名称叫aint *a
:一个指向整型的地址,名称叫a(一级指针,表示a所指向的地址里面存放的是一个int类型的值)int **a
:二级指针,表示a所指向的地址里面存放的是一个指向int类型的指针(即a指向的地址里面存放的是一个指向int的一级指针)int & a
:声明一个int引用类型,名称叫a
C语言中int *a
与int* a
的区别:
用法上没有区别,理解上有区别。前者表示a地址指向的类型是整形,后者表示a是个整形的指针。
int *p
与 int **p
之区别:
一级指针存放变量的地址,指向的值是变量的内容。如int* p={1,2,3}
, p=数组的首地址,*p
=数组的第一个值;
二级指针存放一级指针的地址,指向一级指针。如int*p ={1,2,3}
, int**pp=&p
,pp=指针p的首地址,*pp
=数组的首地址,**pp
=数组第一个值1。
int &
a) 声明引用时必须指定它代表的是哪一个变量,即对它初始化。
int &a=b;
这样是声明a是变量b的引用
如果是int &a;
这样就是错的,没有指定a代表哪一个变量。
b) 引用与其所代表的变量共享同一内存单元,系统并不为引用另外分配存储单元;
这个应该好理解;就像前面所说的,张三和三娃子都是同一个人,三娃子只是张三的别名。
因此,对于 int &a=b;这个例子来说,要输出a和b 的地址,肯定是相同的。
c) 怎样区分&是引用还是取地址符呢?
方法是:判断&a这样的形式前是否有类型符即int &a=b;
如果有类型符(int)则是引用,否则是取地址运算符。
d) 对引用的初始化,可以是一个变量名,也可以是另一个引用。
换句话说:张三的别名可以是三娃子,三小子……及其他多个别名
而三娃子也可以有其他的别名,比如说:老三,小三等
用程序可以这样:
int a=1; //这里是定义一个整形变量 |
e) 引用初始化后不能再被重新声明为另一变量的别名
即三娃子既然是指张三这个人,就不能让其他人也叫三娃子
即一个别名只能对应一个原始变量,但是一个原始变量可以有多个别名,而且别名也可以由自己的别名。
int &b=a;//这个声明语句中的&是一个引用 |
const*
和*const
比如int const*a
;,实际上可以看成是int const (*a)
,这表示指针a所指向的地址可以变,但是所指向的那个值不能变。
而int *const a
;,可以看成int* (const a)
;,我们都知道a的值其实是一个地址,这就表示a所保存的地址是不可以变的,但是这个地址对应的值是可以变的。
举个*const
的例子:
int b = 3, c = 5;
int *const a = &b;
//a = &c; 这一句是错的,因为a所指向的地址是不能变的
cout<<*a<<endl; // 3
b = 6;
cout<<*a<<endl; // 6
再比如const*
的例子:
int b = 3, c = 5; |
还有一种情况,指向常量的常指针,既不能改地址,也不能改值
int b = 3, c = 5; |
const 和取地址操作
在C++中,‘const’ 关键字用于修饰变量,使其成为常量不可修改。在对 ‘const’ 类型的对象取地址时,会有一些特殊的考虑,特别是在使用重载运算符时。
取 const 对象的地址
cpp复制
const int b = 20;
const int* ptrB = &b; // ptrB 是指向 b 的常量指针const 引用
如果你使用 const 引用作为参数传递,可以确保函数内不会修改该引用的值。
cpp复制
void Print(const int& num) {
std::cout << num << std::endl;
}
int main() {
int value = 5;
Print(value); // 传递的是 value 的地址
}
C++ 引用调用
向函数传递参数的引用调用方法,把引用的地址复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
按引用传递值,参数引用被传递给函数,就像传递其他值给函数一样。因此相应地,在下面的函数 swap() 中,您需要声明函数参数为引用类型,该函数用于交换参数所指向的两个整数变量的值。
// 函数定义 |