C TRICKS

发布于 2022-10-30  324 次阅读


任务wp部分

  • 第一题: 求1-n 的累加和, n 为整数。

    #include
    int main()
    {
      printf("请输入需要累加的数\n");
      int sum=0,n;
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
      {
          sum=sum+i;
      }
      //sum=(1+n)*n/2;好像可以直接这样嘿嘿
      printf("%d\n",sum);
      system("pause");
      return 0;
    }
  • 第二题: 输入一行字符求其中 字母个数、数字的个数、空格的个数及其他字符的个数

    #include
    int main()
    {
      printf("请输入字符串\n"); 
      char in,inc[111]={};
      int c=0,zimu=0,num=0,str=0;
      while((in=getchar())!='\n') //这里如果改成"\n"就会报错,不知道为啥???
      {
          inc[c]=in;
          c=c+1;
      }
      for(int i=0;i<=c-1;i++)
      {
          //printf("%d\n",inc[i]);
          if((inc[i]<=57)&&(inc[i]>=48))
          {
              num++;
              continue;
          }
          if(((inc[i]<=90)&&(inc[i]>=65))||((inc[i]<=122)&&(inc[i]>=97)))
          {
              zimu++;
              continue;
          }
      str++;
      }
      printf("有%d个数字,%d个字母,%d个字符串\n",num,zimu,str);
      system("pause");
    }
  • 第三题a:写完整的程序,判断数 n 是否是素数。要求用函数。函数原型: int prime (int n);函数功能: 如果是素数 函数返回值是 1 , 否则 是 0

    #include
    int prime(int n)
    {
      int m;
      m=ceil(sqrt(n));
      for(int i=2;i<=m;i++)
      {
          if((n!=2)&&(n%i==0))
          {
              return 0;
          } 
      }
      return 1;
    }
    
    int main()
    {
      int n;
      printf("输入你想判断的数\n");
      scanf("%d",&n);
      printf("判定结果为%d\n",prime(n));
      system("pause");
      return 0;
    }
  • 第三题b:要求同上 ,函数原型为: void n_prime (int n);函数功能: 该函数不带回返回值, 如果 n 是素数 ,该函数输出 this is a prime.否则 输出 this is not a prime.

    #include
    void n_prime(int n)
    {
      int m;
      m=ceil(sqrt(n));
      for(int i=2;i<=m;i++)
      {
          if((n!=2)&&(n%i==0))
          {
              printf("this is not a prime\n");
              return;
          } 
      }
      printf("this is a prime\n");
    }
    
    int main()
    {
      int n;
      printf("输入你想判断的数\n");
      scanf("%d",&n);
      n_prime(n);
      system("pause");
      return 0;
    }
  • 第四题:输入一行字符,统计其中 数字的个数。要求用函数。函数原型 int number( char ch) ;函数功能 如果 ch 是 ‘0’---‘9’ , 函数返回值是 1 否则是 0

    #include
    int number(char ch)
    {
          if((ch<=57)&&(ch>=48))
          {
              return 1;
          }
      return 0;
    }
    int main()
    {
      printf("请输入需要统计的字符串\n");
      char ch;
      int q=0,sum=0;
      do
      {
          scanf("%c",&ch);//第二题用的getchar,这一道用scanf吧,雨露均沾了属于是 
          sum=sum+number(ch);
          q++;
      }
      while(ch!='\n');
      printf("有%d个数字\n",sum);
      system("pause");
      return 0;
    }
  • 第五题:求 n! , 要求用递归。

    #include
    int jiecheng(int n)
    {
      if(n==1)return n;
      n=n*jiecheng(n-1);
      //printf("%d\n",n);
    }
    int main()
    {
      printf("输入想要阶乘的数\n");
      int n;
      scanf("%d",&n);
      //n=int(n);
      if(n<=0)
      {
          printf("你搁这玩儿我呢,重新输!");
          return 0;
      }
      printf("%d\n",jiecheng(n));
      //n=jiecheng(n);
      //printf("%d",n);
      system("pause");
      return 0;
    }

