笔试面试笔记-c语言2

1.程序的运行结果为?__30 32 64___.

main()

{

unsigned char a, b, c, d;

a = 30;

b = a++;

c = ++a;

d = 10 * (a++); // 320-256 64 溢出

printf("%d %d %d\n", b, c, d);

}

2.请问下面语句的输出是什么__100______.
void func(int a, int b)  
​
{
​
*(&a) = b;
​
}
​
int main(void)
​
{
​
int x = 0x100; 
​
func(x, 255);
​
printf(“%x\n”, x);   //值传递
​
return 0;
​
}

3.请写出下面表达式的值

1)(a = 1) ? 2 : 3 2

2)!!(0x12345678) 1

3)0x12345678 & ~0x1000

0001 0010 0011 0100 0101 0110 0111 1000 & 1111 1111 1111 1111 1110 1111 1111 1111

0x12344678

4)0x12345678 & ~0xfff

0001 0010 0011 0100 0101 0110 0111 1000 & 1111 1111 1111 1111 1111 0000 0000 0000

0x12345000

4.下述函数的作用是:消除字符串首尾空白符(仅指跳格符'\t'和空格符' '),中检出限的中间连续空白符合并为一个空格,请补充其中缺失的行。

\

#define ISWHITE(x) (_(x)=='\t'||(x)==''__)   
​
void trim(char *pStr)
​
{
​
char*pR = pStr;  //R 读指针
​
char *pW = pStr; //W 写指针
​
while(ISWHITE(*pR))                //(   abc    def   )
​
{
​
++pR;
​
}
​
for (;;)  
​
{
​
while (!ISWHITE(*pR))   //不是空白符
​
{
​
*pW++ = *pR++;
​
If(*pR == '\0') break;
​
}
​
while (ISWHITE(*pR) )                //是空白符 向后移动
​
{
​
++pR;
​
If(*pR == '\0')  break;
​
}
c
__If(*pR == '\0')  break;  else *(pW)++ = ' ';
}
​
__*(pW)='\0';______________________; 
​
}
​
​

5.下列表达式的计算结果是:

int i = 3;i>>=1;i<<=1; i=____2_____

0011 -> 0001 -> 0010

※int i = 0xf0000000;i>>=1; i=0x7f0000 0000_______

1111 0000 0000 0000 -> 0111 1111 0000 0000

※unsigned int i = 0xf0000000,i>>=1; i=0x7f0000 0000_________

※signed char c = -1;int i = (int )c; i=__-1___

※unsigned char c = -1;int i = (int)c;i=____255____

int i = (int)(3 *1.0/2 *3); i=__4_

int i=3;i=!!i; i=____1___

!i ->0

!!i -> 1

6.32位X86平台,4字节对齐,下列代码的执行结果是:__2,0,2____

struct

{

int *p;

int val1;

int val2;

} a = {&a.val1};

int *p = (int *) &a;

p[0] = (int)&a.val2;

p[2] = 2;

printf("%d,%d,%d",*a.p,a.val1,a.val2);

a指向int 的指针p 两个整型成员val1 和 val2 初始化时,p被初始化为指向val1地址

int *p = (int *) &a; -->p指向结构体a的起始地址

p[0] = (int)&a.val2;-->p[0]代表a.p -> a.val2地址赋值给a.p

p[2] = 2;-->a.val2=2 a.p = 2 a.val1 = 0

7.请阅读下面这段代码,请问这个函数的作用是_
判断大小端 如果返回1 小端存储 如果返回0 大端存储

int checkSystem()

{

union check

{

int i;

char ch;

}c;

c.i = 1;

return (c.ch == 1);

}

8.在IA32架构下,下面的union结构的sizeof大小为___________.
union PageLayout
​
{
​
struct  
​
{
​
int page_index;
​
char key[5];
​
}; 
​
char dummy[10];  
​
};
​
 

9.程序的功能为:输入一个整数,判断是不是素数,若为素数输出1,否则输出0,请为程序填空。
int main() {
    int i, x, y = 1;
    scanf("%d", &x);  // 输入一个整数
​
    for (i = 2; i <= x / 2; i++) {
        if (x % i == 0) {  // 判断 x 是否能被 i 整除
            y = 0;  // 如果能整除,x 不是素数,设置 y = 0
            break;  // 跳出循环
        }
    }
​
    printf("%d\n", y);  // 输出结果
    return 0;
}

