PTA | C-位运算相关题目

1-1

C语言提供的预处理功能包括条件编译,其基本形式为:

#XXX 标记符
        程序段1
#else
        程序段2
#endif

这里XXX可以是

A. define或include

B. ifdef或include

C. ifdef或ifndef或define

D. ifdef或ifndef或if

GPT

C语言中的条件编译主要由预处理指令控制。你给出的格式是条件编译的基本结构,它通常包含以下几种预处理指令:

  1. #if: 检查一个条件是否为真。
  2. #ifdef: 如果定义了指定的宏,则编译后续代码。
  3. #ifndef: 如果没有定义指定的宏,则编译后续代码。
  4. #else: #if, #ifdef, #ifndef的条件不满足时,编译#else后的代码。
  5. #endif: 结束一个条件编译块。

根据这些信息,针对你提出的选择题,正确答案是:

D. ifdef或ifndef或if

这是因为#define#include是预处理指令,但它们不用于条件编译。#define用于定义宏,而#include用于包含头文件。

1-2

若程序中有宏定义行: #define N 100 则以下叙述中正确的是

A. 宏定义行中定义了标识符N的值为整数100

B. 在编译程序对C源程序进行预处理时用100替换标识符N

C. 上述宏定义行实现将100赋给标示符N

D. 在运行时用100替换标识符N

GPT

在C语言中,宏定义是预处理指令的一部分,使用#define来定义。针对给出的宏定义:

#define N 100

这里定义了一个宏N,其值被设置为100。下面是对选项的解析:

A. 宏定义行中定义了标识符N的值为整数100 - 这个表述不完全准确。在宏定义中,并没有给N赋值,而是在预处理阶段会将N替换为100。

B. 在编译程序对C源程序进行预处理时用100替换标识符N - 这个描述是正确的。预处理器会在编译之前将程序中所有出现的N替换为100。

C. 上述宏定义行实现将100赋给标示符N - 这个描述不准确。宏定义并不是赋值操作,而是文本替换。

D. 在运行时用100替换标识符N - 这个描述不正确。宏替换发生在预处理阶段,而不是运行时。

因此,正确答案是:

B. 在编译程序对C源程序进行预处理时用100替换标识符N

1-3

#define fun(x,y) (x)* (y)

fun(3+2,4+5)的值为( )。

A. 16

B. 25

C. 45

D. 无正确答案

1-4

下列叙述错误的是()。

A. C语言源程序中加入一些预处理命令是为了改进程序设计环境,提高编程效率

B. 宏定义可出现在源程序中任意合适的位置,且必须在行末加分号

C. #define PER 1.5的作用是用标识符PER代表1.5

D. 预处理命令行都必须以#号开始

1-5

下列错误的是()。

A. 预处理命令行都必须以#号开始。

B. C语言程序中加入一些预处理命令是为了改进程序设计环境,提高编程效率

C. 宏定义可出现在源程序中任意合适的位置,且必须在行末加分号

D. #define PER 1.5的作用是用标识符PER代表1.5

1-6

宏定义#define DIV(a, b) a/b,经DIV(x + 5, y - 5) 引用,替换展开后是:

A. (x + 5 / y – 5)

B. (x + 5) / (y - 5)

C. x + 5 / y - 5

D. (x + 5) / (y - 5);

1-7

设有宏定义:#define IsDIV(k, n) ((k%n==1)? 1: 0)且变量m已正确定义并赋值,则宏调用:IsDIV(m, 5)&& IsDIV(m, 7) 为真时所要表达的是

A. 判断m是否能被5和7整除

B. 判断m被5或者7整除是否余1

C. 判断m被5和7整除是否都余1

D. 判断m是否能被5或者7整除

1-8

关于二进制算术运算,下列说法不正确的是________。

A. 二进制算术运算可以用逻辑运算来实现;

B. 二进制算术运算的符号位可以和数值位一样参与运算并能得到正确的结果;

C. 二进制算术运算的符号位不能和数值位一样参与运算但能得到正确的结果;

D. 前述说法有不正确的。

GPT

在二进制算术运算中,关于符号位的处理是一个关键的方面,尤其是在有符号的数值运算中。让我们逐一分析这些选项:

A. 二进制算术运算可以用逻辑运算来实现 - 这个说法是正确的。实际上,在计算机硬件中,算术运算(如加法、减法)可以通过一系列的逻辑运算(如与、或、非、异或等)来实现。

