C/C++指针ios
int a; int* p = &a; // 指向a地址的指针*pc++
一、与const一块儿的时候 char * const p; // 指针不可变,也就是指针只能指向一个地址char* p的指针; char const * p; // 所指内容不可改,也就是p是常量字符串 char const * const p; // 内容和指针都不能改 const char * const p; // 同上...内容和指针不能改 二、str[]和str的区别程序员
#include <iostream> using namespace std; int main() { 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; }
结果是0011, 这但是说是一个深拷贝/浅拷贝的问题.当字符串是数组形式声明并初始化,编译器认为是新数组,分配新空间,但不是深拷贝,由于根本就不算拷贝.而若是是相同的字符串,用指针声明,那就是比较若是有同样的字符串,就直接把新指针指过去,这是正宗的浅拷贝.面试
三、str[]用sizeof判断会出错么?算法
#include <iostream> using namespace std; int MyStrlen( char str[] ) { return ( int )( sizeof( str ) - 1 ); } int main() { char str[] = "mimiasd"; cout << MyStrlen( str ) << endl; }
不管什么时候,返回的老是3。当用函数传递的数组指针的时候就自动退化为指针了,而指针的长度是4,减去1天然就是3.可是若是按照下面代码就能够获得正常的值:数据库
char str[] = "mimiasd"; int len = sizeof( str ) - 1; // 减1是为了去掉'/0'。 cout << len << endl; // 结果为7。
四、注意数组指针和指针数组
#include <iostream> using namespace std; int main() { int a[ 5 ] = { 1, 2, 3, 4, 5 }; int *ptr = ( int* )( &a + 1 ); cout << *( a + 1 ) << " " << *( ptr - 1 ) << endl; }
答案是2 5,首先,a是一个数组,因此编译器解释&a就是a的所有长度,就是说(&a+1)也就是说移动了一个数组,指向了并不存在的a[5],因此ptr-1才会指向a数组的最后一个元素a[4],而a+1和a[1]是同样的...因此答案是25,若是你去掉了(&a+1)的括号,那么答案就是想固然的21了。网络
五、注意指针要分配给足够的空间多线程
#include <iostream> #include <string.h> using namespace std; int main() { char a; char *str = &a; strcpy( str, "hello" ); cout << str << endl; }
运行输出后程序由于访问了没有分配的空间,固然崩溃了.若是你只strcpy(str,"");那程序是能够正常运行的.并发
六、当心编译器的指针字符串初始化
#include <iostream> using namespace std; int main() { char *s = "AAA"; cout << s << endl; s[ 0 ] = 'B'; cout << s << endl; }
这段程编译器报告正常, 输出AAA后报错,由于当在第一句初始化的时候,编译器就认为这是个字符串常量了...再作数组操做的时候确定错了罗...最好的习惯是声明一个指针,用new分配空间,而后用库函数操做,好比strcpy,strcat等等...
七、让人一眼看上去迷糊的函数指针
int ( *s[ 10 ] )( int );
其实这是一个函数指针数组,指向了一组int fun(int)的函数,第一眼确实让人有点迷糊...可是请习惯这样...
八、注意函数传递指针的时候的副本
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; void GetMemory( char *p ) { p = new char[ 100 ]; strcpy( p, "hello world" ); } int main() { char *str = NULL; GetMemory( str ); cout << str; delete [] str; str = NULL; }
缘由很简单...GetMemory这个函数出问题了!函数参数是不能传递分配空间的...由于传递过去其实是一个副本p...不能返回的...并且你在delete那就是件很危险的。
能够以下修改代码:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; void GetMemory( char **p ) { *p = new char[ 100 ]; strcpy( *p, "hello world" ); } int main() { char *str = NULL; GetMemory( &str ); cout << str; delete [] str; str = NULL; }
9、请时刻记住要初始化字符串
#include <iostream> #include <string.h> using namespace std; int main() { char a[ 10 ]; cout << strlen( a ) << " " << sizeof( a ) << endl; }
输出是2 10。其实strlen函数的结果和是否初始化有关的...虽然你分配了空间..可是没有初始化..库函数会出错的..sizeof不受影响...切忌初始化哦....
十、小括号、大区别 char (*str)[20]; // str是一个数组指针,即指向数组的指针. char *str[20]; // str是一个指针数组,其元素为指针型数据.
#include <iostream> #include <string.h> #include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <memory.h> using namespace std; typedef struct AA { int b1:5; int b2:2; } AA; int main() { AA aa; char cc[ 100 ]; strcpy( cc, "0123456789abcdefghijklmnopqrstuvwxyz" ); memcpy( &aa, cc, sizeof( AA ) ); cout << aa.b1 << endl; cout << aa.b2 << endl; }
首 先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是有正负之分。
预处理器(Preprocessor)
一、用预处理指令#define 声明一个常数,用以代表1年中有多少秒(忽略闰年问题)
#include <iostream> #include <string.h> #define SECONDS_PER_YEARS 60 * 60 * 24 * 365UL using namespace std; int main() { unsigned long mimiasd = SECONDS_PER_YEARS; cout << mimiasd << endl; }
2、写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。
#include <iostream> using namespace std; #define MIN( a, b ) ( a < b ? a : b ) int main() { int a, b; cin >> a; cin >> b; cout << "The min number is : " << MIN( a, b ) << endl; }
least = MIN(*p++, b);
输出结果为一地址表示的负数。 p++中++的优先级大于, 因此至关与*(p++).
三、预处理器标识#error的目的是什么?
#ifdef XXX ... #error "XXX has been defined" #else #endif 这样,若是编译时出现错误,输出了XXX has been defined,代表宏XXX已经被定义了。
死循环(Infinite loops)
四、 嵌入式系统中常常要用到无限循环,你怎么样用C编写死循环呢? 首选的方案是:
while(1) { }
一些程序员更喜欢以下方案:
for(;;) { }
这个实现方式让人为难,由于这个语法没有确切表达到底怎么回事。若是一个应试者给出这个做为方案,我将用这个做为一个机会去探究他们这样作的基本原理。
第三个方案是用 goto
Loop: ... goto Loop;
应试者如给出上面的方案,这说明或者他是一个汇编语言程序员(这也许是好事)或者他是一个想进入新领域的BASIC/FORTRAN程序员。
数据声明(Data declarations)
a) int a; // An integer b) int *a; // A pointer to an integer c) int **a; // A pointer to a pointer to an integer d) int a[10]; // An array of 10 integers e) int *a[10]; // An array of 10 pointers to integers f) int (*a)[10]; // A pointer to an array of 10 integers g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
Static
六、 关键字static的做用是什么? 这个简单的问题不多有人能回答彻底。在C语言中,关键字static有三个明显的做用:
Const
7、下面的声明都是什么意思? const int a; int const a; const int a; int * const a; int const * a const; /*****/ 前两个的做用是同样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针能够)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是能够修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。若是应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即便不用关键字 const,也仍是能很容易写出功能正确的程序,那么我为何还要如此看重关键字const呢?我也以下的几下理由:
八、关键字volatile有什么含意?并给出三个不一样的例子。 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都当心地从新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
位操做(Bit manipulation)
9、嵌入式系统老是要用户对变量或寄存器进行位操做。给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操做中,要保持其它位不变。
#define BIT3 (0x1 访问固定的内存位置(Accessing fixed memory locations)
十、嵌入式系统常常具备要求程序员去访问某特定的内存位置的特色。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。 这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。这一问题的实现方式随着我的风格不一样而不一样。典型的相似代码以下:
int *ptr; ptr = (int *)0x67a9; *ptr = 0xaa55;
A more obscure approach is: 一个较晦涩的方法是:
*(int * const)(0x67a9) = 0xaa55;
即便你的品味更接近第二种方案,但建议你在面试时使用第一种方案。
中断(Interrupts)
__interrupt double compute_area (double radius) { double area = PI * radius * radius; printf("\nArea = %f", area); return area; }
这个函数有太多的错误了,以致让人不知从何提及了: 1)ISR 不能返回一个值。若是你不懂这个,那么你不会被雇用的。 2) ISR 不能传递参数。若是你没有看到这一点,你被雇用的机会等同第一项。 3) 在许多的处理器/编译器中,浮点通常都是不可重入的。有些处理器/编译器须要让额处的寄存器入栈,有些处理器/编译器就是不容许在ISR中作浮点运算。此外,ISR应该是短而有效率的,在ISR中作浮点运算是不明智的。 4) 与第三点一脉相承,printf()常常有重入和性能上的问题。若是你丢掉了第三和第四点,我不会太为难你的。不用说,若是你能获得后两点,那么你的被雇用前景愈来愈光明了。
十二、下面的代码输出是什么,为何?
#include <iostream> #include <stdio.h> using namespace std; void foo(void) { unsigned int a = 6; int b = -20; ( a + b > 6 ) ? puts( "> 6" ) : puts( "6" ); } int main() { foo(); }
输出>6。缘由是当表达式中存在有符号类型和无符号类型时全部的操做数都自动转换为无符号类型。所以-20变成了一个很是大的正整数,因此该表达式计算出的结果大于6。
unsigned int zero = 0; unsigned int compzero = 0xFFFF; /*1's complement of zero */
对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写以下:
unsigned int compzero = ~0;
动态内存分配(Dynamic memory allocation)
char *ptr; if ((ptr = (char *)malloc(0)) == NULL) puts("Got a null pointer"); else puts("Got a valid pointer");
这是一个有趣的问题。最近在个人一个同事不经意把0值传给了函数malloc,获得了一个合法的指针以后,我才想到这个问题。这就是上面的代码,该代码的输出是"Got a valid pointer"。我用这个来开始讨论这样的一问题,看看被面试者是否想到库例程这样作是正确。获得正确的答案当然重要,但解决问题的方法和你作决定的基本原理更重要些。
Typedef
15 Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也能够用预处理器作相似的事。例如,思考一下下面的例子:
#define dPS struct s * typedef struct s * tPS;
以上两种状况的意图都是要定义dPS 和 tPS 做为一个指向结构s指针。哪一种方法更好呢?(若是有的话)为何? 这是一个很是微妙的问题,任何人答对这个问题(正当的缘由)是应当被恭喜的。答案是:typedef更好。思考下面的例子: dPS p1,p2; tPS p3,p4; 第一个扩展为 struct s * p1, p2 上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。
16 . C语言赞成一些使人震惊的结构,下面的结构是合法的吗,若是是它作些什么?
int a = 5, b = 7, c; c = a+++b;
这个问题将作为这个测验的一个愉快的结尾。无论你相不相信,上面的例子是彻底合乎语法的。问题是编译器如何处理它?水平不高的编译做者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽量全部合法的用法。所以,上面的代码被处理成:
c = a++ + b;
所以, 这段代码持行后a = 6, b = 7, c = 12。 若是你知道答案,或猜出正确答案,作得好。若是你不知道答案,我也不把这个看成问题。我发现这个问题的最大好处是这是一个关于代码编写风格,代码的可读性,代码的可修改性的好的话题。
一、局部变量可否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,须要使用"::"
局部变量能够与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内能够定义多个同名的局部变量,好比在两个循环体内都定义一个同名的局部变量,而那个局部变量的做用域就在那个循环体内。
二、如何引用一个已经定义过的全局变量?
答:extern
能够用引用头文件的方式,也能够用extern关键字,若是用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,若是你用extern方式引用时,假定你犯了一样的错误,那么在编译期间不会报错,而在链接期间报错。
三、全局变量可不能够定义在可被多个.C文件包含的头文件中?为何?
答:能够,在不一样的C文件中以static形式来声明同名全局变量。
能够在不一样的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时链接不会出错.
四、语句for( ;1 ;)有什么问题?它是什么意思?
答:和while(1)相同。
五、do……while和while……do有什么区别?
答:前一个循环一遍再判断,后一个判断之后再循环
六、请写出下列代码的输出内容
如下是引用片断:
#include <stdio.h> int main() { int a,b,c,d; a=10; b=a++; c=++a; d=10*a++; printf("b,c,d:%d,%d,%d",b,c,d); return 0; }
答:10,12,120
七、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
全局变量(外部变量)的说明以前再冠以static 就构成了静态的全局变量。全局变量自己就是静态存储方式, 静态全局变量固然也是静态存储方式。 这二者在存储方式上并没有不一样。这二者的区别虽在于非静态全局变量的做用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其做用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。因为静态全局变量的做用域局限于一个源文件内,只能为该源文件内的函数公用, 所以能够避免在其它源文件中引发错误。
从以上分析能够看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的做用域, 限制了它的使用范围。
static函数与普通函数做用域不一样。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件之外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其余文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每一个被调用中维持一份拷贝
八、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。
九、设有如下说明和定义:
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.
固然...在某些16位编辑器下, int多是2字节,那么结果是 int2 + DATE10 + double8 = 20
十、队列和栈有什么区别?
队列先进先出,栈后进先出
十二、引用与指针有什么区别? 1) 引用必须被初始化,指针没必要。 2) 引用初始化之后不能被改变,指针能够改变所指的对象。 3) 不存在指向空值的引用,可是存在指向空值的指针。
1三、描述实时系统的基本特性 在特定时间内完成特定的任务,实时性与可靠性
1四、 全局变量和局部变量在内存中是否有区别?若是有,是什么区别? 全局变量储存在静态数据库,局部变量在堆栈
1五、 什么是平衡二叉树? 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1
1六、堆栈溢出通常是由什么缘由致使的? 没有回收垃圾资源
1七、 什么函数不能声明为虚函数? constructor
1八、冒泡排序算法的时间复杂度是什么? O(n^2)
1九、写出float x 与“零值”比较的if语句。 if(x>0.000001&&x<-0.000001)
Internet采用哪一种网络协议?该协议的主要层次结构? tcp/ip 应用层/传输层/网络层/数据链路层/物理层
Internet物理地址和IP地址转换采用什么协议? ARP (Address Resolution Protocol)(地址解析協議)
22.IP地址的编码分为哪俩部分? IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上以后才能区分哪些是网络位哪些是主机位。
23.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至所有输出。写出C程序。 循环链表,用取余操做作
24.不能作switch()的参数类型是: switch的参数不能为实型。
2五、写出下列代码的输出内容
#include<stdio.h> int inc( int a ) { return( ++a ); } int multi( int *a, int *b, int *c ) { return( *c = *a**b ); } typedef int( FUNC1 )( int in ); typedef int( FUNC2 ) ( int*, int*, int* ); void show( FUNC2 fun, int arg1, int*arg2 ) { FUNC1* p = &inc; int temp = p( arg1 ); fun( &temp, &arg1, arg2 ); printf( "%d\n", *arg2 ); } int main() { int a; show( multi, 10, &a ); return 0; }
结果是110.
2六、请找出下面代码中的因此错误
说明:如下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba
一、#include"string.h" 二、main() 三、{ 四、 char*src="hello,world"; 五、 char* dest=NULL; 六、 int len=strlen(src); 七、 dest=(char*)malloc(len); 八、 char* d=dest; 九、 char* s=src[len]; 十、 while(len--!=0) 十一、 d++=s--; 十二、 printf("%s",dest); 1三、 return 0; 1四、}
答: 方法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; }
1 、-1,2,7,28,,126请问28和126中间那个数是什么?为何? 第一题的答案应该是4^3-1=63 规律是n^3-1(当n为偶数0,2,4) n^3+1(当n为奇数1,3,5) 答案:63
二、用两个栈实现一个队列的功能?要求给出算法和思路! 设2个栈为A,B, 一开始均为空.
入队: 将新元素push入栈A;
出队: (1)判断栈B是否为空; (2)若是不为空,则将栈A中全部元素依次pop出并push到栈B; (3)将栈B的栈顶元素pop出;
这样实现的队列入队和出队的平摊复杂度都仍是O(1), 比上面的几种方法要好。
三、在c语言库函数中将一个字符转换成整型的函数是atol()吗,这个函数的原型是什么? 函数名: atol 功 能: 把字符串转换成长整型数 用 法: long atol(const char *nptr); 程序例: #include <stdlib.h> #include <stdio.h> int main(void) { long l; char *str = "98765432";
l = atol(lstr); printf("string = %s integer = %ld\n", str, l); return(0); }
2.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现? c用宏定义,c++用inline
3.直接连接两个信令点的一组链路称做什么? PPP点到点链接
四、软件测试都有那些种类? 黑盒:针对系统功能的测试 白盒:测试函数功能,各函数接口
五、肯定模块的功能和模块的接口是在软件设计的那个队段完成的? 概要设计阶段
1.进程和线程的差异。 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度:线程做为调度和分配的基本单位,进程做为拥有资源的基本单位 (2)并发性:不只进程之间能够并发执行,同一个进程的多个线程之间也可并发执行 (3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但能够访问隶属于进程的资源. (4)系统开销:在建立或撤消进程时,因为系统都要为之分配和回收资源,致使系统的开销明显大于建立或撤消线程时的开销。
2.测试方法 人工测试:我的复查、抽查和会审 机器测试:黑盒测试和白盒测试
3.列举几种进程的同步机制,并比较其优缺点。 原子操做 信号量机制 自旋锁 管程,会合,分布式系统
4.进程之间通讯的途径 共享存储系统 消息传递系统 管道:以文件系统为基础
5.进程死锁的缘由 资源竞争及进程推动顺序非法
12.死锁的4个必要条件 互斥、请求保持、不可剥夺、环路
14.类的静态成员和非静态成员有何区别? 类的静态成员每一个类只有一个,非静态成员每一个对象一个
15.纯虚函数如何定义?使用时应注意什么? virtual void f()=0; 是接口,子类必需要实现
16.数组和链表的区别 数组:数据顺序存储,固定大小 连表:数据能够随机存储,大小可动态改变
17.ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点? 应用层 表示层 会话层 运输层 网络层 物理链路层 物理层 tcp /udp属于运输层 TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操做和多路复用技术等。 与 TCP 不一样, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。因为 UDP 比较简单, UDP 头包含不多的字节,比 TCP 负载消耗少。 tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性很差 udp: 不提供稳定的服务,包头小,开销小
一、(void )ptr 和 ((void**))ptr的结果是否相同?其中ptr为同一个指针 .(void )ptr 和 ((void**))ptr值是相同的
二、int main() { int x=3; printf("%d",x); return 1;
} 问函数既然不会被其它函数调用,为何要返回1? mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息
三、要对绝对地址0x100000赋值,咱们能够用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么作? ((void ()( ))0x100000 ) ( ); 首先要将0x100000强制转换成函数指针,即: (void ()())0x100000 而后再调用它: ((void ()())0x100000)(); 用typedef能够看得更直观些: typedef void()() voidFuncPtr; *((voidFuncPtr)0x100000)();
四、已知一个数组table,用一个宏定义,求出数据的元素个数 #define NTBL #define NTBL (sizeof(table)/sizeof(table[0]))
五、线程与进程的区别和联系? 线程是否具备相同的堆栈? dll是否有独立的堆栈? 进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操做系统就帮你建立了一个主线程。 每一个线程有本身的堆栈。 DLL 中有没有独立的堆栈,这个问题很差回答,或者说这个问题自己是否有问题。由于DLL中的代码是被某些线程所执行,只有线程拥有堆栈,若是DLL中的代码是 EXE中的线程所调用,那么这个时候是否是说这个DLL没有本身独立的堆栈?若是DLL中的代码是由DLL本身建立的线程所执行,那么是否是说DLL有独立的堆栈?
以上讲的是堆栈,若是对于堆来讲,每一个DLL有本身的堆,因此若是是从DLL中动态分配的内存,最好是从DLL中删除,若是你从DLL中分配内存,而后在EXE中,或者另一个DLL中删除,颇有可能致使程序崩溃
6、unsigned short A = 10; printf("~A = %u\n", ~A);
char c=128; printf("c=%d\n",c);
输出多少?并分析过程 第一题,~A =0xfffffff5,int值 为-11,但输出的是uint。因此输出4294967285 第二题,c=0x10,输出的是int,最高位为1,是负数,因此它的值就是0x00的补码就是128,因此输出-128。 这两道题都是在考察二进制向int或uint转换时的最高位处理。
七、long a=0x801010; a+5=? 0x801010用二进制表示为:“1000 0000 0001 0000 0001 0000”,十进制的值为8392720,再加上5就是8392725
8、给定结构struct A { char t:4; char k:4; unsigned short i:8; unsigned long m; };问sizeof(A) = ? 给定结构struct A { char t:4; 4位 char k:4; 4位 unsigned short i:8; 8位 unsigned long m; // 偏移2字节保证4字节对齐 }; // 共8字节
9、下面的函数实如今一个数上加一个数,有什么错误?请改正。 int add_n ( int n ) { static int i = 100; i += n; return i; } 当你第二次调用时得不到正确的结果,难道你写个函数就是为了调用一次?问题就出在 static上?
十、求函数返回值,输入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的个数是很效率很高的。 没必要去一个一个地移位。循环次数最少。
十一、int a,b,c 请写函数实现C=a+b ,不能够改变数据类型,如将c改成long int,关键是如何处理溢出问题 bool add (int a, int b,int *c) { *c=a+b; return (a>0 && b>0 &&(*c<a || *c<b) || (a<0 && b<0 &&(*c>a || *c>b))); }
十二、分析: 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; 当c为有符合数时, c = 100,即 c = 4,同理 b = 3