C和指针考试——整理

来源:互联网 发布:tensorflow 人脸检测 编辑:程序博客网 时间:2024/05/20 06:27

1.函数定义中,有语法错误的是:

void fun(int x, int*y) {    *x *= *y;}

在函数的形参列表当中,声明了一个整型指针y和一个整型变量x,在函数体中,出现了对整型变量x使用*(解引用)的操作,非法。

2.给出以下定义,下列哪些操作是合法的?

const char *p1 = “hello”;char const p2 = “world”;

A:p1++;
B:p1[2] = ‘w’;
C:p2[2] = ‘l’;
D:p2++;

定义了字符指针p1和p2,并且有const修饰,则*p1不能做左值,p2不能做左值,排除了B([ ]自带解引用) 、D。定义的两个指针变量都是指向了字符串常量,因此不能去修改这个字符串常量,排除C。

3.sizeof(struct s1)是多少?

struct s1{  char ch,*ptr;  union  {     short a,b;     unsigned int c:2,d:1;  };  struct s1*next;};    

char ch -> 1+3 字节, char *ptr -> 4 字节, union -> 4 字节(单个最大数据类型——int),struct s1 *next -> 4 字节 ,一共16字节 。在此处需要注意的是:union是联合体(共用体),所占的内存为其中最大单个类型所占的字节大小. int c:2 和 int d:1 中的2和1是位段、位域,指的是 int数据a占2位,b占1位.

4.看下面的程序,求count的值是多少?

int fun(int x){    int count = 0;    x = 9999;    while(x)    {        count++;        x = x&(x-1);    }    return count;}

首先,需要明确语句“x = x&(x-1)”的作用是计算int型数据 x 的二进制形式中 1 的个数,返回的是 count 是1的个数。先将9999换算成二进制形式,经计算得出结果为 8.

5.使用malloc系统调用分配的内存是在哪里分配?

见博文“函数、全局变量、局部变量和动态内存的特点归纳”,动态内存调用的内存是在堆里。

6.以下代码打印的结果是什么?

struct st_t{    int status;    short *pdata;    char errstr[32]; };int main(){    struct st_t st[16];    char *p = (char *)( st[2].errstr + 32 );    printf("%d\n",( p - (char *)(st) ) );    return 0;}

首先,定义了结构体st_t,大小为40字节。随后,定义了一个结构体数组 st[16],还有一个字符型指针 p,要求输出 “p - (char *)(st))”的值。重点在于确定 p 指向的是哪里,见下图。

7.设有定义:char *p,以下选项中,不能正确将字符串赋值给字符型指针p的语句是?

A:p = getchar()
B : scanf(“%s”, p)
C : int str[] = “hello”; p = str
D : *p = “china”;

ABD,C正确。getchar()是接收单个字符。scanf接收的是一串字符串,但是p是一个野指针,这么做就是非法访问,试图修改p随机指向的内存的值,非法。*p = “china”只是将该字符串常量的首地址赋给了p。

8.用十进制计算30!(30的阶乘),将结果转换成3进制进行表示的话,改进之下的结果末尾会有多少个零?

计算1~30之中一共有多少个3: 3 6 9 9 12 15 18 18 21 24 27 27 27 30,一共有14个3,则30!用3进制表示的话末尾会有14个0.

9.设x、y、z均为int型变量,执行语句:t=3; x=y=2; t=x++||++y; ,变量t和y的值为多少?

一定要注意各运算符之间的优先级关系!赋值运算符“=”的优先级低于“||”,最后t的值为“x++||++y”,即1.

10.见以下语句:

#define INT_PTR int*typedef int * int_ptr;INT_PTR a,b;int_ptr c,d;

以上哪个变量不是指针变量?

定义的宏就是字符替换,所以 “INT_PTR a,b;”字符替换之后就是“int a,b;”,其中修饰的是变量a,所以b只是一个int变量,而不是int*型变量,int_ptr在这里则是一种类型——int *,所以语句“int_ptr c,d;”定义了两个指针变量。

11.假设在n进制下,下面的等式成立,567*456=150216,n的值是多少?
A:7
B:10
C:15
D:18

对于这样的问题,首先可以从最后一个数入手,在n进制下,最后一位满n进一 ,所以最后一位就是 num1*num2 % n 的值。
在本题中,7*6等于42, 42%n等于6, 则可能的值有18。