10.下列代码的运行结果是:1___

#define equal(a,b) a == b

int a = 3,b =7;

printf("%d",equal(a&3,3&&b)); 关系>按位与>逻辑与

单算移关与,异或逻条赋

a&3 == 3&&b

a&(3 == 3)&&b

(a&1)&&b

1&&b

1

  1. 以下数据结构体在64位机器上占用的内存是多少?解释原因

    32 字节对齐 按照8个字节对齐

typedef struct _data

{

int id;

char name[6];

long long time;

char add[4];

}data;

12.阅读以下代码,说明main函数打印了什么值,并简述各子函数的含义。 18

uint32_t process(const char* pValues, uint32_t num, const uint32_t *NUMBERS) {  
    uint32_t retValue = 0;  
​
    for (uint32_t i = 0; i < num; i++) {  
        retValue += NUMBERS[pValues[i]];   
    }  
​
    return retValue;  
}  //用于求和字符对应的1个数
​
uint32_t process2(uint8_t value) {  
    uint32_t count = 0;  
​
    while (value != 0) {  
        if ((value & 1) != 0) {  
            ++count;  
        }  
        value >>= 1;  
    }  
​
    return count;  
}  //判断二进制1的个数
​
int main(char **args, int num) {  
    uint32_t NUMBERS[256];   
​
    // 初始化 NUMBERS 数组,存储每个0-255整数的二进制中1的个数  
    for (uint32_t i = 0; i <= 255; i++) {  
        NUMBERS[i] = process2(i);  
    }  
​
    const char* pValues = "aAbBcC"; // 测试的字符串  
    uint32_t processValue = process(pValues, strlen(pValues), NUMBERS);   
​
    // 输出结果  
    fprintf(stdout, "%d\n", processValue);  
​
    return 0;  
}

对于字符串 "aAbBcC",每个字符的ASCII值是:

  • 'a': 97 (二进制是 01100001,包含 3 个1)

  • 'A': 65 (二进制是 01000001,包含 2 个1)

  • 'b': 98 (二进制是 01100010,包含 4 个1)

  • 'B': 66 (二进制是 01000010,包含 2 个1)

  • 'c': 99 (二进制是 01100011,包含 4 个1)

  • 'C': 67 (二进制是 01000011,包含 3 个1)

NUMBERS[97] + NUMBERS[65] + NUMBERS[98] + NUMBERS[66] + NUMBERS[99] + NUMBERS[67] = 3 + 2 + 4 + 2 + 4 + 3 = 18

13、请看下面代码:

int arry[] = { 1, 2, 3, 4, 5, 6 };

#define elements (sizeof(arry)/sizeof(arry[0]))

int main(int argc,char *argv[])

{

int d = -1, x;

if (d<=elements-2) if (d<= (sizeof(arry)/sizeof(arry[0])) -2) sizeof 返回值 无符号的整型 需要强转

{

x = arry[d + 1];

}

printf("%d\n", x);

return 0;

}

问题:这段代码问题出在哪里?如何改进?

x乱码 if (d<=(int) (sizeof(arry)/sizeof(arry[0])) -2) 正常整型的比较 如果不强转 则左边的值会变为无符号 出现错误

14.以下代码是否存在问题,若有请给出解决方法。

#define ABS(a) ((a)>0?(a):(-a))

int sum_array(int *x, int n)

{

int sum = 0;

for (int i = 0; i < n;)

{

sum += ABS(x[i++]); //sum += ((x[i++])>0?(x[i++]):(-x[i++])); i++多次 应该改为 sum += ABS(x[i]); i++;

}

return sum;

}

15.请指出下面代码中的所有错误,并纠正(说明:以下代码是把一个字符串倒序,如:"abcd"倒序后变为"dcba")

#include"string.h" //头文件引用错误 #include<string.h>

main()

