const与sizeof

本文详细介绍了C和C++中const关键字的多种用途及其重要性,包括定义常量、修饰函数参数及返回值、指针和引用的使用场景等。同时对比了const与宏定义的区别,并解释了为何应优先选择const。此外还探讨了const在不同上下文中的应用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Q: const的用途

在C中,const的用法有定义常量,修饰函数参数,修饰函数返回值。在C++中,const还可以修饰函数的定义体,定义类中某个成员函数为恒态函数,即不改变类中的数据成员。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

Q: const和#define都能定义常量,但用const优点更多。

(1)const常量有数据类型,宏常量没有数据类型。编译器可以对前者进行类型的安全检查,后者只进行字符替换,没有类型安全检查,并且在字符替换中可能产生意料不到的错误。

(2)有些调试工具可以对const进行调试,但是不能对宏常量进行调试。const常量完全取代宏常量。


C++离港篇的const教学。

如果定义一个整型。

int x; //变量

变量名:x

存储地址: &x

存储内容: 3


如果加上 const int x;//常量

变量名:x

存储地址:&x

存储内容:3

其中const的存储内容划线,代表是常量,从此不能再更改。


const与指针类型。

	const int *p = NULL;
	int const *p = NULL;//两种写法完全等价
<span style="white-space:pre">	</span>int *const p = NULL;//与上两种有区别

	const int *const p = NULL;//两种写法完全等价
	int const *const p = NULL;

注意以下写法。

<span style="white-space:pre">	</span>int x = 3;
	const *p = &x;
	//p = &x;//正确
	//*p = 4;//错误,因为定义为const,就不能修改,如果不是const则可以
变量名| 存储地址 | 存储内容

x &x 3

p &p &x

如果打印p和*p的话,就是地址值和3。

如果把const的值,放在*后,p的前面,意思就是p=&x被定义为了const,p中的值是x的地址不能改变。但是可以改变*p,通过改变*p可以改变x。

变量 | 存储地址 | 存储内容

x &x3

p &p &x

<span style="white-space:pre">	</span>int x = 3;
	int *const p = &x;
	//p=&y;错误,因为那快内存已被定义为&x,不可更改

如果,前后都用了const。

	const int x = 3;
	const int *const p = &x;
	//p=&y;*p=4;都是错的

变量 | 存储地址 | 存储内容

x &x 3

p &p &x


const与引用。

定义如下。

<span style="white-space:pre">	</span>int x = 3;
	const int &y = x;
	//x=10;正确
	//y=20;错误 

变量名 | 存储地址 | 存储内容

x &x 3


	const int x = 3;
	int *y = &x;//错误,x不可变,*y是可变的,因此存在风险,通过改变*y改变x,编译器禁止

	int x = 3;
	const int *y = &x;//指针*y指向的位置不可变,只有读权限,改变x可以改变*p,允许


在函数中,const的应用也比较普遍,因为可以保障传入函数内部的变量不会因为误操作而修改原有的值。

void fun(const int &a,const int &b)
{
	a = 10;//错误,不能给常量赋值
	b = 20;
}




sizeof的应用。

//sizeof的应用
char* ss1 = "01234567890";      cout << sizeof(ss1) << endl;//输出的是字符指针,指针固定大小4字节,输出为4
char ss2 = "01234567890";		cout << sizeof(ss2) << endl;//1个char,1个字节,加隐含的"\0",所以是11
char ss3[100] = "01234567890"; cout << sizeof(ss3) << endl;//100
int ss4[100];									cout << sizeof(ss4) << endl;//int为4字节,输出400
char q1[] = "abc";							cout << sizeof(q1) << endl;//4
char q2[] = "a\n";							cout << sizeof(q2) << endl;//"\n"为一个字节,加隐含的"\0",3
char* q3 = "a\n";							cout << sizeof(q3) << endl;//指针,4
char *str1 = (char*)malloc(100);	cout << sizeof(str1) << endl;//4
char *str2 = (void*)malloc(100);	cout << sizeof(str2) << endl;//4

考虑下面两个结构体的size。

class B
{
private:
	bool m_bTemp;
	int m_nTemp;
	bool m_bTemp2;
};

class C
{
private:
	int m_nTemp;
	bool m_bTemp;
	bool m_bTemp;
};

cout << sizeof(B) << sizeof(C) << endl;
由于在内存中遵循对齐的规则,并且内存寻址以4字节为单位,两个在数据中存放样式如下

B:

|bool|——|——|——|

|       int     |

|bool|——|——|——|

C:

|       int    |

|bool|bool|——|——|

所以输出为,12,8。


Q:sizeof和strlen之间的区别

char *ss = "01234567890";
sizeof(ss);//指针的大小,输出为4
sizeof(*ss);//*ss的第一个字符,输出为1

char ss[] = *ss = "01234567890";
sizeof(ss);//加上“\0”,结果为11
sizeof(*ss);//*ss的第一个字符,输出为1

char ss[100] = "0123456789";
sizeof(ss); //结果为100
strlen(ss);//结果为10,计算字符串长度,遇到“\0”停止

int ss[100] = "0123456789";
sizeof(ss);//结果为400
strlen(ss);//结果错误,只能参数为char*,且是以“\0”结尾

class X
{
	int i;
	int j;
	char k;
};
X x;
sizeof(X);//12,内存要对齐
sizeof(x)//12

sizeof是算符,strlen是函数。


Q:内联函数和宏定义的差别是什么?

内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,编译时直接把内联函数的代码镶嵌到目标代码中,提升效率。一般逻辑简单,不用反复调用的函数可以写为inline。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值