娓娓道来c指针 (6)const的使用

(6)const的使用

c中的const表达着“常量”的意思,更准确地说是“read-only”(只读)的含义。当const与指针相遇时,由于其与*的相对位置不同,会产生不一样的效果。

举例说明

(1)const位于*的左侧

如,const int *p;此时等同于int const *p;

此时,const的含义体现在:*p是只读的。

(1)const位于*的右侧

如,int *const p;

此时,const的含义体现在:p是只读的。

实验验证

int main()
{
	int foo = 1;
	int bar = 2;
	const int *pa = &foo;
	int *const pb = &foo;
	//尝试修改值
	*pa = 2;    //编译器报错:“表达时必须是可修改的左值”
	pb = &bar;  //编译器报错:“表达时必须是可修改的左值”
	return 0;
}

此时,添加语句*pa=2;会报错,因为*pa是只读的,不可更改;pb=&bar;同样会报错,因为pb是只读的,不可更改。

上面提到,const的本意是“只读”,而并非“常量”。通过一些方法,可以更改它的值。

int main()
{
	const int foo = 1;
	printf("foo...%d\n", foo);
	int *pa = &foo;  //这里有警告,但仍可运行
	*pa = 2;
	printf("foo...%d\n", foo);
	system("pause");
	return 0;
}

运行

从结果看,成功更改了本已声明为只读的foo。这段代码,在c中编译只是有警告,在cpp下编译直接出错。不知还有没有其它的方法,大家可推荐下。

const与结构体类型相遇,此时const会const到什么程度?

typedef struct
{
	char *name;
	char *address;
	int age;
}Person;
void setPerson(const Person* pPer)
{
	/*以下方式会出错!
	pPer->name = "David";
	pPer->address = "BeiJing";
	pPer->age = 22;
	*/
	strcpy(pPer->name, sizeof("David"), "David");
	strcpy(pPer->address, sizeof("BeiJing"), "BeiJing");
}
int main()
{
	Person per;
	char name[10] = "zx";
	char address[20] = "QiChun";
	per.name = name;
	per.address = address;
	per.age = 24;
	printf("per.name...%s\n", per.name);
	printf("per.address...%s\n", per.address);
	printf("per.age...%d\n", per.age);
	printf("update..\n");
	setPerson(&per);
	printf("per.name...%s\n", per.name);
	printf("per.address...%s\n", per.address);
	printf("per.age...%d\n", per.age);
	return 0;
}

运行

编译时无任何警告,从运行结果看,const修饰符起到的作用是这样的:

若直接初始化 per = { "zx", "QiChun" };则在setPerson()方法中,修改name和address所指向的内容也是不可以的。这里的原因不是因为const,而是"zx"和"QiChun"都是常量字符串。一般情况下,常量字符串都位于内存中的只读区域,本身是不可修改的。故在代码中,我们选择申请栈空间。

专栏目录:C指针

时间: 2024-10-06 13:44:41

娓娓道来c指针 (6)const的使用的相关文章

娓娓道来c指针 (0)c语言的梦魇:c指针

(0)c语言的梦魇:c指针 序 c语言中有一个重点:c指针.它也是一个难点.当然,这是一句废话:重点往往也是难点.在c标准中,对指针的定义是这种: 指针的类型是derived from其他类型,也就是说指针的类型是由它指向的类型决定的: 指针是一种reference类型,即引用类型: c指针似乎非常难理解,以至于有人指出:掌握了c指针,就掌握了c语言的精髓.本系列就来聊聊c指针,要想弄懂c指针.光就指针本身进行理解,还不够. 由于指针的本质就一句话:指针就是地址.这句话大多数学过c语言的人都明白

const与指针修改const对象

我们都知道const对象作用是声明变量为常量,在程序中除非显示转换,否则无法修改. 本文针对显示修改的情况,提醒了一种隐式的错误,以及解决办法. 考虑下面的代码: #include<iostream> int main(){ const int a=0; int *p=const_cast<int*>(&a);//&a返回int *,const_cast<int*>显示转换为int*. *p =1; int b=*p; int c=a; std::cou

