1. volatile 关键字在 C++ 中的性能和 C 的一样?

作用是一样的,但是其内部实现原理可能不同。

2. scanf 格式化输入是怎么赋值的?

由于scanf输入的数据个数是不定的,从键盘输入的数据会进入缓冲流,然后将输入的数据赋值给scanf的参数。

3. 下面代码的作用?

void func(const char* input, char* output, unsigned int outLen)
{
int buf[256] = {0};
while( *input )
{
buf[*input++]++;
}
if( output && outLen )
{
int i = 0;
for(i=0; i<256; i++)
{
if( buf[i] )
{
*output++ = (char)i;
}
}
*output = 0;
}
}
// 输入input为“aaabbbccddddd”,得到output为abcd


1、下面的程序输出什么?为什么?(某 CPU 公司面试题)
int main(int argc, char* argv[])
{
    unsigned char a = 0xA5;
    unsigned char b = ~a >> 4 + 1;
    printf("%d\n", b);
    return 0;

}

(分析:第一个坑:运算符优先级,+的优先级大于>>;第二个坑:当小类型变量和整型做运算的时候,会转化为int类型。

这个题,将得到的int型的结果再截断,最后答案:250)

6. 写程序判断一个数是否是 2 的 N 次方! (某 CPU 公司面试题)

