06.2 操作符、函数习题

第一题

以下代码的输出结果

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    short *p = (short *) arr;
    for (int i = 0; i < 4; i++) {
        *(p + i) = 0;
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}

image-20220104004117392

解析:这里的重难点就是short *p = (short *) arr;因为short只有2字节,所以他每次只能操作两个字节的地址。这样的话第一个for循环就可以将两个int的内容变为0。输出的时候就前两个值为0后面的不变。

第二题

以下代码的输出结果

int main() {
    int a = 0x11223344;
    char *pc = (char*)&a;
    *pc = 0;
    printf("%x \n",a);//十六进制的输出形式
    return 0;
}

image-20220104004852646

解析:0x11223344在内存中存储内容是44332211,char* 每次只能操作一个字节的内容。所以44->0,输出的时候再逆序输出就是11223300。

第三题

以下代码的输出结果

int i;
int main() {
    i--;
    if(i> sizeof(i)){
        printf("> \n");
    } else{
        printf("<\n");
    }
    return 0;
}

image-20220104005537888

解析:全局变量没有初始化的时候默认是0;

sizeof()计算变量/变量所占内存的大小。大小>=0,是无符号数。

当无符号数与正常数字进行比较时先将正常数转化为无符号数。-1转化为无符号数是一个很大的值。所以结果就是 “>”。

第四题

以下代码的输出结果

int main() {
    int a=0,b=0,c=0;
    a = 5;
    c = ++a;
    b = ++c,c++,++a,a++;
    b += a++ + c;
    printf("a = %d b = %d c = %d\n",a,b,c);
    return 0;
}

image-20220104011710562

解析:"=“的优先级高于”,",1. a = 5;c = 6;c = 7;b = 7;c = 8;a = 6;a = 7; “+“的优先级高于”=” 2. 计算b += a++ + c; -> a = 8, c = 8 b = 7->>b = 23

第五题

统计一个数二级制中1的个数

写一个函数返回参数二级制中1的个数。

方法一:
int Count_1(unsigned int n) {
    int count = 0;
    while (n) {
        if (n % 2 == 1) {
            count++;
        }
        n = n / 2;
    }
    return count;
}

int main() {
    int n = 0;
    scanf("%d", &n);
    //函数  a的二级制补码中的1的个数
    int count = Count_1(n);
    printf("count = %d", count);
    return 0;
}

解析:计算二进制为1的位数时每次对2取余就是获取最后一位的数字。除以二就是将这个数最后一位删去。对于负数只需要将其按照无符号数来对待就可以了。

方法二:
int Count_1( int n) {
    int count = 0;
    for(int i = 0;i<32;i++){
        if(((n>>i)&1)==1){
            count++;
        }
    }
    return count;
}

解析:使用移位的方式,和位计算且的原理,只要和1与运算的结果为一说明当前数的最后一位为1,每次多移一位进行运算。出现1count+1。32次运算,结果就是答案。

方法三:
int Count_1( int n) {
    int count = 0;
	while(n){
        n = n&(n-1);
        count++;
    }
    return count;
}

解析:一个数的二进制可以通过(n)&(n-1)将n最右边的1消除掉。这样计算时间复杂度是最低的。

第六题

题目:求二进制中不同位的个数

内容: 两个int(32位)整数m和n的二进制表达式中,有多少个位(bit)不同。

int Count_1( int n) {
    int count = 0;
	while(n){
        n = n&(n-1);
        count++;
    }
    return count;
}
int GetDiff(int m,int n){
    int count=0;
    count = Count_1(m^n);
    return count;
}
int main(){
    int m=0,n=0;
    scanf("%d %d",&m,&n);
    int count = GetDiff(m,n);
    printf("count=%d",count);
    return 0;
}

解析:先将两数进行异或计算。这样不相同的位数就可以由异或后的值进行表达,然后再将此值进行位为1的个数统计。

第七题

题目:打印二进制的奇数位和偶数位(从低位往高位数)

获取一个整数的二进制序列中所有的偶数位和奇数位,分别打印出二进制序列。