{

char *src = "hello,world";

char *dest = NULL, *d, *s;

int len = strlen(src);

dest = (char *)malloc(len); //malloc分配内存不足 字符串结尾有'\0' 应该分配为len+1

d = dest;

s = src[len]; //s = src + len - 1

while (len--!=0)

{

d++ = s--; //*(d++) = *(s--);

}

//*d = '\0';

printf("%s", dest);

//free(dest);

return 0;

}

16.下面这段代码的输出结果是(B)

char *ptr;

if((ptr = (char*)malloc(0)) == NULL)

puts("Got a null pointer");

else

puts("Got a valid pointer");

A Got a null pointer.

B Got a valid pointer .

C 程序崩溃

D 一堆乱码

malloc(0) 的行为是未定义的,但大多数现代实现会返回一个非空指针。这个指针不能被解引用(因为分配的内存大小为 0),但它是一个有效的指针。

17.如下一段神奇的代码实现的功能是(C)
int miracle(unsigned int n)
{
int m = n == 0?0:1;
​
while(n = (n&(n-1)))
{
m++;
}
return m;
}

A n的二进制表示中“0”的个数

B n的二进制表示的倒序值

C n的二进制表示中“1”的个数

D 一个均匀的哈希函数

18.在little-endian的机器上,下面的代码打印的结果是(htonl函数的功能是把数转换为big - endian存储): (B)
union
​
{
​
    int32_t i; 
​
    struct 
​
    {
​
        char c1;
​
        char c2;
​
    }st;
​
}num;
​
num.i = htonl(0xa1a2a3a4); 
​
printf("%d%d\n", num.st.c1, num.st.c2);  1010 0100   

A. - 92 - 93

B. - 95 - 94

C.161162

D.164163

  • 0xa1a2a3a4的存储顺序,按照小端格式(低位在前)为:

    • 0xa4 (最低字节)

    • 0xa3

    • 0xa2

    • 0xa1 (最高字节)

调用htonl将这个数转换为大端(big-endian)存储。转换后,存储顺序将变为:

  • 0xa1

  • 0xa2

  • 0xa3

  • 0xa4

num.st.c1 = 0x a1

num.st.c2 = 0x a2

0x a1 = 10* 16 + 1 = 161 (溢出) 161 -256 = -95

0x a2 = 10* 16 + 2= 162 (溢出) 162 -256 = -94

19.如下代码的输出结果是(A)
#include <iostream>  
#include <cstdlib> // 用于 abs 函数  
​
using namespace std;  
​
int function2(int a[], int b, int e) {  
    // 检查边界条件  
    if (e - b <= 1) {  
        return abs(a[b] - a[e]) >= 3 ? a[b] : a[e];  
    }  
​
    int l = 0, r = 0;  
    // 递归调用  
    l = function2(a, b, b + (e - b) / 2);  
​
    if (l % 2 == 0) {  
        r = function2(a, b + (e - b) / 2 + 1, e);  
    } else {  
        return l;  
    }  
​
    // 返回结果  
    if (l | r) {  
        return l | r;  
    } else {  
        return r;  
    }  
}  
​
int main() {  
    int a[] = { 10, 5, 8, 4, 5, 20, 2, 3 };  
    cout << function2(a, 0, sizeof(a) / sizeof(int)) << endl; // 修改数组大小计算  
    int b[] = { 3, 5, 8, 4, 8, 30, 2, 3 };  
    cout << function2(b, 0, sizeof(b) / sizeof(int)) << endl; // 修改数组大小计算  
​
    return 0;  
}

A.15, 5

B.10, 5

C.20, 3

D.其他

20.如下代码的输出结果是(C)
int_t main(i nt argc, _TCHAR* argv[])
​
{
​
int a[2][5] = { { 2, 3, 4, 5, 6 }, { 7, 8, 9, 10, 11 } };
​
int *ptr = (int *)(&a + 1);
​
cout << *(ptr - 3) << endl;
​
}

A.3

B.4

C.9

D.10

int *ptr = (int *)(&a + 1);

ptr指向a下一块地址,ptr-1 -> a最后一块地址 a[1][4] 
ptr-3 a倒数第三块地址 a[1][2] -> 9

