C语言知识小店

!!!!ASCII码表

1.负数求模

除数或被除数有一方是负数的求模运算,并且结果的正负号有被除数的正负号决定。且取模运算的操作数不能是小数。

Eg.        5%-3=2        -5%3=-2

在c++/c中,求模运算两边的值只能是整数,否则会报错;

而在java中,求模运算可以是小数:

2.自增

a++:把a的当前值赋给运算式中,然后a再自增。

Eg.   a=1,b=1,c=1

        b+=a++ +c;结果:b=3,a=2,c=1

++a:先把a自增,再把a的值赋给当前运算式中。

Eg.        a=5,c=0;

        c=++a;结果:c=6,a=6

3.EOF

题目要求输入多组数据,但没有明确是输入几组,所以这时候需要用到EOF这个条件。

EOF即End Of File,作用是持续读取用户输入的两个整数,直到输入结束。

 如果想要结束输入,按ctrl+z后按enter键:

       

这是因为:

在c++中,想要输入多组数据,书写方式与C语言不同,如下

4.if语句易错点

if语句的括号里面允许出现赋值语句,而不是必须是条件判断语句,赋值语句不会报错;

if语句后如果只跟了一条语句这个时候if可以不带大括号,但是如果大于一个语句就必须跟大括号,因为不带大括号if只会控制其后跟的第一条语句。

else也遵循上述规则。

5.switch语句易错点

switch(c)语句中,c不可以是float或double类型。

若有多个case,但每个case后没有break,程序会把每一个case以及default执行,

func(1)=0;

6.coutinue与break跳出的区别

循环语句:for,while,do-while

continue:跳出当前所在循环语句的本次循环,并且不不会进行当前位置所在的以下所有语句。但是跳出本次循环以后,会继续进行下一次循环。

break:跳出break所在的循环语句,并且不会再继续进行循环。

7. fgets输入字符串,用strlen计算的结果的差异

如上图,我们可以得到: fgets函数输入字符串时,会在字符串结尾自动加上一个'\n',所以在用strlen计算字符串字符个数的时候,会把'\n'加入到字符串个数中.所以会比实际上输入字符串的真正个数多一个。

8.关于strlen

strlen不能用于计算数字数组的长度。因为strlen是专门为字符数组建立的。

9.strlen与sizeof;数字数组与字符数组

字符数组数字数组
sizeofsizeof计算时得到的是整个数组全部元素的个数,所以在计算字符数组的元素个数运用时要-1.在定义一个数字数组,初始化内容但没有指定数组的前提下)得到的就是数组的真实元素个数。
strlen

专门用于计算字符数组的元素个数。并且在计算时会自动去掉字符串末尾的‘\0’,所以得到的是数组中真正的元素个数。运用时很方便

\(不能用于此计算)

10.字符数组有无个数限制,对计算数组元素个数的不同影响。

sizeofstrlen
有大小限制不管用户输入多少个字符,结果总是初始化的大小不管有无初始化数组大小,结果总是用户输入的元素个数,不包括’\0'
无大小限制结果是用户输入的元素个数,包括‘\0'不管有无初始化数组大小,结果总是用户输入的元素个数,不包括’\0'

11.关于定义一个数字数组以及不同定义的情况下,计算数组元素的不同结果

不初始化内容同时也不指定元素个数 int arr[ ];错误❌
初始化内容但不指定元素个数int arr[ ]={1,2,3,4};用sizeof[arr]/sizeofarr[0];得到的就是真正的元素个数
初始化内容,同时指定元素个数int arr[10]={1,2,3};或者int arr[10];在之后用循环确定各位置上的元素用sizeof[arr]/sizeofarr[0];得到的是10.因为sizeof[arr]计算得到的是整个数组所占用的字节数,所以在相除后的结果总是10

12.检查数组是否存在相同的元素

  for (int i = 0; i < count - 1; i++) 
  {
      for (int j = i + 1; j < count; j++) 
      {
          if (digits[i] == digits[j]) 
          {
              hasSame = 1;
              break;
          }
      }
      if (hasSame) 
      {
          break;
      }
  }

 13.回文数

像“121”,“12321”,‘4334“这样从左往右往读和从右往左读都一样的正整数,叫做回文数。

14.判断一个数是否是回文数

#include<stdio.h>
int main()
{
    int num;
    scanf("%d",&num);
    int reversednum=0,remindernum=0,originalnum=0;
    originalnum=num;
    while(num!=0)
    {
        remindernum=num%10;
        reversednum=reversednum*10+remindernum;
        num/=10;
    }
    if(reversednum==originalnum)
    {
        printf("%d是回文数",originalnum);
    }
    else
    printf("%d不是回文数",originalnum);

    
    return 0;
}

15.a++不只是赋值运算,更是一种“行为”

省略部分代码
    int i=0;
    int a=0,b=1,c=3,d=4;
    i=(a++ && ++b + c++));
    printf("%d %d %d %d",a,b,c,d);
    printf("%d ",i);
