姓名:朱军伟 学号:19170100001 学院:电子工程学院 班级:1902015
原文转自:https://download.csdn.net/download/sun_jfly/4326176?utm_medium=distribute.pc_relevant_t0.none-task-download-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-download-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
【嵌牛导读】任何行业的终极目标都是为了谋求发展,嵌入式作为一个前沿行业,我们有必要熟悉一下常见的面试题,我将此作为一个系列发布。
【嵌牛鼻子】嵌入式行业面试题
【嵌牛提问】如何轻松应对嵌入式行业面试?
【嵌牛正文】
分析下面的程序:
void GetMemory(char **p,int num)
{
*p=(char *)malloc(num);
}
int main()
{
char *str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
free(str);
if(str!=NULL)
{
strcpy(str,"world");
}
printf("\n str is %s",str);
getchar();
}
问输出结果是什么?希望大家能说说原因,先谢谢了
输出 str is world。
free 只是释放的 str 指向的内存空间,它本身的值还是存在的.
所以 free 之后,有一个好的习惯就是将 str=NULL.
此时 str 指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储
空间是可能被重新分配给其他变量的,
尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚了),但是通常会打印出
world 来。
这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。
当你 malloc 一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),
然后在这块空间中记录一些管理信息(一般是在你申请的内存前面一点),并将可用内存的
地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继
续访问这块地址的,只不过。。。。。。。。楼上都说过了,最好别这么干。
char a[10],strlen(a)为什么等于 15?运行的结果
#include "stdio.h"
#include "string.h"
void main(){
char aa[10];
printf("%d",strlen(aa));
}
sizeof()和初不初始化,没有关系;
strlen()和初始化有关。
char (*str)[20];/*str 是一个数组指针,即指向数组的指针.*/
char *str[20];/*str 是一个指针数组,其元素为指针型数据.*/
long a=0x801010;
a+5=?
0x801010 用二进制表示为:“1000 0000 0001 0000 0001 0000”,十进制的值为 8392720,再
加上 5 就是 8392725 罗
1)给定结构 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 字节
2)下面的函数实现在一个数上加一个数,有什么错误?请改正。
int add_n ( int n )
{
static int i = 100;
i += n;
return i;
}
当你第二次调用时得不到正确的结果,难道你写个函数就是为了调用一次?问题就出在
static 上?
// 帮忙分析一下#include
#include
#include
#include
#include
#include
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 < cout << aa.b2 < } 答案是 -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 的个数是很效率很高的。 不必去一个一个地移位。循环次数最少。 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 &&(*ca || *c>b))); } 分析: struct bit { int a:3; int b:2; int c:3; }; int main() { bit s; char *c=(char*)&s; cout< *c=0x99; cout << s.a < 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 位域 : 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如 在存放一个开关量时,只有 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 }; 从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。 二、位域的使用位域的使用和结构成员的使用相同,其一般形式为: 位域变量名• 位域名 位域允许用各种格式输出。 main(){ struct bs { unsigned a:1; unsigned b:3; unsigned c:4; } bit,*pbit; bit.a=1; bit.b=7; bit.c=15; pri 改错: #include int main(void) { int **p; int arr[100]; p = &arr; return 0; } 解答: 搞错了,是指针类型不同, int **p; //二级指针 &arr; //得到的是指向第一维为 100 的数组的指针 #include int main(void) {int **p, *q; int arr[100]; q = arr; p = &q; return 0; } 下面这个程序执行后会有什么错误或者效果: #define MAX 255 int main() { unsigned char A[MAX],i;//i 被定义为 unsigned char for (i=0;i<=MAX;i++) A[i]=i; } 解答:死循环加数组越界访问(C/C++不进行数组越界检查) MAX=255 数组 A 的下标范围为:0..MAX-1,这是其一.. 其二.当 i 循环到 255 时,循环内执行: A[255]=255; 这句本身没有问题..但是返回 for (i=0;i<=MAX;i++)语句时, 由于 unsigned char 的取值范围在(0..255),i++以后 i 又为 0 了..无限循环下去. struct name1{ char str; short x; int num; } struct name2{ char str; int num; short x; } sizeof(struct name1)=8,sizeof(struct name2)=12 在第二个结构中,为保证 num 按四个字节对齐,char 后必须留出 3 字节的空间;同时为保 证整个结构的自然对齐(这里是 4 字节对齐),在 x 后还要补齐 2 个字节,这样就是 12 字节。 intel: A.c 和 B.c 两个 c 文件中使用了两个相同名字的 static 变量,编译的时候会不会有问题?这两个 static 变量会保存到哪里(栈还是堆或者其他的)? static 的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。他们都放在数据区,但是编译器对他们的命名是不同的。 如果要使变量在其他模块也有意义的话,需要使用 extern 关键字。 struct s1 { int i: 8; int j: 4; int a: 3; double b; }; struct s2 { int i: 8; int j: 4; double b; int a:3; }; printf("sizeof(s1)= %d\n", sizeof(s1)); printf("sizeof(s2)= %d\n", sizeof(s2)); result: 16, 24 第一个 struct s1 { int i: 8; int j: 4; int a: 3; double b; }; 理论上是这样的,首先是 i 在相对 0 的位置,占 8 位一个字节,然后,j 就在相对一个字节 的位置,由于一个位置的字节数是 4 位的倍数,因此不用对齐,就放在那里了,然后是 a, 要在 3 位的倍数关系的位置上,因此要移一位,在 15 位的位置上放下,目前总共是 18 位, 折算过来是 2 字节 2 位的样子,由于 double 是 8 字节的,因此要在相对 0 要是 8 个字节的 位置上放下,因此从 18 位开始到 8 个字节之间的位置被忽略,直接放在 8 字节的位置了, 因此,总共是 16 字节。 第二个最后会对照是不是结构体内最大数据的倍数,不是的话,会补成是最大数据的倍数 上面是基本问题,接下来是编程问题: 本人很弱,这几个题也搞不定,特来求救: 1)读文件 file1.txt 的内容(例如): 1234 56 输出到 file2.txt: 56 34 12 (逆序) 2)输出和为一个给定整数的所有组合 例如 n=5 5=1+4;5=2+3(相加的数不能重复) 则输出 1,4;2,3。 望高手赐教!! 第一题,注意可增长数组的应用. #include #include int main(void) { int MAX = 10; int *a = (int *)malloc(MAX * sizeof(int)); int *b; FILE *fp1; FILE *fp2; fp1 = fopen("a.txt","r"); if(fp1 == NULL) {printf("error1"); exit(-1); } fp2 = fopen("b.txt","w"); if(fp2 == NULL) {printf("error2"); exit(-1); } int i = 0; int j = 0; while(fscanf(fp1,"%d",&a[i]) != EOF) {i++; j++; if(i >= MAX) { MAX = 2 * MAX; b = (int*)realloc(a,MAX * sizeof(int)); if(b == NULL) { printf("error3"); exit(-1); } a = b; } } for(;--j >= 0;) fprintf(fp2,"%d\n",a[j]); fclose(fp1); fclose(fp2); return 0; } 第二题. #include int main(void) { unsigned long int i,j,k; printf("please input the number\n"); scanf("%d",&i); if( i % 2 == 0) j = i / 2; else j = i / 2 + 1; printf("The result is \n"); for(k = 0; k < j; k++) printf("%d = %d + %d\n",i,k,i - k); return 0; }#include void main() { unsigned long int a,i=1; scanf("%d",&a); if(a%2==0) {