21.如下代码的输出结果是(B)
#include <iostream>  
​
using namespace std;  
​
// 使用递归的方式计算两个数字的和,不使用加法运算符  
int WhoAmI(int num1, int num2) {   
    if (num2 == 0) {  
        return num1;  
    }  
​
    int num = num1 ^ num2;            // 计算无进位和  
    int carry = (num1 & num2) << 1;   // 计算进位  
    
    return WhoAmI(num, carry);        // 递归调用  
}  
​
int main() {                          
    cout << WhoAmI(5, 6) << endl;    // 输出两个数的和  
    return 0;  
}

A.1

B.11

C.-1

D.30

22.Consider a program P that consists of two source modules M1 and M2 contained in two

different files.If M1 contains a reference to a function defined in M2, the reference

will be resolved at : __. C

在程序 P 中,如果模块 M1 中包含对模块 M2 中定义的函数的引用,这个引用将在 C. Link time(链接时)被解析。

A.Edit time

B.Compile tcime

C.Link time

D.Load time

23.在一个32位PC机器上,下面代码的运行结果是B____.
#include <stdio.h>  
​
int main() {  
    short a = 0xffff;     // a 是有符号 short,值为 -1
    int b, c;  
    unsigned short d =  0xffff; // d 是无符号 short,值为 65535
    unsigned int e, f;  
​
    b = a;  // 将 a(有符号 short)赋值给 b(有符号 int)
    c = 0xffff; // 将 0xffff(无符号 int)赋值给 c(有符号 int)
    e = a;  // 将 a(有符号 short)赋值给 e(无符号 int)
    f = d;  // 将 d(无符号 short)赋值给 f(无符号 int) 
    printf("%d %d 0x%x 0x%x", b, c, e, f);  
    
    return 0;  
}

A.65535 65535 0xffffffff 0xffff

B.-1 65535 0xffffffff 0xffff

C.65535 65535 0xffff 0xffff

D.-1 65535 0xffff 0xffff

//short 有符号范围为 -32768-32767

unsigned short 无符号范围为0-65535

int 有符号 范围为-21474836482147483647

unsigned int 无符号 范围为04294967295

24.设unsigned int x, y;则下列语句x = x + y; y = x - y, x = x - y; 实现了____A___.

A.不使用中间变量正确实现了x与y的互换

B.不使用中间变量实现了x与y的互换,但当x + y溢出时有错误

C.x与y并未互换

D.最后x与y相等

25.现有如下代码

int array[] = { 23, 34, 12, 17, 204, 99, 16 };

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))

void main()

{

int d = -1, x;

if (d <= TOTAL_ELEMENTS - 2)

x = array[d + 1];

}

那么x的结果是(A)

A.23 B.28 C.7 D.不确定

26.字符串www.qq.com所有非空子字符串(两个子串如果内容完全相同则只算一个)个数是_. D

A. 1024 B. 1018 C. 55 D. 50

www.qq.com
对于长度为 n 的字符串,非空子字符串的总数为 n*(n+1)/2。
对于 www.qq.com,长度为 10,总子字符串数为 10*11/2 = 55。
​
去除重复的子字符串
w:2(单字符) + 1(双字符) = 3。
q:1(单字符)。
.:1(单字符)。
总计重复:3 + 1 + 1 = 5。
去重后的子字符串总数:55 - 5 = 50。

27.请实现32位大小端转换宏: 字节序的颠倒 字节里的内容交换
#define swap32(x) \
    (((x)&0xff 00 00 00)>>24) |\
    (((x)&0x00 ff 00 00)>>8)  |\
    (((x)&0x00 00 ff 00)<<8)  |\
    (((x)&0x00 00 00 ff)<<24) 
​

\28. int a[] = { 2, 8, 16, 24 };

char *p1 = a;

char *p2 = &a[3];

那么 p2-p1=__12__.

计算p2 p1 的地址差 相距 3个sizeof(int) 3*4

29.以下代码的执行结果是()

int main()

{

int i = -2147483648;

return printf("%d,%d,%d,%d\n", ~i, -i, 1 - i, -1 - i);

}

int -2147483648~ 2147483647

~i 按位取反 1000 0000 0000 0000 -> 0111 1111 1111 1111

-i 取反 2147483648 -> 溢出 2147483648 - 4294967296 = -2147483648

1-i 2147483649 -> 溢出 2147483649- 4294967296 = -2147483647