proc's wp部分

proc1

#include <stdio.h>

int main(void)
{
    char str[] = "hello world";
    for (size_t i = 0,count = sizeof(str) - 1; i < count; i++)
    {
        putchar(str[i]);
    }
    return 0;
}

/*
以上程序的输出是:
A hello
B hello world
C HELLO WORLD
D HELLOWORLD
*/
  • 选b
  • size_t表示的是当前环境最大的数类型(通常都是unsigned,因为unsigned没有符号,就多了一位存放数据,比有符号数的范围要大一倍)
  • sizeof()运算符可以获取变量或者类型的字节数,我们教材上就用这个获取了int类型是4个字节,这里被用作获取str数组的分配空间
  • 补充一个strlen(),可以获取字符串长度,如果用在这里,应该是比sizeof()多一位,因为字符数组被创建后会被自动在末尾加一个\0作为结束符(此函数会统计字符串中的空格)

proc2

#include <stdio.h>

int f(int a,int b)
{
    return a + b;
}

int main(void)
{
    printf("%d",f(1,2));
    return 0;
}

/*
以上程序的运行结果是:
A 0
B 1
C 2
D 3
*/
  • 选d
  • 不知道为啥源代码删掉了一些定义,这里加上了

proc3

#include <stdio.h>

static int var;

int main(void)
{
    printf("%d",var);
    return 0;
}

/*
以上程序的输出是:
A 0
B 1
C 2
D 3
*/
  • 这里学到了static关键字,在一个cpp文件中定义的全局变量(未在main函数或者其他函数中定义的变量),是可以在其他cpp文件中经过extern声明后被使用(暂时没有尝试),static声明的系统变量(只要加了static,不管在哪里声明的,都直接成为系统变量)无法在其他文件中被使用
  • 这里想要考察的应该是:未经初始化的局部静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)

proc4

#include <stdio.h>

typedef struct _Data
{
    int val;
} Data;

void func(Data a,Data b)
{
    int tmp = a.val;
    a.val = b.val;
    b.val = tmp;
}

int main(void)
{
    Data a = {.val = 1};
    Data b = {.val = 0};
    func(a,b);
    printf("%d %d",a.val,b.val);
    return 0;
}

/*
以上程序的输出是:
A 1 0
B 0 1
C 0 0
D 1 1 
*/
  • 选b
  • typedef相当于define,data是_data的别名
  • 这里形参交换了数值但是实参没有交换数值,而且结构体内部变量为局部变量,在结构体外应该用指针交换(问了一下大佬为啥不能直接交换,原来是因为函数中虽然可以对结构体的局部变量直接进行交换,但是交换的生命周期截至到函数结束,而在main函数中交换则可以维持到程序结束,所以需要使用指针交换)

proc5

#include <stdio.h>

size_t func(int arr[])
{
    return sizeof(arr);
}

int main(void)
{
    int arr[100];
    size_t size = func(arr);
    printf("%d",size == sizeof(arr));
    return 0;
}

/*
以上程序的输出是:
A 1
B 0
C 2
D 3
*/
  • 答案不是100吗? size_t size = func(arr);给size赋了个值,printf里面又有个==,于是我在本地试了一下
#include<bits/stdc++.h>
int main()
{
    int a=0,b=0;
    printf("%d",a==b);
    return 0;
}
  • 输出的结果是1,难道1是 真 的意思,于是做了以下测试
#include<bits/stdc++.h>
int main()
{
    int a=0,b=1;
    printf("%d",a==b);
    return 0;
}
结果是0