B. 二进制算术运算的符号位可以和数值位一样参与运算并能得到正确的结果 - 这个说法在某些情况下是正确的。例如,在二进制补码表示法中,进行加法运算时,符号位确实可以像数值位一样参与运算,并且通常可以得到正确的结果。但这并不适用于所有情况,特别是在其他类型的运算中(如乘法和除法),符号位的处理更为复杂。

C. 二进制算术运算的符号位不能和数值位一样参与运算但能得到正确的结果 - 这个说法不完全正确。如前所述,对于某些运算(特别是补码加法),符号位可以和数值位一样参参与运算。

D. 前述说法有不正确的 - 鉴于B和C项的表述在某些情况下可能不准确或有歧义,可以认为这个说法是正确的。

因此,选项D是不正确的说法,因为它本身指出了其他说法中存在不准确之处。但如果考虑到B和C项的潜在歧义,这个问题的答案可能需要更具体的上下文来确定。在不同的二进制算术运算和表示法中,符号位的处理方式可以有很大差异。

GPT-Again

在C语言的上下文中,考虑二进制算术运算和符号位的处理,我们可以重新审视每个选项:

A. 二进制算术运算可以用逻辑运算来实现 - 在C语言中,这是正确的。实际上,低级的算术运算可以通过逻辑运算符(如位与、位或、位非、位异或等)实现。

B. 二进制算术运算的符号位可以和数值位一样参与运算并能得到正确的结果 - 在C语言中,对于加法和减法,尤其是使用补码表示法时,这通常是正确的。补码表示法使得符号位可以与其他位一起参与运算,并通常得到正确的结果。

C. 二进制算术运算的符号位不能和数值位一样参与运算但能得到正确的结果 - 这个说法在C语言的上下文中是不正确的。因为在补码表示法中,符号位确实参与运算,并且通常可以得到正确的结果。

D. 前述说法有不正确的 - 鉴于选项C的表述是不准确的,这个选项实际上是正确的。

因此,在C语言的上下文中,不正确的说法是选项C:二进制算术运算的符号位不能和数值位一样参与运算但能得到正确的结果。在C语言中,特别是使用补码表示法时,符号位确实参与运算,并且可以得到正确的结果。

1-9

位运算符只能用于( )。

A. 整数

B. 浮点数

C. 字符串

D. 字节串

1-10

下面哪个运算符不是位操作符( )。

A. <<

B. and

C. &

D. |

2-1 绝对值函数(宏)*

C 函数库中提供整数绝对值 abs 函数和实数绝对值 fabs 函数,函数声明如下:

函数原型

int abs(int x);
double fabs(double x);

说明:函数值为参数 \(x\) 的绝对值 \(∣x∣\)

请在空白处填写适当内容,用带参数的宏替换命令来实现相同的功能,将上面两个函数合并为一个,并命名为 Abs

裁判程序1

#include <stdio.h>

__________

int main()
{
    int a, b;
    double x, y;
    scanf("%d %lg", &a, &x);
    b = Abs(a);
    y = Abs(x);
    printf("%d %g\n", b, y);
    return 0;
}

输入样例1

-5 -2.5

输出样例1

5 2.5

输入样例2

7 3.8

输出样例2

7 3.8

输入样例3

0 0

输出样例3

0 0

输入样例4

-0 -0

输出样例4

0 0

注:裁判程序有很多,不止一个。

特别提示:注意实数为 -0.00.0 的情况。

Code

#define Abs(x) ((x>0)?(x):((x<0)?(-(x)):0))

2-2 圆的面积(宏)

已知圆面积的函数原型如下:

函数原型

double CircleArea(double radius);

说明:参数 radius 圆的半径,函数值为圆的面积。

请在空白处填写适当内容,用带参数的宏替换命令来实现相同的功能。

裁判程序

#include <stdio.h>

#define pi 3.1415926535897932384626

__________

int main()
{
    double a, b;
    scanf("%lg", &a);
    b = CircleArea(a);
    printf("%g\n", b);
    return 0;
}

注:裁判程序有很多,不止一个。

输入样例

0.6

输出样例

1.13097

Code

#define CircleArea(x) ((x)*(x)*(pi))

2-3 整数与二进制串的互转换(位运算)

分数 10 作者 Happyer 单位 湖北文理学院