-1-i 2147483647

30 .下列程序的运行结果是__.

int main()
​
{
​
int a[5][2] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
​
int* p = a;             //0
​
int(*p2)[2] = &a[1];    //a[1]   {2,3}
​
++p;    
​
++p2;                   //a[2]  {4,5}
​
printf("%d\n", *p);      //1    
​
printf("%d\n", **p2);    //4  
​
printf("%d\n", p2[1][2]);//8
​
return 0;
​
} 

31.32位X86平台,4字节对齐,下列代码的结果是__12 4_0 0___.

#include <stdio.h>  
​
union uni {  
    struct {  
        char* p1;  
        int n2;  
        char c;  
    } s1;  
    
    struct {  
        int n3;  
        char* p4;  
    } s2;  
};  
​
int main() {  
    union uni u;  
​
    printf("%d %d %d %d \n",   
           sizeof(u),   
           sizeof(&u),   
           (int*)&u.s2.p4 - (int*)&u.s1.p1,   
           (char*)&u.s2.n3 - (char*)&u.s1.p1);  
    
    return 0;  
}
s1 结构体的对齐:
char* p1 4 字节
int n2 4 字节
char c 1 字节
s1大小为12
s2 结构体的对齐也类似:
int n3 4 字节
char* p4 4 字节
s2大小为8
联合体大小为12  sizeof(u) = 12
 sizeof(&u) 联合体指针大小为4
 联合体共享内存    (int*)&u.s2.p4 - (int*)&u.s1.p1 = 0
                (char*)&u.s2.n3 - (char*)&u.s1.p1) = 0

32.用变量p给出下面的定义

一个指向整型数的指针

int *p;

一个指向指针的指针,它指向的指针式指向一个整型数

int n = 1;

int * a = &n;

int **p = &a;

一个有10个指针的数组,该指针式指向一个整型数的

int *arr[10];

一个指向有10个整型数数组的指针

int arr[10];

int *p = arr;

一个指向函数的指针,该函数有一个整型参数并返回一个整型数

int myfun(int x)

{

return x*2;

}

int (*fun)(int) = myfun;

一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数

int myfun(int x)

{

return x*2;

}

int (*fun[10])(int);

for(int i = 0;i<10;i++)

{

fun[i] = myfun;

}

\33. 在32位x86CPU环境下,下列三行语句结束后,result值为_. 10

unsigned char port = 0x5a;

unsigned char result;

result = (~port) >> 4;

0x5a ->二进制 0101 1010

~port -> 10100101

(~port) >> 4 -> 0000 1010-> 10

34.下面程序,求count的值__1___.

#include <stdio.h>  
​
int func() {  
    int count = 0;             // 初始化 count 为 0  
    unsigned int a = 1;       // a 的值为 1  
    int b = -5;               // b 初始化为 -5  
​
    while (b++ <= 5) {        // 当 b 小于等于 5 时循环  
        if (a + b > 5) {      // 如果 a + b 大于 5  
            count++;          // 计数器加 1  
        }  
    }  
​
    return count;             // 返回 count  
}  
​
int main() {  
    int result = func();      // 调用 func 函数  
    printf("Count: %d\n", result); // 打印 count 的值  
    return 0;  
}

count = __1__ ?

\35. 请描述下面代码的运行结果______,并说明原因

#include <stdio.h>  
​
int main() {  
    int i = 0;  
    int name[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };  
​
    for (i = 0; i <= 10; i++) {  
        name[i] = 0;  
        printf("ok\n");  
    }  
​
    return 0;  
}

ok ok ok ok ok ok ok ok ok ok ok

36 .下面的数据声明代表什么?

float(**def)[10];   
指向有10个float*元素的数组的指针
 
​
double*(*gh)[10];   
指向有10个double*元素的数组的指针
 
​
double(*f[10])();
包含10个返回double的函数指针的数组
 
​
int*((*b)[10]); 
指向有10个int*元素的数组的指针
​
long(*fun)(int);
指向一个接收int并返回long型的函数指针
 
int(*(*f)(int, int))(int);  
指向一个接收两个int参数,并返回一个接收int并返回int的函数的指针的函数的指针
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值