C++学习(56)

本文深入探讨了C++中的内存管理概念,包括不同内存区域的用途、静态与动态变量的区别,以及常量指针的正确使用方法。同时解析了特定C++代码片段的行为,如静态成员变量的操作和位运算计数等。

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

1.分析下述程序执行的结果:

#include<iostream>
using namespace std;
class cla{
	static int n;
	public:
		cla() {
			n++;
		}
		~ cla() {
			n--;
		}
		static int get_n() {
			return n;
		}
};
int cla::n=0;
  
int main() {
	cla *p=new cla;
	delete p;
	cout<<" n="<<cla::get_n()<<endl;
	return 0;
}

分析:

类的实例化:cla *p=new cla,p分配在栈上,p指向的对象分配在堆上。
n为静态成员变量,没有this指针,属于类域,所有对象共享。
实例化——调用构造函数,所以n++;
delete——调用析构函数,所以n--。
最后输仍旧为0。



类的实例化: 1、cla p; 2、cla  *p=new cla; ?

局部变量存放在栈区,而需要new或malloc出来的就存放在堆区;1的cla p是一个变量,没有使用new,所以存放在栈区;2的*p是一个指针,也是在栈区,但是它所指向的cla对象被new在堆区。所以cla* p = new cla是栈区的指针指向堆区的对象。


类的静态数据成员的生命期与程序生命期相同,只是在该类内可见。


static int get_n() {returnn;} 
这是一个静态成员函数,也就是说在编译时期,就已经确定好了 n 的值,这是因为 static int n;被初始化为0.  
因而cla::get_n() 显然这是针对静态成员函数中的变量n的值。 
若类中还有其他类成员变量 int n 的定义,则它的调用也应该是  类::n 或者成员函数访问n ,(默认是private) 
另一角度,类成员变量n 的存储位置是在栈中,而类静态成员函数的 变量n 是存储在堆中,因而访问的也不是同一个 变量 n 的值。 


2.设x=9981,下面函数的返回值是多少?

int func(x){
int count=0;
whiel(x) {
 count++;
 x=x&(x-1);
}
return count;
}

 由于二进制数每个位置上不是1就是0 ,假设有数X ,则 x-1必然会从x的某一位借位。 

恰好&操作,同为1才真 。 (在二进制数操作中 &经常被用来清零,| 操作被用来置数)。 

因此x&(x-1)会记录两个数相差的1的个数。  最终结果是10.


3.内存空间被分为不同区域,其中用函数
void *malloc (unsigned int size);
申请的内存在:动态存储区。
分析:C 编程语言中的 malloc 、 calloc 函数和 C++ 的 new 运算符都是在动态存储区( heap )上申请内存空间 。

静态储存:全局变量、 静态变量 ;
Stack:局部变量 (系统会自动回收);
heap:new 、malloc(需要程序员自己申请回收);


stack由系统自动分配,heap需要程序员自己申请,C中用函数malloc分配空间,用free释放;C++用new分配,用delete释放。 

当然热爱java的童鞋肯定更关心java的内存空间划分(虽然强大的java让程序猿在编程时不需要考虑太多内存方面的细节) 
java 对内存空间的划分五部分; 
栈、堆、方法区、本地方法区、寄存器。 
1、栈内存:存储都是局部变量。只要是在方法中定义的变量都是局部变量。 
一旦变量的生命周期结束该变量就被释放。 
2、堆内存都是实体(对象)(new 关键词创建的) 
每一个实体都有一个首地址值。 
堆内存的变量都有默认的初始化值。不同类型不一样, 
int——0,double——0.0 boolean——false char——’\u0000’ 
当实体不在使用时,就会被垃圾回收机制处理。 

4.在C语言中,关于静态变量的说法正确的(B)
A 静态变量和常量的作用相同//与静态局部变量的作用域相同
B 函数中的静态变量,在函数退出后不被释放
C 静态变量只可以赋值一次,赋值后则不能改变//可以改变
D 静态全局变量的作用域为一个程序的所有源文件//作用域为单个源文件

分析:此题主要考察static局部变量相关知识: 
1)、静态变量在内存的静态存储区,静态数据一直占有着该存储区单元直到程序结束; 
2)、静态局部变量只声明一次,一旦申请内存成功,不再接受重复申请; 
3)、静态局部变量的作用域与一般局部变量一样,二者区别在于以上两点:一般局部变量在函数调用结束后释放变量占用的存储单元,而静态局部变量不释放。 
注意:由于静态局部变量在内存中存在的时间较长,即占用内存时间较长,故应尽量少用static来修饰变量(有刚需除外)。


函数中的静态变量是静态局部变量, 函数退出后不被释放 ,在程序运行结束时才释放。只在函数中可访问。 
静态全局变量的作用域只能是定义它的文件里,不是被其他文件使用。

5.以下选项中如果可以初始化正确,那么就会初始化正确,那么以下哪种语法在C++中初始化以后会编译会错误?其中X为C++类。
A 、const X *x; B 、X const *x; C、const X const *x; D、X *const x;

分析:AB运行没问题,
C运行提示:error: duplicate 'const'|
D运行提示:error: uninitialized const 'x' [-fpermissive]|
答案应该是CD,分析如下
先回顾一下题目:
以下哪种语法在C++中是错误的?其中X为一C++类
const X * x
X const * x
const X const * x
X * const x
这里大X表示类,小写x代表实例。
其实考的是const用法:在X *x这个经典语句中,const插到*前面还是*后面的区别。
AB没有区别,const在*号前面,都表示*x不可修改。
C中*号前面两个const,g++编译器也提示duplicate 'const',所以C的语法是错的。
D中const在*号后面,表示x指针不可修改。运行 会提示x需要初始化。 const类型的指针声明时必须初始化

题目不严谨,应该是CD
最后,借X *x的形式考const用法略奇葩。自己可以替换为传统数据类型int之类,用int *x的形式来分析

6.在C语言中,用非零表示逻辑“真”值。

7.
char *p1,int64_t *p2;
p1=(char *)0x800000;
p2=(int64_t *)0x800000;
char *a=p1+2;
int64_t *b=p2+2;
那么a=?,b=?
答:0x800002, 0x800010
我们定义指针的时候给指针一个类型就是为了方便指针的加减操作。p1是char类型指针,每个char占一个字节,所以p1+2就是在p1的基础上加2个char的长度,就是两个字节。p2是指向64位int型的指针,所以p2+2就是p2加上两个64位int的长度,也就是加上128位,即16个字节。用16进制表示是0x10
所以a=0x800000+0x2=0x800002
a=0x800000+0x10=0x800010

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值