计算机中所有的数据都是以二进制形式存储的,整数也不例外。输入一个长度在[1-32]内的由0,1组成的字符串,要求编程其转换为整数。反之,也要写一个函数,完成将给定整数转换成0和1组成的字符串的功能。以上两个函数的实现均要求用位运算的方法,为确保你使用位运算的方法实施,系统提供了三个必须调用的函数,设置整数的某个位为0:setXi0(x,i),设置整数的某个位为1:setXi1(x,i),检测整数某个位是什么(0?|1?):getXi(x,i)。

函数接口定义:

char* int2Bin(int x);//3-->"0000000..0011"
int Bin2int(char *pch);//"0...00101"->5

注意:字符串传入和返回时都是传的地址。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
int num0=0,num1=0,num2=0;
void setXi0(int *x,int i)//set:  x[i]=0
{ *x&=~(1<<i);num0++;}
void setXi1(int *x,int i)//set: x[i]=1
{    *x|=1<<i;num1++;}
int getXi(int x,int i)//  return:  x[i]== 0|1?
{ num2++;return (x&(1<<i))!=0;}
char* int2Bin(int x);//3-->0000000..0011.
int Bin2int(char *pch);//0...00101->5
int main(int argc, char *argv[]){
    char st[33];int x;gets(st);
    x=Bin2int(st);
    printf("%d\n",x);
    x=-111;char *p=int2Bin(x);
    puts(p);
    printf("%d",Bin2int(p));
    return 0;
}

/* 请在这里填写答案 */

输入样例:

一组长度不超过32的由0和1构成的字符串,字符串长度大于零。

001100101100

输出样例:

三行输出分别为:字符串转成的整数。一个整数转成的二进制字符串(整数的机内存储形式)。有关调用位操作的统计信息。 (练习者只需要完成两个函数,不用进行输出及格式控制)。

812
00000000000000000000010011000010
0,9,32,1218

Code

char *int2Bin(int x)
{
    char *p = (char *)malloc(sizeof(char) * 33);
    for (int i = 0; i < 32; i++)
        p[i] = '0';
    p[32] = '\0';
    for (int i = 0; i < 32; i++)
        if (x & (1 << (31 - i)))
            p[i] = '1';
    for (int i = 0; i < 32; i++)
        if (p[i] == '1')
            num1++;
    // printf("num1=%d\n", num1);
    num2 = 32;
    return p;
}
#include <string.h>
int Bin2int(char *pch)
{
    int len = strlen(pch);
    int res = 0, digit = 1;
    for (int i = len - 1; i >= 0; i--)
    {
        if (pch[i] - '0')
        {
            res += digit;
            if (num2 != 32)
                num1++;
        }
        digit *= 2;
    }
    // printf("num1=%d\n", num1);
    return res;
}

3-1 任务10-01-02 合法C标识符

任务描述

给定一个不包含空白符的字符串,请判断是否是C语言合法的标识符号(注:题目保证这些字符串一定不是C语言的保留字)。

C语言标识符要求:

  1. 非保留字;
  2. 只包含字母、数字及下划线(“_”)。
  3. 不以数字开头。

输入格式:

一行,包含一个字符串,字符串中不包含任何空白字符,且长度不大于20。 ## 输出格式: 一行,如果它是C语言的合法标识符,则输出yes,否则输出no。 ## 输入样例:

RKPEGX9R;TWyYcp
## 输出样例:
no
## 题目来源 该题目选自OpenJudge网站,在线网址:http://noi.openjudge.cn/ch0107/06/

Code

#include <stdio.h>
#include <string.h>
int main(){
    // 类型说明保留字:int,long,short,float,double,char,unsigned,signed,const,void,volatile,enum,struct,union
    // 语句定义保留字:if,else,goto,switch,case,do,while,for,continue,break,return,default,typedef
    // 存储类说明保留字:auto,register,extern,static
    // 长度运算符保留字:sizeof
    char remain[][20]={"int","long","short","float","double","char","unsigned","signed","const","void","volatile","enum","struct","union","if","else","goto","switch","case","do","while","for","continue","break","return","default","typedef","auto","register","extern","static","sizeof"};
    // printf("%d\n",sizeof(remain));
    char in[30];
    scanf("%29s",in);
    // printf("%lu\n",strlen(in));
    int i=0;
    if(in[i]>='0' && in[i]<='9'){
        i=strlen(in)+1;
    }
    for(;i<strlen(in);i++){
        if((in[i]>='0' && in[i]<='9') || (in[i]>='a' && in[i]<='z') || (in[i]>='A' && in[i]<='Z') || in[i]=='_'){
            continue;
        }else{  
            break;
        }
    }
    for(int j=0;j<sizeof(remain)/20;j++){
        if(strcmp(remain[j],in)==0){
            i=strlen(in)+1;
            break;
        }
    }
    if(i!=strlen(in)){
        printf("no\n");
    }else{
        printf("yes\n");
    }
    return 0;
}

