boll型变量:if(!var)
int型变量: if(var==0)
float型变量:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
指针变量: if(var==NULL)
2 交换两个变量x和y的值,但不要引入第三方
void inplace_swap(int *x, int *y)
 {
{
 *x = *x ^ *y;
    *x = *x ^ *y;
 *y = *x ^ *y;
    *y = *x ^ *y;
 *x = *x ^ *y;
    *x = *x ^ *y;
 }
} 
其实这儿就运用到了 a ^ a = 0 和 a ^ 0 = a 的性质。3 
逻辑运算与位运算不同的是,如果第一个参数能确定表达式的结果,就不会对后续参数求值进行运算。如p&&*p++就不会间接引用空指针。具体原因请参看后面C的汇编表示中关于逻辑运算的汇编表示部分。
C的移位运算,左移比较简单,直接在右边的空位补0。而右移就不同了,分为逻辑右移和算术右移两种,逻辑右移也是直接在左边的空位补0,而算术右移则在左 边的空位补上最高有效位的拷贝。几乎所有的编译器/机器组合都对有符号数使用算术右移。移位运算同样很重要,乘法在Cpu上的执行要比加减法多很多指令, 为了提高效率,通常就可以用移位运算对乘法运算进行优化。
3 
cout<<sizeof(a)<<endl; // 4
cout<<sizeof(*a)<<endl; // 72
cout<<sizeof(**a)<<endl; // 24
cout<<sizeof(***a)<<endl; // 4
cout<<sizeof(****a)<<endl; // 8
a是一个很奇怪的定义,他表示一个指向double*[3][6]类型数组的指针。
既然是指针,所以sizeof(a)就是4。既然a是执行double*[3][6]类型的指针,*a就表示一个double*[3][6]的多维数组类型,因此sizeof(*a)  =3*6*sizeof(double*)=72。
同样的,**a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof  (double*)=24。
***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。
至于****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。
   sizeof操作符,对变量或对象可以不加括号,但若是类型,须加括号
4 union 与struct的空间计算
 总体上遵循两个原则:
   (1)整体空间是 占用空间最大的成员(的类型)所占字节数的整倍数
   (2)数据对齐原则----内存按结构成员的 先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。。。。。
   注意:数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。
例:[引用其他帖子的内容]
因为对齐问题使结构体的sizeof变得比较复杂,看下面的例子:(默认对齐方式下)
{
char a;
double b;
int c;
char d;
};
struct s2
{
char a;
char b;
int c;
double d;
};
cout<<sizeof(s1)<<endl; // 24
cout<<sizeof(s2)<<endl; // 16
同样是两个char类型,一个int类型,一个double类型,但是因为对界问题,导致他们的大小不同。计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1和s2的对界都取最大的元素类型,也就是double类型的对界8。然后开始摆放每个元素。
  对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,但是下一个元素d是double类型,要放到8的对界上,离1最接近的地址是8了,所以d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,16可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个元素d需要对界1,也正好落在对界上,所以d放在了20,结构体在地址21处结束。由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大小变成了24。
  对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;下一个元素c的对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,占用总空间为16,正好是8的倍数。
  这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子: 
{
char a[8];
};
struct s2
{
double d;
};
struct s3
{
s1 s;
char a;
};
struct s4
{
s2 s;
char a;
};
cout<<sizeof(s1)<<endl; // 8
cout<<sizeof(s2)<<endl; // 8
cout<<sizeof(s3)<<endl; // 9
cout<<sizeof(s4)<<endl; // 16;
   s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异。所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。
5 繼承類,
有以下C#代碼 using System;
using System; class A
class A {
{ public A()
    public A() {
    { test();
        test(); }
    } public virtual void test(){}
    public virtual void test(){} }
} class B:A
class B:A {
{ int x=1;
    int x=1; int y;
    int y; public B()
    public B() {
    { y=-1;
        y=-1; }
    } public override void test()
    public override void test() {
    { Console.WriteLine("x={0},y={1}",x,y);
        Console.WriteLine("x={0},y={1}",x,y); }
    } static void Main(string[] args)
    static void Main(string[] args) {
    { B b=new B();
        B b=new B(); }
    } }
}這類是一些很基礎的題目主要考察的是對面向對象的了解,,
首先我們要了解,繼承的時候,類的聲明,初始化。子類的聲明,內部都會先聲明父類。這里我們可以根據父親才有孩子的思想去記憶,沒有父親,哪里來孩子呢,
上面的程序父類的構造函數是調用子類的TEST()方法,我們看一下TEST方法
 Console.WriteLine("x={0},y={1}",x,y);
