C语言指针常量和指向常量的指针
指针常量本质是一个常量,而用指针修饰它,那么说明这个常量的值应该是一个指针。指针常量 的值是指针,这个值因为是常量,所以不能被赋值。因为指针常量是一个常量,在声明的时候一定要给它赋初值。一旦赋值,以后这个常量再也不能指向别的地址。下面的例子展示了指针常量不同于指向常量的指针:
当一个指针指向具有 const 限定的对象,称为指向常量的指针,可以修改该指针的值。然而,只能使用这样的指针来读取所指向的对象,但不能修改所指向的对象。因此,指向常量的指针常常被称为只读指针(read-only pointer)。所引用对象本身可以是常量,也可以不是常量。例子如下:
类型修饰符和类型限定符可以以任何顺序排列。因此,下面的写法是合法的:
赋值表达式 ptr_to_const=&var 必需采用隐式转换:int 指针值 &var 会自动地转换成左操作数的类型,也就是指向 const int 的指针。对于与之类似的类型操作数的运算符,编译器会隐式地将指向某一类型T的指针,转换为具有更多限定符的类型 T 的指针。
如果想将一个指针转换为有较少限定符的类型,必须使用显式的类型转换。下面的程序代码片段使用前面例子所声明的变量:
如果编译器将常量对象 c_var 放置在内存中的只读区域,那么最后一条语句将会引发运行错误。
也可以声明指向常量的常量指针,如下面函数原型的参数声明:
该函数的参数是只读指针,当该函数被调用时该只读指针参数会被初始化,并且在函数执行过程中保持该值不变。
int var; // 一个int类型的对象 int *const c_ptr = &var; // 一个int类型指针常量 *c_ptr = 123; // 合法:我们可以修改它所引用的对象 ++c_ptr; // 错误:我们不能修改指针
当一个指针指向具有 const 限定的对象,称为指向常量的指针,可以修改该指针的值。然而,只能使用这样的指针来读取所指向的对象,但不能修改所指向的对象。因此,指向常量的指针常常被称为只读指针(read-only pointer)。所引用对象本身可以是常量,也可以不是常量。例子如下:
int var; //一个int类型的对象 const int c_var = 100, // 一个int类型的常量对象 *ptr_to_const; // 一个指向常量的指针:指针本身不是常量! ptr_to_const = &c_var; // 合法:使得ptr_to_const指向c_var var = 2 * *ptr_to_const; // 合法:等效于var = 2 * c_var ptr_to_const = &var; // 合法:使得ptr_to_const指向var if ( c_var < *ptr_to_const ) // 合法:“只读”方式获取 *ptr_to_const = 77; // 错误:我们不能使用ptr_to_const修改var, // 尽管var不是常量
类型修饰符和类型限定符可以以任何顺序排列。因此,下面的写法是合法的:
int const c_var = 100, *ptr_to_const;
赋值表达式 ptr_to_const=&var 必需采用隐式转换:int 指针值 &var 会自动地转换成左操作数的类型,也就是指向 const int 的指针。对于与之类似的类型操作数的运算符,编译器会隐式地将指向某一类型T的指针,转换为具有更多限定符的类型 T 的指针。
如果想将一个指针转换为有较少限定符的类型,必须使用显式的类型转换。下面的程序代码片段使用前面例子所声明的变量:
int *ptr = &var; // 一个指向var的int指针 *ptr = 77; // 合法:ptr 不是一个只读指针 ptr_to_const = ptr; // 合法:隐式地将ptr从指向int的指针 // 转换为指向int常量的指针 *ptr_to_const = 77; // 错误:不能通过一个只读指针修改一个变量 ptr = &c_var; // 错误:不能隐式地将指向int常量的指针转换 // 为指向int 的指针 ptr = (int *)&c_var; // 合法:显式的指针类型转换总是可行的 *ptr = 200; // 尝试修改c_var:可能会造成运行错误
如果编译器将常量对象 c_var 放置在内存中的只读区域,那么最后一条语句将会引发运行错误。
也可以声明指向常量的常量指针,如下面函数原型的参数声明:
void func( const int * const c_ptr_to_const );
该函数的参数是只读指针,当该函数被调用时该只读指针参数会被初始化,并且在函数执行过程中保持该值不变。
所有教程
- socket
- Python基础教程
- C#教程
- MySQL函数
- MySQL
- C语言入门
- C语言专题
- C语言编译器
- C语言编程实例
- GCC编译器
- 数据结构
- C语言项目案例
- C++教程
- OpenCV
- Qt教程
- Unity 3D教程
- UE4
- STL
- Redis
- Android教程
- JavaScript
- PHP
- Mybatis
- Spring Cloud
- Maven
- vi命令
- Spring Boot
- Spring MVC
- Hibernate
- Linux
- Linux命令
- Shell脚本
- Java教程
- 设计模式
- Spring
- Servlet
- Struts2
- Java Swing
- JSP教程
- CSS教程
- TensorFlow
- 区块链
- Go语言教程
- Docker
- 编程笔记
- 资源下载
- 关于我们
- 汇编语言
- 大数据
- 云计算
- VIP视频