C++指针与const

在C++中,const修饰符一般用于修饰常量.常量在定义的时候必须初始化,而且值一旦定义之后就不能修改,这样就能保证常量的值在程序运行过程中不会发生变换. 1.指向const对象的指针 指向const对象的指针本身的指向可以发生变换,但是不可以通过该指针修改所指向变量的值.指向const对象的指针在定义的时候无需初始化,而且这种类型的指针也可以指向普通变量,只不过不能通过该指针修改对应变量的值,即便对应变量不是常量.指向常量的指针在类型标识符前必须有const修饰符修饰,否则编译不通过. 指向c

C++中的指针与const

刚开始接触C++时,指针和const之间的关系有点混乱,现在总结如下: 一.指向const变量的指针 #include<iostream.h> void main() { const int *p=NULL; const int a=10; p=&a; cout<<"*p="<<*p<<endl; int b=100; p=&b; cout<<"*p="<<*p<<e

娓娓道来c指针 (8)开发可变参数函数

(8)开发可变参数函数 在c语言中,可变参数的函数极其常见,如常用的printf().可变参数函数的一般形式如下: 返回值类型 函数名(类型1 参数1,类型2 参数2,...类型n 参数n,...); 如上所示,这是一个典型的可变参数样式,它共有n个确定的参数,最后的...表示可变参数的含义.必须指出...必须位于最后,并且它至少要有一个确定的参数,原因后面陈述. 为了开发可变参数的函数,需用到头文件stdarg.h.下面共给出两个实例,在实例中详细解释用法.一是求可变个整数的和:二是模仿pri

指向const对象的指针和const指针

const char *p1;/指向const对象的指针 char const *p2;//同上 char *const p3;//const 指针 区别:const后面是什么就限定什么,比如char const *p 就是限定(*p),(*p)就是p指向的那段内存不能变,p的值可以改变,如果是char* const p就是限定p指针的值. 1. 指向const对象的指针,适合做函数形参,保证指向对象不被修改 1.1 p1指向的值不可改变,指向const对象,但是p1可以被修改指向非const对

深入学习 const指针,const引用

指针和引用的区别: 1.指针可以为空,引用不可以为空. 2.指针初始化后可以重新指向新对象,引用初始化以为不可以重新绑定新对象, 3.指针可以在初始化时赋值,可以初始化以后通过赋值运算符(=)赋值:引用只能在初始化时赋值. 4.指针是个实体(占内存4byte),引用只是个别名(不占内存) 5.指针sizeof是4byte,引用sizeof是绑定对象的大小. 6.指针是类型安全,引用是类型安全的. const对于指针和引用的区别: int a = 1: int b = 1: const int *

娓娓道来c指针 (2)内存分配

(2)内存分配 c语言中描述变量的时候常用的两个用语 1.作用域:也叫可见域,指的是变量的作用范围.在哪个范围内,该变量是可见的.可以使用的. 2.生存期:也叫存储期,指的是变量从创建到销毁的生存时间段. 作用域和存在域是两个不同的概念,比如在程序的某个位置,某变量存在(内存中分配了地址)但不可见(不可使用). 作用域 从作用域看,变量分为以下三种: 1.全局变量 在c语言中,把在任何函数之外声明的变量称为全局变量.一般情况下,全局变量在任何地方都是可见的.当然也有例外,比如在语句块{}内声明了

娓娓道来c指针 (3)指针和数组

(3)指针和数组 在c中指针和数组似乎有着千丝万缕的关系.其实它们不是一回事:指针是指针,数组是数组,两者不相同. 说它们有关系,不过是因为常见这样的代码: int main() { int array[] = {1,2,3,4,5}; int n = sizeof(array) / sizeof(int); int *p = array; int i; for (i = 0; i < n; i++) printf("p[%d]...%d\n", i, p[i]); system