Console.WriteLine("x={0},y={1}",x,y);
這里是在控制臺輸出X,Y的值,C#是先初始化A讓后在初始化B,在初始化A的時候調用了子類的TEST方法,子類的TEST方法在B沒有初始化的時候Y是沒有給定值的,在沒有給定值的時候INT類型CLR會自動初始一個0到 Y里面去,所以輸出的結果將會是1,0,
6 extern修饰变量时必须要写
extern修饰函数时可以不写
6 
static全局变量与普通的全局变量的区别:
全局变量本身就是静态存储方式,所以static全局变量与普通的全局变量在存储方式上是相同的。两者的区别是,static的全局变量只有在当前文件是可见的,而全局变量在所有的源文件是可见的,前提是先extern引用它。
static局部变量和普通局部变量的区别:
普通的局部变量是存储在堆栈中的
static局部变量是存储在静态存储区中的,所以两者的存储方式不同。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
static函数与普通函数的区别:
作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。
7 
typedef union {long i; int k[5]; char c;} DATE;
struct data { int cat; DATE cow; double dog;} too;
DATE max;
printf("%d",sizeof(struct date)+sizeof(max));的执行结果是:___52____
答:DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20
data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32.
所以结果是 20 + 32 = 52.
8    请找出下面代码中的所以错误
说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
1、#include"string.h"
2、main()
3、{
4、 char*src="hello,world";
5、 char* dest=NULL;
6、 int len=strlen(src);
7、 dest=(char*)malloc(len);
8、 char* d=dest;
9、 char* s=src[len];
10、 while(len--!=0)
11、 d++=s--;
12、 printf("%s",dest);
13、 return 0;
14、}
答:
方法1:
int main(){
char* src = "hello,world";
int len = strlen(src);
char* dest = (char*)malloc(len+1);//要为\0分配一个空间
char* d = dest;
char* s = &src[len-1];//指向最后一个字符
while( len-- != 0 )
*d++=*s--;
*d = 0;//尾部要加\0
printf("%s\n",dest);
free(dest);// 使用完,应当释放空间,以免造成内存汇泄露
return 0;
}
方法2:
#include <stdio.h>
#include <string.h>
main()
{
char str[]="hello,world";
int len=strlen(str);
char t;
for(int i=0; i<len/2; i++)
{
t=str[i];
str[i]=str[len-i-1]; str[len-i-1]=t;
}
printf("%s",str);
return 0;
}
9 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
c用宏定义,c++用inline
10  软件测试都有那些种类?
黑盒:针对系统功能的测试 白合:测试函数功能,各函数接口
11 TCP/IP通信建立的过程怎样,端口有什么作用?
三次握手,确定是哪个应用程序使用该协议
12 C/C++编译器中虚表是如何完成的?
13 给两个变量,如何找出一个带环单链表中是什么地方出现环的?
一个递增一,一个递增二,他们指向同一个接点时就是环出现的地方
14 一语句实现x是否为2的若干次幂的判断
cout << boolalpha << ((i & (i - 1)) ? false : true) << endl;
15 什么是预编译,何时需要预编译:
1、总是使用不经常改动的大型代码体。
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
16
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
结果是:0 0 1 1
解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间;
而str5,str6,str7,str8是指针,它们指向相同的常量区域。
17 strlen sizeof区别
#include <string.h>
size_t strlen(const char *s);
size_t sizeof()
本质上,strlen是函数,而sizeof是算符。strlen需要进行一次函数调用,而对于sizeof而言,因为缓冲区已经用已知字符串进行了初始化,起长度是固定的,所以sizeof在编译时计算缓冲区的长度。sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。
1). strlen计算不包含终止null字节的字符串长度,而sizeof则计算包括终止null字节的缓冲区长度。
2). strlen只能用char*做参数,且必须是以'\0'结尾的。sizeof可以用类型做参数,还可以用函数做参数。数组传递给strlen就退化为指针了,传递给sizeof的参数不退化。
3). 当适用了于一个结构类型时或变量,sizeof返回实际的大小;当适用一静态地空间数组,sizeof 归还全部数组的尺寸。sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸   
4). 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:fun(char [])都等价于
fun(char  *) 
在C/C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小,需要这样做:  
   fun(const char  *s, int len)
   {  
        char* buf [len+1]; 
        memcpy(buf, s, len);
   }
5). Sizeof操作符不能用于函数类型、不完全类型或位字段。不完全类型是指具有未知存储大小的数据数据类型,如未知存储大小的数组类型,void类型等。
18 char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
有什么错?
"AAA"是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。
cosnt char* s="AAA";
然后又因为是常量,所以对是s[0]的赋值操作是不合法的。
19  c和c++中的struct有什么不同?
c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。c++中struct
和class的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private
20 #include <stdlib.h>
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,"hello world");
}
int main( )
{
char *str=NULL;
getmemory(str);
printf("%s/n",str);
free(str);
return 0;
}
程序崩溃,getmemory中的malloc 不能返回动态内存, free()对str操作很危险
21 程序跳转到绝对地址是0x100000去执行,应该怎么做?
*((void (*)( ))0x100000 ) ( );
首先要将0x100000强制转换成函数指针,即:
(void (*)())0x100000
然后再调用它:
*((void (*)())0x100000)();
用typedef可以看得更直观些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
22 char类型的取值范围是-128~~~~127
char ch=128 是以-128的补码来存的
23 进制转换
sprintf(str,"0X%x",num);//将num以十六进制的形式存入到str中
sprintf(str,"%d",num);//将num转化为字符串,实现itoa的作用。
int atoi(char*str)//将str指向的字符串转化为整数
int n,num;
scanf("%d",&num);
n=0;
for(;num>0;num>>=1)
{
    str[n++]=num&1;
}
while(n--)
{
    printf("%d",str[n]);
}
 
                     
                    
                 
                    
                 


 posted on
 posted on 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号