void Print(int m){
    for (int i = 30; i >= 0; i-=2) {
        printf("%d",(m>>i)&1);
    }
    printf("\n");
    for (int i = 31; i >= 0; i-=2) {
        printf("%d",(m>>i)&1);
    }
}
int main(){
    int m = 0;
    scanf("%d",&m);
    Print(m);
    return 0;
}

解析:从最高位开始右移每次只要最后一位。通过奇数位偶数位的控制进行打印。

第八题

题目:交换两个变量(不创建临时变量)

方法一 思路 (加减法可能会溢出)

image-20211231120741442

代码实现

int a = 2;
int b = 3;
a = a+b;
b = a-b;
a = a-b;

方法二 (思路) 一个数对同一个数两次异或回到本身。而且异或运算有交换律

image-20211231122117758

代码实现

int a = 2;
int b = 3;
a = a^b;
b = a^b;
a = a^b;
printf("%d  ",a);
printf("%d  ",b);

image-20211231123937838

函数传参

第一题

字符串逆序(递归实现)

编写一个函数reverse_string(char* string)。

非递归:

void reverse_string(char* arr,int sz){
    int left= 0;
    int right = sz-2;
    int temp;
    while (left<right){
        temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
}
int main(){
    char arr[] = "abcdef";
    int sz = sizeof(arr)/ sizeof(arr[0]);
    // printf("%d",sz);
    reverse_string(arr,sz);
    printf("%s",arr);
}

递归:

int my_strlen(char *str) {
    char *start = str;
    char *end = str;
    while (*end != '\0') {
        end++;
    }
    return (int)(end - start);
}
void reverse_string(char arr[]) {
    char temp = arr[0];
    int len = my_strlen(arr);
    arr[0] = arr[len - 1];
    arr[len - 1] = '\0';
    if (my_strlen(arr + 1) >= 2)
        reverse_string(arr + 1);
    arr[len - 1] = temp;
}
int main() {
    char arr[] = "abcdefg";
    printf("%d\n", my_strlen(arr));
    reverse_string(arr);
    printf("%s\n", arr);
    return 0;
}

解析:问题分解。交换最外层的两个值,当当前字符串长度大于等于2时递归。

实现步骤:1.将数组第一个值传给临时变量temp,将最后一个值传给第一个值。2.将最后一个位置先修改为’\0’用来表示字符串暂时结束。3.将数组下标从第二个开始reverse_string()。4.递归完之后将临时变量的值传给最后一个位置。

第二题

计算一个数的每位之和(递归实现)

写一个递归函数DigitSum(a),输入一个非负整数,返回组成他的数字之和。

int DigitSum(unsigned int num){
    if(num/10 == 0){
        return num;
    }
    return num % 10 +DigitSum(num/10);
}

int main(){
    unsigned int num = 0;
    scanf("%d",&num);
    int res = DigitSum(num);
    printf("res = %d",res);
    return 0;
}

解析:终止条件就剩下一位数的的时候。举例1234的每位之和等于4+123的每位之和。

第三题

递归实现n的k次方

double Pow(int n,int k){
    if (k==0) return 1;
    else if (k>0) return n* Pow(n,k-1);
    else return (1.0/n)* Pow(n,k+1);
}

int main(){
    int n = 2;
    int k = -3;
    double res = Pow(n,k);
    printf("res = %lf \n",res);
    return 0;
}

解析:Pow(n,k) = n * Pow(n,k-1)。终止条件,k == 0的时候等于1。

第四题

计算斐波那契数列(递归实现)

int Fib(int first,int second,int n){    //---->>>需要修改参数的量
    if (n<=2) return 1;
    if (n==3) return first+second;
    else return Fib(second,first+second,n-1);
}
int main(){
    int n;
    scanf("%d",&n);
    int res = Fib(1,1,n);
    printf("%d",res);
    return 0;
}

解析:经过优化的斐波那契数列。
w(n,k-1)。终止条件,k == 0的时候等于1。

第四题

计算斐波那契数列(递归实现)

int Fib(int first,int second,int n){    //---->>>需要修改参数的量
    if (n<=2) return 1;
    if (n==3) return first+second;
    else return Fib(second,first+second,n-1);
}
int main(){
    int n;
    scanf("%d",&n);
    int res = Fib(1,1,n);
    printf("%d",res);
    return 0;
}

解析:经过优化的斐波那契数列。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎丶辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值