#include<bits/stdc++.h>
int main()
{
    int a=0,b=1;
    printf("%d",a!=b);
    return 0;
}
结果是1
  • 以上成功试出了printf("%d",size == sizeof(arr));的意思.==符号左边的内容是arr在函数中被sizeof()了,右边的内容是arr在main()中被sizeof()了,所以这里肯定相等,所以选a,然而答案错了
  • 查百度这里还有一个小知识数组在作为形参时会退化为指针,看不大懂,在本题中的后果是,sizeof直接处理数组,数组的每个空间都会按指针(4个字节)来计算,用函数把数组传入时,数组整体变成指针,一共就只有4个字节了
  • 400!=4,所以选b

proc6

#include <stdio.h>

int main(void)
{
    int var = 0;
    char *p = (char*)&var;
    *p = 255;
    printf("%d",var);
    return 0;
}

/*
以上程序的输出是:
A 0
B 64
C 128
D 255
*/
  • 选d
  • p->var的地址,对p指针变量的操作等价于对var变量的操作

proc7

#include <stdio.h>

void func(void f())
{
    printf("%d",sizeof(f));
}

void fun(){}

int main(void)
{
    func(fun);
    return 0;
}

/*
以上输出一定与哪个值相同:
A sizeof(int)
B sizeof(char)
C sizeof(int*)
D sizeof(short)
*/
  • 选a,c
  • 百度了一下,sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用,这里func函数输出了一个int型,选a,c?a是int肯定没错,通过上面学习知道指针是4个字节,int也是4个字节

proc8

#include <stdio.h>

int func(int f(int,int),int arg1,int arg2)
{
    printf("%d %d",arg1,arg2);
}

int comp()
{
    return 0;
}

int main(void)
{
    func(comp,0,1);
    return 0;
}

/*
以上程序的输出是:
A 0 1
B 1 1
C 0 0
D 编译失败
*/
  • 选d?改了几处都运行不了

proc9

#include <cstdio>

int main()
{
    int *p1 = new int;
    int *p2 = new int();
    std::printf("%d",*p1 == *p2);
    delete p1;
    delete p2;
    return 0;
}

/*
以上程序的输出是:
A 0
B 1
C 2
D 3
*/
  • 选a
  • 先补充一个知识,std::就是在名为std的空间中调用函数的意思
  • new int是申请了一个未知大小动态空间,如果是new int()则是申请空间并且进行初始化,区别是前者的量是未知且随机的,后者的量是0

proc10

#include <cstdio>

void func(int &a)
{
    std::printf("%d ",a + 1);
}

void func(int &&a)
{
    std::printf("%d ",a + 2);
}

int main()
{
    int &&a = 1;
    func(a);
    func(1);
    return 0;
}

/*
以上程序的输出是:
A 2 3
B 3 3
C 2 2
D 3 2
*/
  • 选a
  • 这里的&和&&不是取地址的意思,而是取左值(有地址的值)和取右值(没有地址的值)的意思
  • 查了好多资料,没咋看懂,网上的意思大概是左值引用(加一个&)时必须初始化左值,,右值引用(两个&&)必须初始化为右值
  • a是一个右值引用变量,但是它自身是一个左值,所以进第一个func,而1自身是一个右值,进第二个func
  • 这里还用到了函数的重载,函数名一样,但传参不同,就可以实现不同的处理
  • http://c.biancheng.net/view/7829.html这个比较靠谱,,,,,

奇奇怪怪的姿势

  • 上面第二题,如果用scanf输入字符串,会将最后一个敲击的回车遗留在缓冲区中,如果后面有相关的输入,会导致后面的程序出错,这时候就需要额外写一个getchar()来吃掉遗留的回车符号,如果用getchar来读入字符串则不存在该问题
  • 也是上面第二题,关于""和''和使用,""是存放的字符串,数据会被自动在结尾处添加\0作为结束符,而''表示的是单个的字母,上面的问题是scanf输入的数据类型是字符型,而!="\n"是字符串型,所以出错.
届ける言葉を今は育ててる
最后更新于 2024-02-07