C++ 基础 002

1、求下面函数的返回值
int func(x)
{
int countx =0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}

假定x = 9999。 答案:8

思路:将x转化为2进制,看含有的1的个数。

2、分别写出BOOL,int,float,指针类型的变量a 与“零”的比较语句。

BOOL :  if ( !a ) or if(a)
int :   if ( a ==0)
float : const EXPRESSION EXP =0.000001
  if ( a < EXP&& a >-EXP)
pointer : if ( a != NULL) or if(a == NULL)

3、结构与联合有和区别?
(1)结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。
(2)对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。

4、输出?

a)

#include <stdio.h>
union
{
  int i;
  char x[2];
}a;

void main()
{
  a.x[0] =10;
  a.x[1] =1;
  printf("%d",a.i);
}

答案:266 (低位低地址,高位高地址,内存占用情况是Ox010A)

main()
{
union{ /*定义一个联合*/
int i;
struct{ /*在联合中定义一个结构*/
char first;
char second;
}half;
}number;
number.i=0x4241; /*联合成员赋值*/
printf("%c%c\n", number.half.first, mumber.half.second);
number.half.first=‘a‘; /*联合中结构成员赋值*/
number.half.second=‘b‘;
printf("%x\n",number.i);
getch();
}

答案: AB (0x41对应‘A‘,是低位;Ox42对应‘B‘,是高位)

6261 (number.i和number.half共用一块地址空间)

5、已知strcpy的函数原型:char *strcpy(char *strDest, const char *strSrc),其中 strDest 是目的字符串,strSrc 是源字符串。不调用 C/C++ 的字符串库函数,请编写函数 strcpy。

/*
编写strcpy函数(10分)
已知strcpy函数的原型是
char *strcpy(char *strDest, const char *strSrc);
其中strDest是目的字符串,strSrc是源字符串。
(1)不调用C++/C的字符串库函数,请编写函数 strcpy
(2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?
答:为了 实现链式表达式。 // 2分
例如 int length = strlen( strcpy( strDest, “hello world”) );
*/

#include <assert.h>
#include <stdio.h>
char*strcpy(char*strDest, constchar*strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL)); // 2分
char* address = strDest;   // 2分
while( (*strDest++=*strSrc++) !=‘\0‘ )       // 2分
NULL;
return address ;    // 2分
}

6、另外strlen函数如下:

#include<stdio.h>
#include<assert.h>
int strlen( constchar*str ) // 输入参数const
{
assert( str != NULL ); // 断言字符串地址非0
int len = 0;
while( (*str++) !=‘\0‘ )
{
len++;
}
return len;
}
复制代码

8、已知String类定义如下:

class String
{
public:
  String(const char *str = NULL); // 通用构造函数
  String(const String &another); // 拷贝构造函数
  ~String(); // 析构函数
  String& operater =(const String &rhs); // 赋值函数
private:
  char* m_data; // 用于保存字符串
};

尝试写出类的成员函数实现。

String::String(constchar*str)
{
if ( str == NULL ) // strlen在参数为NULL时会抛异常才会有这步判断
{
m_data =newchar[1] ;
m_data[0] =‘\0‘ ;
}
else
{
m_data =newchar[strlen(str) +1];
strcpy(m_data,str);
}
}
String::String(const String &another)
{
m_data =newchar[strlen(another.m_data) +1];
strcpy(m_data,other.m_data);
}

String& String::operator=(const String &rhs)
{
if ( this==&rhs)
return*this ;
delete []m_data; //删除原来的数据,新开一块内存
m_data =newchar[strlen(rhs.m_data) +1];
strcpy(m_data,rhs.m_data);
return*this ;
}

String::~String()
{
delete []m_data ;
}
复制代码

10、

void test1()
{
 char string[10];
 char* str1 = "0123456789";
 strcpy( string, str1 );
}
  试题2:
void test2()
{
 char string[10], str1[10];
 int i;
 for(i=0; i<10; i++)
 {
  str1 = ‘a‘;
 }
 strcpy( string, str1 );
}
  试题3:
void test3(char* str1)
{
 char string[10];
 if( strlen( str1 ) <= 10 )
 {
  strcpy( string, str1 );
 }
}
 解答:
  试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;
 对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10 分;
  对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节。
  剖析:
  考查对基本功的掌握:
  (1)字符串以’\0’结尾;
  (2)对数组越界把握的敏感度;
  (3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案: 2分
void strcpy( char *strDest, char *strSrc )
{
  while( (*strDest++ = * strSrc++) != ‘\0’);
}
  4分
void strcpy( char *strDest, const char *strSrc )
//将源字符串加const,表明其为输入参数,加2分
{
  while( (*strDest++ = * strSrc++) != ‘\0’);
}
  7分
void strcpy(char *strDest, const char *strSrc)
{
 //对源地址和目的地址加非0断言,加3分
 assert( (strDest != NULL) && (strSrc != NULL) );
 while( (*strDest++ = * strSrc++) != ‘\0’);
}
  10分
//为了实现链式操作,将目的地址返回,加3分!
char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != ‘\0’);
  return address;
}
  从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊!
  (4)对strlen的掌握,它没有包括字符串末尾的‘\0‘。
  读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:
int strlen( const char *str ) //输入参数const
{
 assert( strt != NULL ); //断言字符串地址非0
 int len;
 while( (*str++) != ‘\0‘ )
 {
  len++;
 }
 return len;
}

11、
void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}
void Test( void )
{
 char *str = NULL;
 GetMemory( str );
 strcpy( str, "hello world" );
 printf( str );
}
  试题5:
char *GetMemory( void )
{
 char p[] = "hello world";
 return p;
}
void Test( void )
{
 char *str = NULL;
 str = GetMemory();
 printf( str );
}
  试题6:
void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}
void Test( void )
{
 char *str = NULL;
 GetMemory( &str, 100 );
 strcpy( str, "hello" );
 printf( str );
}
  试题7:
void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str );
 ... //省略的其它语句
}
  解答:
  试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完
char *str = NULL;
GetMemory( str );
  后的str仍然为NULL;
  试题5中
char p[] = "hello world";
return p;
  的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。
  试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句
*p = (char *) malloc( num );
  后未判断内存是否申请成功,应加上:
if ( *p == NULL )
{
 ...//进行申请内存失败处理
}
  试题7存在与试题6同样的问题,在执行
char *str = (char *) malloc(100);
  后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:
str = NULL;
  试题6的Test函数中也未对malloc的内存进行释放。
  剖析:
  试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。
  对内存操作的考查主要集中在:
  (1)指针的理解;
  (2)变量的生存期及作用范围;
  (3)良好的动态内存申请和释放习惯。

时间: 2024-08-11 09:43:51

C++ 基础 002的相关文章

算法Sedgewick第四版-第1章基础-002最大公约数(Euclid’s algorithm)

1. 1 public static int gcd(int p, int q) { 2 if (q == 0) return p; 3 int r = p % q; 4 return gcd(q, r); 5 }

软件测试基础002

1.软件测试具有几个特点,请详细说明 客观性--尽力的寻找错误,但是可以不受错误的影响 权威性--专业优势,更加具有说服性 专业性--大量的实践经验,形成自己的专业 资源有保证 3.软件测试的概念 利用测试工具按照测试方案和流程对产品进行功能测试和性能测试,可出现的问题进行分析和评估. 4.软件测试的方法有哪些 从测试设计方法分类:黑盒测试,白盒测试,灰盒测试 从测试是手动还是自动上分类:手动测试,自动化测试(用程序编程测试) 下面这些情况可以做自动化:1.测试存储过程.例如用C#去测试存储过程

Java基础002 Java9开发环境搭建(Win10平台)

搭建Java9开发环境 本篇文章目标 下载和安装JDK 裸写Java代码.运行代码 下载和安装Eclipse IDE.设置 Eclipse 开发环境.了解主要的 Eclipse 组件和如何使用它们执行 Java 开发.在 Eclipse 中创建新 Java 项目(安装Eclipse需要先下载JavaSDK) 使用Gradle和Maven 下载和安装JDK 下载SDK 按照以下步骤下载并安装 JDK: 浏览 Java SE Downloads 显示最新版 JDK 的下载页面. 同意您想要下载的版本

网络基础

3.1 网络基础 001 问题:为什么要学习网络编程? 回答:(1)网络编程是一种实时更新应用数据的常用手段 (2)网络编程是开发优秀网络应用的前提和基础 002 网络基本概念 2-1 客户端(就是手机或者ipad等手持设备上面的APP) 2-2 服务器(远程服务器-本地服务器) 2-3 请求(客户端索要数据的方式) 2-4 响应(需要客户端解析数据) 2-5 数据库(服务器的数据从哪里来) 3.2 Http 001 URL 1-1 如何找到服务器(通过一个唯一的URL) 1-2 URL介绍 a

50句高级SQL语句

一个题目涉及到的50个Sql语句 --(下面表的结构以给出,自己在数据库中建立表.并且添加相应的数据,数据要全面些. 其中Student表中,SId为学生的ID) ------------------------------------表结构----------------------------------------学生表tblStudent(编号StuId.姓名StuName.年龄StuAge.性别StuSex)--课程表tblCourse(课程编号CourseId.课程名称CourseN

50个查询系列-建表和插入数据

为了练习sql语句,需要先建表: 需要建立如下的表格: tabstudent和tblteacher都是普通的表,但是talscore和tablcourse都要有主外键的关系.各自的建表语句如下: tblteacher表: CREATE TABLE `tblteacher` ( `TeaId` VARCHAR(3) NOT NULL, `TeaName` VARCHAR(20) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`TeaId`) ) ENGINE=

sql 高级查询语句总结

数据库建表语句在最后 –这是一个学生成绩管理系统,创建数据库表语句在最后,表包括四张表tblStudent 学生信息表,tblScore 成绩表 ,tblteacher 教师信息表,tblcourse 课程表 –希望大家学会使用mysql数据库,以后工作中使用的数据库是由公司决定,有可能是mysql数据库也有可能是oracel 或者sqlserver数据库, –但是所有数据库都是基于sql操作,每个数据库都有每个数据库的方言,学会基本的sql语句,接触新的数据库时候学习一下该数据库对比与 –其他

Python入门(目录全览)

目录 Python入门(目录全览) 第一篇 markdown编辑器 第二篇 计算机基础 第三篇 Python解释器和集成环境 第三篇 Python基础 第四篇 Python进阶 第五篇 文件处理 第六篇 函数基础 第七篇 函数进阶 第八篇 模块基础 第九篇 Python常用模块 第十篇 面向对象基础 第十一篇 面向对象进阶 第十二篇 面向对象高阶 第十三篇 网络编程 第十四篇 并发编程 第十五篇 MySQL数据库 Python入门(目录全览) 第一篇 markdown编辑器 001markdow

java web 开发三剑客 -------电子书

Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知Internet的目的是让各个net交互.所以,Internet实质上是将世界上各个国家.各个网络运营商的多个网络相互连接构成的一个全球范围内的统一网,使各个网络之间能够相互到达.各个国家和运营商构建网络采用的底层技术和实现可能各不相同,但只要采用统一的上层协议(TCP/IP)就可以通过Internet