结果:a=1,b=1,c=3,d=4,
        i=0;





(a++ && ++b + c++):先进行左边的a++。把a当前的值0赋给当前运算中,然后a再自增,a=1
                    逻辑运算中左式子为假,返回值为0.右边的式子不会进行计算。

i的结果是0或1,i的结果是括号里的逻辑运算的返回值。逻辑运算为真,返回1;运算结果为假,返回0.

16.逻辑运算符短路的特点

"||","&&"在逻辑运算中具有短路的特点。即当左边的表达式能确定逻辑运算的结果时,右边的表达式不会计算。

“||”:当左边的表达式为,不会进行右边的计算;返回值为1

“&&”:当左边的表达式为,不会进行右边的运算;返回值为0

17.连用2个scanf对不同类型元素输入的不同处理

scanf在处理不同类型的数据时,会有不同的处理方式。

对于%d(整型),会自动跳过空白字符,如:\n,\t等。连用2个scanf输入数字时,即使第一个输入后缓存区有空白字符,第二个scanf也会自动跳过,从%d处开始读取。不需要在第二个scanf的格式控制字符串前加一个空格。

对于%c(字符型),读取全部字符。在连用2个scanf输入字符时,输入第一个字符后,用户需要在键盘上按下一个Enter,这个换行符会留在缓冲区,程序运行到第二个scanf时,会立即读取这个换行符,从而导致第二个字符读取出错。所以在连用2个scanf输入字符时,需要在第二个scanf的格式控制符前加一个空格,让scanf跳过前面的空白字符。如果没有加空格,第二个输出就是空白字符:’ ‘

情况一:

情况二:

scanf不能用于输入字符串。如果输入了字符串,那么第一个scanf读取”hello“,遇到空格会停止,并把空格存储在缓冲区中,第二个scanf不能输入了,因为缓冲区现有的是“ world”,第二个scanf会继续读取缓冲区的“ world”,因为world前面有个’ ‘,所以相当于在第二个scanf的格式空格符前加了空格,吸取了换行符。所以输出会如下所示:

18.fgets与scanf连用,输入元素的处理

fgets输入字符串时,会读取全部字符

    fgets(str,sizeof(str),stdin);
    scanf("%c",&x);
    

fgets输入”hello“之后,用户会手动按下Enter,但是,(在输入的内容没有超过fgets的限制下)fgets会读取完整的输入,包括输入的换行符。所以,fgets后的scanf不需要再在scanf的格式控制符前加空格。 

19.空白字符

\f :换页符   作用:在早期的打印机和打字机中,用于将纸张推进到下一页的开头。在现代编程中,换页符的使用场景非常有限。                 

\n:换行符    作用:用于将光标移动到下一行的开头,实现文本的换行显示。      

\t:制表符               

' ':空格符               

\r:回车符:作用:将光标移动到当前行的开头。

20.fgets函数

fgets函数原型:
        char *fgets(char *str, int n, FILE *stream);

所以fgets是专门用于输入字符型的数据。       

21.与fgets配合使用的printf输出     

                                                                                                                 

printf 输出换行的原因是 fgets 函数读取输入时会将换行符 \n 也包含在读取的字符串中,而这个换行符在后续输出时导致了换行。                                                                                                                                                             

相比之下,scanf就输出就不会换行 

22.判断一个数是否为素数  

关键步骤: 

设m=a*b;如果m有因子,那么其中一个数字一定小于√m

因为m=√m* √m         

23.汉字占用字符个数   

  一个汉字占用2个字符        

24.库函数对应的头文件       

<stdio.h>

printf,scanf,gets,fgets

<string.h>

strlen,strcpy,strcmp

<stdlib.h>

system,rand

<time.h>

time

25.随机数生成(要求生成的随机数在1~100)

1.0(rand函数)

rand函数原型:

rand函数会生成一个“伪随机数”,这个随机数的范围是0~ RAND_MAX .RAND_MAX的值依赖编译器,大多都是32767.

但是,rand生成的随机数是伪随机数

当再一次运行该程序,会发现每一次的“随机”值都一样

这是因为,rand函数是一个对“种子”的基准值进行运算产生的随机数。之所以每次运行产生的随机数相同,是因为“种子”的默认值是1。如果要生成不同的随机数,“种子”应该是变化的。

2.0 rand+srand函数

srand用来初始化随机数的生成器

原型:

如上图,当srand()括号里的值变化时,rand生成的随机数的就是随机的,并且当为srand(1)时,rand生成的随机数与默认“种子”的相同 。也就是说,srand()括号里的值在变化,“种子”的值就在变化。

但是,rand生成随机数的前提是:srand()括号里的数是随机的。

生成一个随机数:前提是先生成一个随机数。这是矛盾的哦。

3.0  rand+srand+time