12.如下代码:

int main{   unsigned int a = 0xfffffff7;   unsigned char ch = (unsigned char)a;   char *p = (char *)&a;   printf("%08x, %08x",ch,p);}

ch是无符号字符型数据,大小只有1字节,p是字符型指针变量,指向了char*强转后的a的地址。重点是,printf中各种数据的输出,是按照其中的格式化输出的,本题中的格式是“%08x”——输出八个(4字节)的十六进制数据,左位补零。其中,ch只有一字节的数据长度,所以就在前面补了6个零——0x0000 00f7。另外,指针p同样是按照格式化输出的样式来输出数据,需要从指针指向的位置向后读取4个字节的数据——0xffff fff7。

13.以下程序:

int Fun(int x, int y){   return (x&y) + ((x^y)>>1);}

Fun(729,271)的结果是多少?

这是程序在求x,y两个数的平均值,能看出来吗?
(x&y)是在求x、y两个数据相同的部分,((x^y)>>1)中的(x^y)的是x、y两个数不相同的所有部分,>>1就是除以2,即求得不同部分的平均值。那么,相同部分加上不同部分的平均值不就是在求两个数的平均值吗?FUN(729,271)的结果是500。

14.见以下程序:

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

问程序的结果是?

C函数中的参数都是以“传值调用”的方式进行传递的,即函数将获得参数的一份拷贝,函数可以对这份拷贝进行任何操作,而不用担心会影响调用程序实际传递给它的参数。当参数是一个指针时,也称为“传址调用”,但与“传值调用”并不冲突,只不过指针的这份拷贝可以通过解引用去实际传递过来的参数。所以,子函数(被调用函数)的改变要想影响到父函数(调用函数),就得传指针、解引用。
在本题中,GetMemory(str,100) 中传入的是指针,但是函数中并没有解引用,造成str并没有得到GetMemory(str,100)中开辟的空间的结果,str还是一个空指针,导致字符拷贝函数strcpy()的崩溃。
应作出如下改动:

void GetMemory(char **p, int num)//传指针的地址{   *p = (char *)malloc(sizeof(char)*num);//解引用}int main(){   char *str = NULL;   GetMemory(&str,100);  // assert(str!=NULL);   strcpy(str,"hello");   printf(str);}

作如下图解:
这里写图片描述

15.f(1)的返回值是多少?

int f(int n){   static int i=1;   if(n >= 5)   {      return n;   }   n = n+i;   i++;   return f(n);}

静态变量只初始化一次!所以不要认为在递归的过程中,每一次都对静态变量 i 进行初始化,只有最开始的一次。后面的问题就迎刃而解了。

16.能实现“判断一个非零整数x是否是2的幂”的功能的表达式是?

同样是“x&(x-1)”,计算x二进制形式当中 1 的个数,只有当 1 的个数为1个的时候,x才是2的幂,其他情况都不是。

17.假设进栈次序是e1, e2, e3, e4,那可能的出栈次序可能是?
A:e2, e4, e3, e1
B:e2, e3, e4, e1
C : e3, e2, e4, e1
D : e1, e2, e4, e3

以上四种情况都可以。以下为图解
A:这里写图片描述

B:这里写图片描述

C、D同理同时,也有很多情况不能实现,例如:e2, e4, e1, e3。见下图:

这里写图片描述

18.表达式“X = A+B*(C-D)/E”的后缀表达形式可以是?

答案是:XABCD-*E/+=
这是数据结构中的内容,平时我们用的是中缀表达式,如题中所给的表达式,除了后缀表达式(又称“波兰式”),还有前缀表达式(又称“逆波兰式”)。
以本题为例,介绍一下计算的过程:

  1. 先嵌套“( )”,消除运算符优先级大小的影响。
    X = ( A+( ( B* (C-D ) )/E ) )
  2. 把运算符从内往外地,往后移动,把括号去掉。XABCD-*E/+=

    在后缀表达式中,不存在运算符之间的优先级问题。那么,怎么“看”后缀表达式呢?

对于变量,从右往左开始运算,右端的运算符是从左往右一一执行的。C、D先 -,得到的值再与 B *,得到的值再 / E,得到的值再 + A,最后的值 = 给X。

原创粉丝点击