(分析:

2的1次方:0000 0001

2的2次方:0000 0010

2的3次方:0000 0100

那么,如果一个数是2的N次方,那么这个数的二进制就只有一个1.

假设X这个数是2的N次方,(X-1 & X)必然等于0!!!


7. 有 2 个数组保存着 100 以内的自然数,编程求出两个数组的交集(两个数组中同时出现的自然数)。

#include <iostream>
using namespace std; int main()
{
int a[] = {1, 2, 3, 4, 5, 6};
int b[] = {3, 5, 7, 9};
int buf[100] = {0}; for(int i=0; i<sizeof(a)/sizeof(*a); i++)
{
buf[a[i]]++;
}
for(int i=0; i<sizeof(b)/sizeof(*b); i++)
{
if( buf[b[i]] )
cout << b[i] << endl;
} return 0;
}

8. 面试时如何被问及期望的薪水,该如何回答?

(打听公司底薪+500)

9. 职场新人应该注意些什么问题?

(如果有的师傅不屌你,那么你就需要主动问师傅有什么杂活可以帮你做的,给师傅节省了时间,打好了关系,他才会也才有时间教你。不要坐着耗下去,因为即便跳槽也一样。)


1.有一个问题: C++定义一个空类,编译器都会做些什么??

(例如:定义Test空类

class Test
{
};

1:如果类中没有数据成员,那么编译器会给这个类分配固定的大小,VS是1,不可能是0

2:编译器会在类中放入构造函数、拷贝构造函数、赋值运算符、析构函数。

Test() {};

Test(const Test& obj) {};

Test& operator= (const Test& obj) {};

~Test() {};

2.二阶构造法【为解决半成品的构造对象】

(使用场所:当在构造函数里面申请资源,并且这个资源可能申请失败的时候

分析:相当于将申请资源的步骤分为两个阶段:

1:第一阶段申请不会出错的资源(类对象资源)

2:第二阶段申请可能出错的资源,并进行判断,出错返回NULL,否则返回完整对象

这样就有效地避免了半成品对象的产生!!!

4.对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形。
首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中
由空格隔开的单词反序,同时反转每个字符的大小写。

比如"Hello World"变形后就变成了"wORLD hELLO"。

(分析:

步骤1:先将大小写字母反转;

步骤2:再将整个字符串反转;

步骤3:最后以空格为分界,每段的字符串再反转一次。

代码如下:

#include <iostream>
using namespace std; // 字符大小写反转
char change_char(char ch)
{
char ret = ch; if (('a' < ch) && (ch < 'z'))
{
ret = 'A' + ch - 'a';
}
else if (('A' < ch) && (ch < 'Z'))
{
ret = 'a' + ch - 'A';
} return ret;
} // 字符串反转
void reverse(char s[], int index, int len)
{
int i = index; // 第一个位置下标
int j = index + len - 1; // 最后一个位置下标 while ( i < j )
{
char t = s[i];
s[i] = s[j];
s[j] = t; i++; j--;
}
} void solution(char s[])
{
int len = strlen(s);
int i = 0; // 空间换时间
int* space = (int*)malloc(len * sizeof(int)); // 用来记录空格的位置
int* index = (int*)malloc(len * sizeof(int)); // 用来记录空格之后第一个字符的位置
int j = 0;
int k = 0; for (i = 0; i<len; i++)
{
s[i] = change_char(s[i]);
} cout << "1th: " << s << endl; reverse(s, 0, len); cout << "2th: " << s << endl; for (i = 0; i<len; i++)
{
if (s[i] == ' ')
{
space[j] = i; // 记录第一个空格下标位置
index[j] = k; // 记录第一个字符下标位置,就是起始的字符位置0 j = j + 1;
k = i + 1;
}
}
// 最后字符串的结束符当做空格处理,所以需要再写一次
space[j] = i;
index[j] = k; for (i = 0; i <= j; i++)
{
reverse(s, index[i], space[i] - index[i]);
} free(space);
free(index);
} int main()
{
char str[] = "Hello World!"; cout << "before: " << str << endl; solution(str); cout << "after: " << str << endl; return 0;
}

1、GetMemory函数用于申请一片内存空间,要使用二重指针。

void GetMemory2(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
void main(void)
{
char *str=NULL;
GetMemory=(&str);
strcpy(str,"hello world");
printf(str);
}

2、列举几种进程的同步机制,并比较其优缺点。

答案:   原子操作  信号量机制     自旋锁    管程,会合,分布式系统  
 
3、进程之间通信的途径 
答案:共享存储系统消息传递系统管道:以文件系统为基础  
 
4、进程死锁的原因 
答案:资源竞争及进程推进顺序非法  
 
5、死锁的 4个必要条件 
答案:互斥、请求保持、不可剥夺、环路  
 
6、死锁的处理 
答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁  
 
7、操作系统中进程调度策略有哪几种? 
答案:FCFS(先来先服务),优先级,时间片轮转,多级反馈

8、(void *)ptr  和 (*(void**))ptr 的结果是否相同?(其中 ptr为同一个指针)

答案:(void *)ptr  和 (*(void**))ptr值是相同的

9、要对绝对地址 0x100000 赋值,我们可以用  (unsigned int*)0x100000 = 1234;  那么要是
想让程序跳转到绝对地址是 0x100000 去执行,应该怎么做? 
答案:*((void (*)( ))0x100000 ) ( );

首先要将 0x100000 强制转换成函数指针,即: (void (*)())0x100000

然后再调用它: *((void (*)())0x100000)();

用 typedef 可以看得更直观些: 
typedef void(*)() voidFuncPtr;

*((voidFuncPtr)0x100000)();

(但是在gcc里面编译会出错,但是写成:
typedef void(*FuncType)();
FuncType pf = (FuncType)0x10000;
pf();
可以编译通过,只不过段错误。)

10、

11、


微软亚洲技术中心的面试题!!!
1.进程和线程的差别。
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

2.测试方法

人工测试:个人复查、抽查和会审

机器测试:黑盒测试和白盒测试

unsigned short A = 10;
printf("~A = %u\n", ~A);

char c=128;
printf("c=%d\n",c);
输出多少?并分析过程

第一题,~A =0xfffffff5,int值 为-11,但输出的是uint。所以输出4294967285
第二题,c=0x80,以char的8位字节来看,最高位为1,是负数。所以在内存的存储方式为补码(补码 = 反码 + 1)所以~(10000000-1)=-128
这两道题都是在考察二进制向int或uint转换时的最高位处理。

#include<iostream.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef struct AA
{
        int b1:5;
        int b2:2;
}AA;
void main()
{
        AA aa;
        char cc[100];
         strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");
       memcpy(&aa,cc,sizeof(AA));
        cout << aa.b1 <<endl;
        cout << aa.b2 <<endl;
}
答案是 -16和1
首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit.
经过strcpy和memcpy后,aa的4个字节所存放的值是:
0,1,2,3的ASC码,即00110000,00110001,00110010,00110011
所以,最后一步:显示的是这4个字节的前5位,和之后的2位
分别为:10000,和01
因为int是有正负之分  所以:答案是-16和1

求函数返回值,输入x=9999;
int func ( x )
{
    int countx = 0;
    while ( x )
    {
        countx ++;
        x = x&(x-1);
    }
    return countx;
}
结果呢?
知道了这是统计9999的二进制数值中有多少个1的函数,且有
9999=9×1024+512+256+15
9×1024中含有1的个数为2;
512中含有1的个数为1;
256中含有1的个数为1;
15中含有1的个数为4;
故共有1的个数为8,结果为8。
1000 - 1 = 0111,正好是原数取反。这就是原理。
用这种方法来求1的个数是很效率很高的。
不必去一个一个地移位。循环次数最少。

struct bit
{   int a:3;
    int b:2;
    int c:3;
};
int main()
{
bit s;
char *c=(char*)&s;
   cout<<sizeof(bit)<<endl;
*c=0x99;
   cout << s.a <<endl <<s.b<<endl<<s.c<<endl;
     int a=-1;
   printf("%x",a);
return 0;
}
输出为什么是
4
1
-1
-4
ffffffff
因为0x99在内存中表示为 100 11 001 , a = 001, b = 11, c = 100
当c为有符合数时, c = 100, 最高1为表示c为负数,负数在计算机用补码表示,所以c = -4;同理
b = -1;

位域 :  
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:    
struct 位域结构名    
{ 位域列表 };   
其中位域列表的形式为: 类型说明符 位域名:位域长度    
例如:    
struct bs   
{   
int a:8;   
int b:2;   
int c:6;   
};   
位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:    
struct bs   
{   
int a:8;   
int b:2;   
int c:6;   
}data;   
说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:   
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:    
struct bs   
{   
unsigned a:4   
unsigned :0 /*空域*/   
unsigned b:4 /*从下一单元开始存放*/   
unsigned c:4   
}   
在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。   
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:    
struct k   
{   
int a:1   
int :2 /*该2位不能使用*/   
int b:3   
int c:2   
};   
从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。

(2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?
答:为了实现链式表达式。 // 2分
例如 int length = strlen( strcpy( strDest, “hello world”) );

编写类String的构造函数、析构函数和赋值函数
已知类String的原型为:
class String
{
 public:
String(const char *str = NULL);// 普通构造函数
String(const String &other);   // 拷贝构造函数
~ String(void);   // 析构函数
String & operate =(const String &other);// 赋值函数
 private:
char   *m_data; // 用于保存字符串
};
请编写String的上述4个函数。

标准答案:
// String的析构函数
String::~String(void)               // 3分
{
delete [] m_data;                    
// 由于m_data是内部数据类型,也可以写成 delete m_data;
}
// String的普通构造函数             
String::String(const char *str)      // 6分
{
if(str==NULL)                          
{
m_data = new char[1];    // 若能加 NULL 判断则更好
*m_data = ‘\0’;                      
}                                       
else
{
int length = strlen(str);           
m_data = new char[length+1];  // 若能加 NULL 判断则更好      
strcpy(m_data, str);                
}
}
// 拷贝构造函数
String::String(const String &other)   // 3分
{
int length = strlen(other.m_data);
m_data = new char[length+1];      // 若能加 NULL 判断则更好    
strcpy(m_data, other.m_data);         
}
// 赋值函数
String & String::operate =(const String &other)    // 13分
{
// (1) 检查自赋值                     // 4分
if(this == &other)
return *this;

// (2) 释放原有的内存资源            // 3分
delete [] m_data;

// (3)分配新的内存资源,并复制内容 // 3分
int length = strlen(other.m_data);
m_data = new char[length+1];         // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);

// (4)返回本对象的引用            // 3分
return *this;
}


请问下面程序有没有错误为什么?

(段错误: char *strcpy(char *dest, const char *src);是拷贝字符串的函数,s只是字符数组,在结尾没有’\0’字符。)

(strlen(a) = 255;因为char类型的范围为-256~255,当i=256时,a[256] = 1 0000 0000b, 产生截断,a[256]= 0,对于strlen来看相当于结束符。)




C/C++练习题(一)的更多相关文章

  1. Linux基础练习题(二)

    Linux基础练习题(二) 1.复制/etc/skel目录为/home/tuer1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限. [root@www ~]# cp -r ...

  2. shell 脚本之 shell 练习题汇总

    整理了一些 shell 相关的练习题,记录到这里. 1. 请按照这样的日期格式 xxxx-xx-xx 每日生成一个文件,例如:今天生成的文件为 2013-09-23.log, 并且把磁盘的使用情况写到 ...

  3. MySQL练习题

    MySQL练习题 一.表关系 请创建如下表,并创建相关约束 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 3.查询平均成绩大于60分的同学的学号和平均成 ...

  4. MySQL练习题参考答案

    MySQL练习题参考答案 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 思路: 获取所有有生物课程的人(学号,成绩) - 临时表 获取所有有物理课程的人(学号,成绩) - 临时表 根据[ ...

  5. mysql练习题-查询同时参加计算机和英语考试的学生的信息-遁地龙卷风

    (-1)写在前面 文章参考http://blog.sina.com.cn/willcaty. 针对其中的一道练习题想出两种其他的答案,希望网友给出更多回答. (0) 基础数据 student表 +-- ...

  6. 【UOJ#228】基础数据结构练习题 线段树

    #228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...

  7. 【Java EE 学习 28 下】【Oracle面试题2道】【Oracle练习题3道】

    一.已知程序和数据 create table test1 (id int primary key, name ), money int); ,); ,); ,); ,); 要求根据下图写出相应的sql ...

  8. 从一道NOI练习题说递推和递归

    一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可 ...

  9. 《java编程思想》读书笔记 暂停一段时间,改为上面的练习题

    发现个很尴尬的现象.我一天实在看得太快了...全写下 写博客都得一晚上.. 之前因为是第一次看这么厚的书,别人都说很难,以为会看很慢的.然而,已经完全学过Java的 我感觉没啥压力,越看越快....第 ...

  10. 很不错的sql练习题(select)

      创建表和输入数据 CREATE TABLE STUDENT (SNO VARCHAR(3) NOT NULL,    SNAME VARCHAR(4) NOT NULL,    SSEX VARC ...

随机推荐

  1. ScrollView嵌套listview ,滚动问题。设置listview不滚动

    对于ListView内部的ListView,一般用来展示少量的列表数据. 内部的ListView的高度看起来是一个固定值且无法滑动,这个就比较蛋疼了.. 提供两种解决方案,方案的核心都是重新设置内部L ...

  2. Codeforces807 A. Is it rated? 2017-05-08 23:03 177人阅读 评论(0) 收藏

    A. Is it rated? time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  3. IDEA14添加SVN

    今天升级IDEA14,发现SVN变了,折腾了好一会才搞好.记录一下,希望其他人能少走弯路.主要是IDEA14的svn是用命令行工具进行操作,这样对以后SVN的兼容性也会好很多,这个在他们官方的博客上也 ...

  4. hdu 5018

    http://acm.hdu.edu.cn/showproblem.php?pid=5018 任意给你三个数,让你判断第三个数是否在以前两个数为开头组成的Fibonacci 数列中. 直接暴力 #in ...

  5. [ajax] quick double or multiple click ajax submit cause chrome explorer's error snatshot

    快速点击ajax提交,引发的错误截图1: snapshot -2:

  6. Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox组件来从列表中选择某一项

    http://blog.csdn.net/delphiteacher/article/details/8924110 Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox ...

  7. Android-项目所有文件报红色j,状态栏无法Run 'app'

    项目所有文件报红色j,不可用状态 状态栏如下: 无法 Run 'app' 无法 Debug 'app' ........... 以下操作按钮灰色的,无法点击: 解决方案: 只需要:Sync Proje ...

  8. 设计模式之适配器模式(Adapter Pattern)

    在正式开始之前,让我们先思考几个问题: 如果现有的新项目可以利用旧项目里大量的遗留代码,你打算从头开始完成新项目还是去了解旧项目的模块功能以及接口? 如果你了解过遗留代码之后,发现有几个重要的功能模块 ...

  9. Ocelot中文文档入门

    入门 Ocelot仅适用于.NET Core,目前是根据netstandard2.0构建的,如果Ocelot适合您,这个文档可能会有用. .NET Core 2.1 安装NuGet包 使用nuget安 ...

  10. 20164317《网络对抗技术》Exp1 PC平台逆向破解

    实验目的: 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getSh ...