srand()不是必须需要一个随机生成的随机值,是一个本身就在不断变化的值就可以

time函数原型:

time_t==long long是一种整型;time函数的返回值就是时间戳。

时间戳:当前的时间 - 计算机的起始时间=秒数(得到的秒数就是时间戳)

                                        1970-1-1 0:0:0

 补充:NULL是用来初始化值指针变量的----0

不管生成多少随机数,只需要设置一次随机数生成的“种子”就行。

4.0 设置随机数的范围

生成0~99之间的随机数:

1. rand()%100;//范围是0~99

生成1~100之间的随机数:

2. rand()% 100 + 1;//范围1~100

生成100~200之间的随机数:

3.  100 + rand() % (200 -100 +1)//范围100~200

生成a~b之间的随机数 :

a + rand % (b - a + 1)

 26.%取余,得到指定范围的数

x是任意数(可以是1位数,2位数,3位数……)

x%100——得到的结果一定在0~99之间,不会>=100

x%1000——得到的结果一定在0~999之间,不会>=1000

...

这是因为:

27.在“种子”不变的前提下,多次运行程序与在一个程序内多次调用rand函数的区别

a.多次运行程序

多次运行程序,每次程序开始调rand函数时都是从初始固定的状态开始。而且rand函数生成的都是伪随机数,不是真正的随机,而是根据一个初始值(也就是“种子”)通过算法得到的结果,这个算法是固定的。所以,当“种子”相同时,得到的随机数(随机序列)也就相同。

b.在一个程序内多次调用rand函数

第一次调用 rand() 时,它基于默认种子生成一个随机数;第二次调用时,它会基于上一次调用后的内部状态生成另一个随机数,依此类推。所以程序运行时会输出不同的随机数。

28.调用srand可能遇到的问题

如果将第一张图片中的srand函数放到第二张图片的位置 ,可能会破环随机性:

每次调用game()函数都会重置“种子”的值,实际上会强制随机序列从新“种子”开始。假如玩家1s内进行了3局游戏,由于这三局的“种子”值(时间戳)相同,用rand()得到的随机值也就会相同。(虽然说1s内进行3局的可能性很小,但不是没有!!( ̄y▽, ̄)╭ ,那么把这串代码放在main函数里,只初始化一次,就完全避免了这种情况,完美)

29.if语句相关 

  1. if语句0为假,1为真(错误
    if语句中非0为真;非0包括1
  2. if语句后跟一条或多条语句;一条不需要加{};多条需要加{}。

30. 算术运算符相关

a%b:a,b只能是整数

a/b:a或b只要有一个是小数就可以进行小数除法运算

        a,b都是整数进行的是整数除法运算

31.printf函数

printf函数的占位符与参数是一一对应的关系。如果有n个占位符,就有n+1个参数。

因为格式化字符串也是一个参数

1个参数:格式化字符串

printf("Hello, World!");

2个参数:格式化字符串+一个整型参数

printf("Age: %d", 25);

32.等腰三角形的判断 

else if((a==b&&a!=c)||(a==c&&a!=b)||(b==c&&b!=a))
            {
                printf("Isosceles triangle!\n");
            }

记得(a==b&&a!=c),排除是等边三角形的可能。

33.内置类型

内置类型:是由编程语言直接提供的基本数据类型

数组是一种内置类型,数组内的元素包括内置类型和自定义类型。

34.Sleep函数

Sleep函数的头文件是<Windows.h>,S要大写

35.bool类型的使用

bool类型的使用需要包含头文件<stdbool.h>

36.形参与实参

形参与实参的名称可以相同,因为两个元素作用域不同定义域,不会报错

37.if语句中关系操作符易错点

如图,“j==x-i-1”,不要看右边是个表达式就写成“j=x-1-i”

38.计算字符数组的长度

不管字符数组末尾有没有'\0',用strlen计算得到的结果总是字符数的真实长度,不包含'\0'。如下图

数组acX和数组acY的长度不相同,acX的长度为8,acY的长度为7

当使用初始化列表来初始化字符数组时,数组的长度由初始化列表中元素的数量决定,不会自动添加空字符 '\0'。

但是,char acY[] = { 'a','b','c','d','e','f','g'};用strlen求长度时,因为没有'\0'结束标志,所以结果是一个随机值

39.C语言中的逗号表达式

所以结果是16

40.scanf的错觉

啊哈哈,错觉,一切都是错觉

41.二维数组初始化

42.变长数组的大小的确定

43.函数没有返回值就是void

44.fgets函数读取字符串会吸取“\n”符作为字符串内容

45.使用strcspn函数,把字符数组内的某一特定元素替换为另一元素

46.isspace(cha[])——判断数组是否为空,包含在string.h内

47.0.0/0.0=nan;浮点数/0.0=(+-)inf;整数/0.0=程序崩溃

48

49.指针未初始化,访问会导致程序崩溃

50.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值