有关类指针的问题
- 格式:doc
- 大小:72.00 KB
- 文档页数:5
含有指针变量的类需要重写拷贝构造函数,拷贝赋值函数,析构函数编译器⾃带拷贝构造(ctor)和拷贝赋值函数(operator =),但是对于成员变量含有指针的类,其不能使⽤默认的拷贝赋值函数。
因为使⽤默认的,会直接将指针指向的地址进⾏赋值 (浅拷贝,共享内存,共指⼀个对象),⽽不是分配⼀块内存,具有相同的数值 (深拷贝,独⽴,两个对象)。
浅拷贝容易造成dangling pointer。
⽤⼀个例⼦来展⽰:1 #ifndef __MYSTRING__2#define __MYSTRING__34class String{5public:6 String(const char* cstr=0);7 String(const String& str); // 拷贝构造8 String& operator= (const String& str); // 拷贝赋值9 ~String();10char* get_c_str const(){11return m_data;12 }13private:14char* m_data; // 带指针成员的类:⼀定要注意拷贝赋值,拷贝构造,析构15// String的底部通过char实现,在外部表现为string16 };1718 inline String::String ( const char* cstr=0 ){19if(cstr){20 m_data=new char[strlen(cstr)+1];21 strcpy(m_data,cstr); // char * strcpy ( char * destination, const char * source );22 }23else{ // 考虑cstr=0;24 m_data=new char[1];25 m_data[0]='\0';26 }27 }2829 inline String::String(const String& str){30 m_data=new char[strlen(str.get_c_str())+1];31 strcpy(m_data,str.m_data);32 }3334 inline String::~String(){35delete[] m_data;36 }3738 inline String& String::operator=(const String& str){39if(this==&str){ // self assignment :⾃我检验(如果没有进⾏这样的处理,在⾃我赋值会产⽣严重的错误)40return *this;41 }42// 构造函数是第⼀次,因此不需要删除,但是赋值需要先进⾏delete43delete[] m_data; // 先删除,重新分配⼀样⼤⼩!44 m_data=new char[strlen(str.get_c_str())+1];45 strcpy(m_data,str.m_data);46return *this; // 其实不⽤返回*this也可以,因为已经实现了修改,但是这样有⼀个好处可以实现 a=b=c;(因为返回的类型继续⽀持=)47 }4849// 调⽤形式: cout << String() ; 第⼀个参数为 << 左边,第⼆个参数为 << 右侧;返回ostream 可以实现 cout << a << b ;50 ostream& operator<<(ostream& os,const String& str){51 os<<str.get_c_str();52return os;53 }5455#endif。
数学能力提升解密时钟和日历问题时钟和日历问题在数学中是常见的计算问题,需要运用一定的数学知识和技巧进行解答。
本文将介绍几类常见的时钟和日历问题,并提供相应的解决方法。
一、时钟问题时钟问题主要涉及时间的计算和刻度的运用,常见的问题有以下几种类型:1. 时钟的夹角问题时钟的夹角问题是指计算时针和分针之间的夹角。
时针每小时走过30度,每分钟走过0.5度;分针每分钟走过6度。
根据这些规律,我们可以先计算时针和分针各自当前所指的角度,然后计算它们之间的夹角。
2. 时钟的相对速度问题时钟的相对速度问题是指计算两个或多个时钟指针之间的相对速度。
以两个时钟为例,假设它们的速度分别为x和y,则它们相对速度的大小为|x - y|。
根据这个公式,我们可以计算出时钟指针的相对速度。
3. 时钟指针相遇问题时钟指针相遇问题是指计算两个时钟指针相遇的时间。
以时针和分针相遇为例,假设它们的相遇时间为t,则时针走过的路程为30t,分针走过的路程为360t。
根据这个公式,我们可以计算出时钟指针相遇的时间。
二、日历问题日历问题主要涉及日期的计算和推理,常见的问题有以下几种类型:1. 日期的加减计算日期的加减计算是指在已知某个日期的基础上,计算过去或未来的某一天是星期几。
这类问题可以根据星期的周期性规律来解决,从已知日期出发,按照相应的天数进行加减计算,最后得出所求的星期。
2. 闰年和平年问题闰年和平年问题是指判断某一年是否为闰年,以及给定一个年份,计算该年的二月份有多少天。
根据公历的规定,闰年是指能被4整除但不能被100整除的年份,或者能被400整除的年份。
根据这个规律,我们可以判断出一个年份是否为闰年,并计算出该年的二月份天数。
3. 日期推理问题日期推理问题是指根据已知的一些日期信息,推理出其他日期的信息。
这类问题常常涉及一些条件和约束,需要通过逻辑推理和排除法来解决。
在解答这类问题时,我们需要仔细分析已知的信息,运用数学的推理方法,逐步找出答案。
c语言指针类面试题C语言指针是面试中常见的话题之一,下面我将从多个角度回答与C语言指针相关的面试题。
1. 什么是指针?指针是一个变量,用于存储内存地址。
它可以指向其他变量或数据,通过指针可以直接访问或修改这些数据。
2. 指针和变量的区别是什么?变量是一个具体的数据存储单元,而指针是存储变量地址的变量。
变量有自己的值,而指针存储的是另一个变量的地址。
3. 如何声明和定义指针?在C语言中,可以使用以下语法声明和定义指针:c.数据类型指针变量名;例如:c.int ptr;这声明了一个指向整型数据的指针变量ptr。
4. 如何使用指针访问变量的值?可以使用解引用运算符()来访问指针所指向的变量的值。
例如,如果有一个整型指针ptr,可以使用`ptr`来获取ptr所指向的整型变量的值。
5. 指针与数组的关系是什么?数组名本身就是一个指针,它存储了数组的首地址。
可以通过指针算术运算来访问数组中的元素,例如`(array + i)`可以访问数组中的第i个元素。
6. 什么是指针的运算?指针的运算包括指针的加法、减法、比较等操作。
指针加法可以用于在指针上进行偏移,指针减法可以计算两个指针之间的距离,指针比较可以判断两个指针是否相等或者大小关系。
7. 什么是空指针和野指针?空指针是指未指向任何有效地址的指针,可以用NULL来表示。
野指针是指指向未知或无效地址的指针,使用野指针可能导致程序崩溃或产生不可预测的结果。
8. 如何避免野指针?避免野指针的方法包括及时初始化指针、在指针使用完毕后将其置为NULL、避免对未分配内存的指针进行解引用操作等。
9. 什么是指针的指针?指针的指针是指一个指针变量存储了另一个指针变量的地址。
通过指针的指针可以实现对指针的间接访问和修改。
10. 什么是指针数组和数组指针?指针数组是指一个数组中的元素都是指针类型。
数组指针是指一个指针,它指向一个数组的首地址。
以上是对C语言指针类面试题的回答,希望能对你有所帮助。
C51 指针问题一般指针一般指针的声明和使用均与标准C 相同,不过同时还可以说明指针的存储类型,例如:long * state;为一个指向long 型整数的指针,而state 本身则依存储模式存放。
char * xdata ptr;ptr 为一个指向char 数据的指针,而ptr本身放于外部RAM 区,以上的long,char 等指针指向的数据可存放于任何存储器中。
一般指针本身用3 个字节存放,分别为存储器类型,高位偏移,低位偏移量。
2.存储器指针基于存储器的指针说明时即指定了存贮类型,例如:chardata * str;str 指向data 区中char 型数据int xdata * pow; pow 指向外部RAM 的int 型整数。
这种指针存放时,只需一个字节或2 个字节就够了,因为只需存放偏移量。
/*.........................................................................................char * xdata ptr;//ptr 本身放在Xdata(XRAM)区char xdata * ptr;//ptr 指向的数据放在Xdata(XRAM)区........................................................................................*/char xdata * pxchar xdata * data pxdata char xdata * px 这3 者有什么不同??char xdata * pxpx 本身存在于自动分配的空间,一般位于data 中,指向的内容位于xdatachar xdata * data pxpx 本身存在于data 空间,指向的内容位于xdatadata char xdata * px =char xdata *data pxdata:固定指前面0x00-0x7f 的128 个RAM,可以用acc直接读写的,速度最快,生成的代码也最小。
C语言指针的长度和类型讲解C语言指针的长度和类型讲解对于初学者深入理解C语言程序设计有很好的参考价值,下面是店铺为大家整理的C语言指针的长度和类型讲解,欢迎参考~ 一般来说,如果考虑应用程序的兼容性和可移植性,指针的长度就是一个问题,在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,尽管C标准没有规定所有类型指针的长度相同,但是通常实际情况就是这样。
但是函数指针长度可能与数据指针的长度不同。
指针的长度取决于使用的机器和编译器,例如:在现代windows 上,指针是32位或是64位长测试代码如下:#include#include#include#includestruct p{int n;float f;};int main(){struct p *sptr;printf("sizeof *char: %d ", sizeof(char*));printf("sizeof *int: %d ", sizeof(int*));printf("sizeof *float: %d ", sizeof(float*));printf("sizeof *double: %d ", sizeof(double*));printf("sizeof *struct: %d ", sizeof(sptr));return 0;}运行结果如下图所示:指针相关的预定义类型:① size_t:用于安全地表示长度② ptrdiff_t:用于处理指针算术运算③ intptr_t:用于存储指针地址④ uintptr_t:用于存储指针地址分述如下:一、size_t类型size_t 类型是标准C库中定义的,应为unsigned int,在64位系统中为long unsigned int。
C语言中,此类型位于头文件stddef.h 中。
C语言技术的常见问题及解决方案C语言作为一门广泛应用于软件开发和系统编程的编程语言,常常出现一些问题困扰开发者。
本文将讨论一些常见的C语言技术问题,并提供相应的解决方案。
问题一:内存泄漏在C语言编程中,内存泄漏是一个常见但又令人头疼的问题。
内存泄漏指的是在动态内存分配之后,没有正确释放该内存导致系统无法再次使用。
解决方案:为了避免内存泄漏,必须始终确保在使用完动态分配的内存后进行释放。
使用free函数来释放之前使用malloc或calloc函数分配的内存块。
此外,应该避免在循环中重复分配内存,以免造成内存泄漏和性能问题。
问题二:指针问题指针是C语言的一个重要特性,但也常常出现一些问题。
指针问题包括未初始化指针、指针越界、野指针等。
解决方案:避免指针问题的关键是始终确保指针的正确初始化和使用。
在声明指针变量时,应该将其初始化为NULL以避免成为野指针。
另外,访问指针指向的内存时,应该确保不越界,可以通过检查指针是否为NULL或使用合适的边界检查来避免越界访问。
问题三:数组越界访问数组越界访问是指在访问数组元素时超出了数组的有效范围。
这会导致不可预测的结果,包括程序崩溃和数据损坏等问题。
解决方案:为了避免数组越界访问,开发者需要在编写代码时严格遵守数组索引的范围。
在使用循环或指针遍历数组时,必须确保不超过数组的边界。
在进行数组操作时,使用合适的条件判断语句来控制访问边界。
问题四:类型不匹配C语言是一种静态类型语言,要求变量的类型在声明时就确定并且不能更改。
类型不匹配问题包括不同类型之间的赋值错误、函数参数类型错误等。
解决方案:为了避免类型不匹配问题,开发者需要严格遵守变量类型的规定。
在进行变量赋值时,确保变量的类型匹配。
在使用函数时,检查函数参数的类型是否与函数声明一致,并根据需要进行合适的类型转换。
问题五:死循环死循环是指程序中的循环不会结束,导致程序陷入无限循环的状态。
这常常是由于循环条件错误或循环体内没有引入适当的循环退出条件造成的。
c语言常见问题集C语言作为一种古老而强大的编程语言,在使用过程中可能会遇到各种常见问题。
以下是一些C语言常见问题及解决方法的集合:1.指针问题:问题:指针使用不当导致内存泄漏或段错误。
解决方法:谨慎使用指针,确保正确的内存分配和释放,避免野指针。
2.内存泄漏:问题:未正确释放动态分配的内存。
解决方法:在不再使用内存时,使用free函数释放动态分配的内存。
3.数组越界:问题:访问数组元素时超出了数组边界。
解决方法:确保数组索引在合法范围内,使用循环时注意控制循环边界。
4.未初始化变量:问题:使用未初始化的变量。
解决方法:在使用变量之前确保对其进行初始化,避免产生未定义行为。
5.逻辑错误:问题:程序的输出与预期不符。
解决方法:仔细检查代码逻辑,使用调试工具进行单步调试,查找错误的源头。
6.编译错误:问题:编译时出现错误。
解决方法:仔细阅读编译器报错信息,检查代码语法错误,确保使用正确的语法和标准库函数。
7.字符串处理问题:问题:字符串操作时未考虑字符串结束符\0。
解决方法:确保字符串以\0结尾,使用字符串处理函数时注意边界条件。
8.文件操作问题:问题:未正确打开、关闭文件,或者在未打开文件的情况下进行文件操作。
解决方法:在使用文件之前确保正确打开,使用完毕后关闭文件,检查文件是否成功打开。
9.结构体使用问题:问题:结构体成员的访问不当。
解决方法:确保使用正确的结构体成员名,避免结构体成员越界访问。
10.数据类型不匹配:-问题:不同数据类型之间的不匹配导致错误。
-解决方法:确保进行运算或赋值时,数据类型一致或符合隐式转换规则。
以上问题及解决方法提供了一些基本的指导,但在实际编码中,关键在于谨慎、仔细和严谨,同时善用调试工具和编程工具,及时修复潜在问题。
C++智能指针试题1.auto_ptr在C++11中被标记为已弃用,主要因为它具有哪个性质导致资源管理混乱?o A. 所有权转移时的浅拷贝o B. 可以显式释放资源o C. 强制类型转换的构造函数o D. 没有引用计数答案: A解析: auto_ptr在拷贝构造和赋值操作时,仅进行所有权转让,而不是深拷贝,这可能导致原对象的资源被释放后,新对象仍试图使用已被释放的资源,造成悬挂指针。
2.假设有一个unique_ptr对象uptr,以下哪个操作是非法的?o A. uptr->func();o B. (*uptr).func();o C. uptr = nullptr;o D. uptr = uptr;答案: D解析: unique_ptr不允许自我赋值,因为这会导致资源管理混乱,即两次释放相同的资源。
3.shared_ptr的主要优势是什么?o A. 自动管理资源的生命周期o B. 所有权的唯一性o C. 可以在不同线程间安全地传递o D. 消耗的资源比auto_ptr和unique_ptr少答案: A解析: shared_ptr通过引用计数管理资源的生命周期,当引用计数为0时自动释放资源,从而允许多个shared_ptr实例共享相同的资源。
4.以下哪项描述了unique_ptr和shared_ptr之间的一个关键区别?o A. unique_ptr可以使用new[]分配的数组o B. shared_ptr可以被复制和转移o C. unique_ptr支持任意类型o D. shared_ptr的析构函数是公有的答案: B解析: unique_ptr不支持复制和转移所有权,而shared_ptr通过引用计数机制支持复制和所有权的共享。
5.在以下代码片段中,ptr指向的对象何时被销毁?o B. 当weakPtr离开作用域时o C. 当ptr引用计数变为0时o D. 代码编译错误,无法执行答案: C解析: shared_ptr在引用计数为0时会释放资源,当ptr被赋值为weakPtr (实质上是一个shared_ptr)时,原ptr指向的对象的引用计数变为0。
有关类指针的问题
我编了一个小程序,来验证有关类指针的一个用法。
#ifndef MYSTRING_H
#define MYSTRING_H
class CMystring
{
public:
CMystring();
~CMystring();
private:
char *m_pStr;
};
#endif
#include "stdafx.h"
#include "Sample.h"
#include <stdio.h>
CMystring::CMystring()
{
printf("string constructor!\n");
}
CMystring::~CMystring()
{
printf("string disconstructor!\n");
}
int main(int argc, char* argv[])
{
CMystring *pStr1=NULL;
pStr1 = new CMystring;
delete pStr1;
CMystring *pStr2=NULL;
pStr2 = new CMystring;
delete pStr1;
return 0;
}
运行结果如下:
假如我将main函数修改为如下:int main(int argc, char* argv[]) {
CMystring *pStr1=NULL;
pStr1 = new CMystring;
// delete pStr1;
CMystring *pStr2=NULL;
pStr2 = new CMystring;
delete pStr1;
return 0;
}
我们再把main函数修改一下:int main(int argc, char* argv[]) {
CMystring *pStr1=NULL; // pStr1 = new CMystring;
// delete pStr1;
CMystring *pStr2=NULL;
pStr2 = new CMystring;
delete pStr2;
return 0;
}
运行结果如下:
通过比较这三个运行结果,我们可以发现,一个类指针以new开始启动构造函数,以delete 启动析构函数。
假如没有new,就不会有类的构造函数,同样,没有delete,也不会有类的析构函数。
那么C语言的malloc函数会不会有这个效果呢?我们再把main函数修改一下:
int main(int argc, char* argv[])
{
CMystring *pStr1=NULL;
// pStr1 = new CMystring;
// delete pStr1;
pStr1 = (CMystring*)malloc(sizeof(CMystring));
free(pStr1);
CMystring *pStr2=NULL;
pStr2 = new CMystring;
delete pStr2;
return 0;
}
看,malloc()并没有达到这个效果。
可是malloc到底有没有开辟内存空间呢?有的,而且和new开辟的内存空间一样大,但它就是不启动构造函数。
同样free也不启动析构函数。
我想这是new和delete比malloc和free优越的地方。
这一点其实林锐的《高质量C++编程
指南》已经提到过。
这一次我们是用程序证实了这一点。