3-2 编写带参数的宏ISDIGIT,判断一个字符是否是数字字符。

这是一个编程题模板。

编写带参数的宏,判断一个字符是否是数字字符(注意不要定义成函数)。例如当字符为‘A’是,宏的值为 0,表示不是数字字符,当字符为‘1’时,宏的值为1,是数字字符。

输入格式:

请在这里写输入格式。例如:输入在一行中给出一个字符c。

输出格式:

请在这里描述输出格式。例如:当字符为数字时,输出“ c 是数字字符”,当字符不是数字时,输出“c 不是数字字符”。

输入样例:

在这里给出一组输入。例如:

9

输出样例:

在这里给出相应的输出。例如:

9 是数字字符

Code

#define ISDIGIT(x) ((x>='0'&&x<='9')?1:0)
#include<stdio.h>
int main(){
    char c;
    scanf("%c",&c);
    if(ISDIGIT(c)){
        printf("%c 是数字字符",c);
    }else{
        printf("%c 不是数字字符",c);
    }
    return 0;
}

3-3 C或Java中的二进制位运算

本题目要求读入2个整数和一个字符,然后根据这个字符值,对两个整数进行相应的二进制位的运算。要求必须使用switch选择结构。

  • 如果字符是&,则两个整数进行二进制位的与运算;
  • 如果字符是|,则两个整数进行二进制位的或运算;
  • 如果字符是^,则两个整数进行二进制位异或运算;
  • 如果是其他字符,则固定输出信息:ERROR

输入格式:

在一行中依次输入整数1,字符,整数2。 字符的前后都有一个空格。

输出格式:

类似3 & 4 = 0

其中,运算符号&的前后都有一个空格,等号的前后也都有一个空格。 上面表示3和4做二进制的与运算,结果是0。

输入样例:

符号&的前后,各有一个空格。

3 & 4

输出样例:

3的二进制是0011,4的二进制是0100,二者与运算的结果是0。

注意&=的前后,都是有且仅有一个空格。

3 & 4 = 0

输入样例:

7 X 3

输出样例:

ERROR

Code

#include<stdio.h>
int main(){
    int a,b;
    char c;
    scanf("%d %c %d",&a,&c,&b);
    if(c=='&'){
        printf("%d %c %d = %d",a,c,b,a&b);
    }else if(c=='|'){
        printf("%d %c %d = %d",a,c,b,a|b);
    }else if(c=='^'){
        printf("%d %c %d = %d",a,c,b,a^b);
    }else{
        printf("ERROR");
    }
    return 0;
}

3-4 7-4 位运算

给定一个数,将该数的某二进制位上置0、置1或取反。

输入格式:

第1行:输入一个十进制整数。(32位int取值范围,其二进制数补码表示)

第2行后:每行输入一个位操作运算要求。

格式:输入位操作运算类型(1表示置02表示置13表示按位取反) 位数(从最低位向高位,范围从0~31

最终以键盘输入^Z 或 文件结束(EOF标志)。

输出格式:

输出位运算后的整数值。

输入样例:

在这里给出一组输入。例如:

3
1 0
1 1
2 3
3 1
3 2
2 0

输出样例:

在这里给出相应的输出。例如:

15

Code

#include<stdio.h>
#include<stdlib.h>
int main(){
    int n;
    scanf("%d",&n);
    int op,dig;
    while(scanf("%d%d",&op,&dig)!=EOF){
        if(op==1){
            n=n&~(1<<dig);
        }
        if(op==2){
            n=n|(1<<dig);
        }
        if(op==3){
            if((n & (1 << dig)) != 0)
                n=n&~(1<<dig);
            else
                n=n|(1<<dig);
        }
    }
    printf("%d",n);
    return 0;
}

PTA | C-位运算相关题目
https://acm.nanyan.cc/posts/f1b7.html
作者
nanyan
发布于
2024年1月5日
许可协议