C语言基础

 简介

1、转义字符(是一个字符)

所有的转义字符和所对应的意义:
转义字符
意义
ASCII码值(十进制)
\a
响铃(BEL)
007
\b
退格(BS) ,将当前位置移到前一列
008
\f
换页(FF),将当前位置移到下页开头
012
\n
换行(LF) ,将当前位置移到下一行开头
010
\r
回车(CR) ,将当前位置移到本行开头
013
\t
水平制表(HT) (跳到下一个TAB位置)
009
\v
垂直制表(VT)
011
\\
代表一个反斜线字符''\'
092
\'
代表一个单引号(撇号)字符
039
\"
代表一个双引号字符
034
\?
代表一个问号
063
\0
空字符(NUL)
000
\ddd
1到3位八进制数所代表的任意字符
三位八进制
\xhh
十六进制所代表的任意字符
十六进制

\n\  第一个\n代表换行;第二个\代表续行,代码很长,下面一行代码连接上一行(注意下面一行不能有缩进pri\    ntf;会把两个缩进拼接到当中,即经过解释后变成pri    ntf)

2、关键字

1999年12月16日,ISO推出了C99标准,该标准新增了5个C语言关键字:
_Imaginary
2011年12月8日,ISO发布C语言的新标准C11,该标准新增了7个C语言关键字:
_Alignas
_Alignof
_Atomic
_Static_assert
_Noreturn
_Thread_local
_Generic

词语解释

  • auto :声明自动变量
  • break:跳出当前循环
  • case:开关语句分支
  • char :声明字符型变量或函数返回值类型
  • const :声明只读变量
  • continue:结束当前循环,开始下一轮循环
  • default:开关语句中的“默认”分支
  • do :循环语句的循环体
  • double :声明双精度浮点型变量或函数返回值类型
  • else :条件语句否定分支(与 if 连用)
  • enum :声明枚举类型
  • extern:声明变量或函数是在其它文件或本文件的其他位置定义
  • float:声明浮点型变量或函数返回值类型
  • for:一种循环语句
  • goto:无条件跳转语句
  • if:条件语句
  • int: 声明整型变量或函数
  • long :声明长整型变量或函数返回值类型
  • register:声明寄存器变量
  • return :子程序返回语句(可以带参数,也可不带参数)
  • short :声明短整型变量或函数
  • signed:声明有符号类型变量或函数
  • sizeof:计算数据类型或变量长度(即所占字节数)
  • static :声明静态变量
  • struct:声明结构体类型
  • switch :用于开关语句
  • typedef:用以给数据类型取别名
  • unsigned:声明无符号类型变量或函数
  • union:声明共用体类型
  • void :声明函数无返回值或无参数,声明无类型指针
  • volatile:说明变量在程序执行中可被隐含地改变
  • while :循环语句的循环条件

3、变量

意义

变量的意义就是确定目标并提供存放空间

变量名定义规则

  • 变量名只能是英文字母(A-Z,a-z)和数字(0-9)或者下划线(_)组成。  i_love_fishC_520
  • 第一个字母必须是字母或者下划线开头。
  • 标识符区分大小写。  FISHC ≠fishc
  • 不能使用关键字来命名标识符。

4、常量

  • 整型常量:520,1314,123
  • 实型常量:3.14,5.12,8.97
  • 字符常量   

  —普通字符:'L','o','v','e'   

  —转义字符:'\n' ,'\t','\b'

  • 字符串常量:"FishC"
  • 符号常量:使用之前必须先定义

定义符号常量

 格式:#define  标识符  常量(所有的标识符被常量代替)

#include <stdio.h>

#define URL "http: // www .fishc.com"
#define NAME "鱼C工作室"
#define Boss "小甲鱼"
#define YEAR 2010
#define MONTH 5
#define DAY 20

int main ( )
{
    printf("%s成立于%d年%d月%d日 \n",NAME,YEAR,MONTH,DAY );
    printf("%s是%s创立的.... \n"",NAME,BoSS) ;
    printf("%s的域名是%s\n",NAME,URL);

    return 0;
}

标识符

  • 标识符只能是英文字母(A-Z,a-z)和数字(0-9)或者下划线(_)组成。  i_love_fishC_520
  • 第一个字母必须是字母或者下划线开头。
  • 标识符区分大小写。  FISHC ≠fishc
  • 不能使用关键字来命名标识符。

判断字符串常量的结束

'\0':表示空字符,代表字符串的结束位置

字符串:"Hello world"

'H' 'e' 'l' 'l' 'o' ' ' 'w' 'o' 'r' 'l' 'd' '\0'

5、格式符

printf——格式化输出

格式化占位符的语法如下:

%[flags][width][.precision][length]specifier

每一个格式化占位符均以 % 开始,以转换字符结束。

specifier

(转换字符,必选)的内容及含义如下:

转换字符
参数类型;转换结果
c
char;字符
d
int;有符号十进制整数
i
同上
e
double;以指数形式输出单、双精度浮点数(小写 e)
E
同上(大写 E)
f
double;以小数形式输出单、双精度浮点数
g
double;以 %f 或 %e 中较短的输出宽度输出单、双精度浮点数(指数显示小写 e)
G
同上(指数显示大写 E)
o
unsigned int;无符号八进制(无前导 0)
s
char *;字符串
u
int;无符号十进制
x
unsigned int;无符号十六进制(无前导 0x)
X
同上(无前导 0X)
p
void *;指针值
n
int *;存放已写字符的个数
%
不进行参数转换;即%%输出字符%

flags

(标志,可选)的内容即含义如下:

标志
含义
-
指定被转换的参数在其字段内左对齐(默认是右对齐)
+
指定在输出的数前面加上正负号
空格
如果第一个字符不是正负号,则在其前面加上一个空格
0
对于数值转换,当输出长度小于字段宽度时,添加前导 0 进行填充
#
指定另一种输出形式:
1. 如果转换字符为 o,则第一个数字为 0
2. 如果转换字符为 x 或 X,则指定在输出的非 0 值前加 0x 或 0X
3. 对于转换字符为 e、E、f、g 或 G 的情况,指定输出总是包含一个小数点。另外,对于转换字符为 g 或 G,还指定输出值尾部无意义的 0 将被保留

注:flags 可同时出现多个,且无顺序要求。

width

(宽度,可选)是一个数值,用于指定最小字段的宽度

转换后的参数输出宽度至少要达到这个数值。如果参数的字符数小于该数值,则在参数左边(如果 flags 设置为 -,要求左对齐的话则在右边)填充一些字符。填充字符通常为空格,但是如果 flags 设置为 0,则填充字符为数字 0。

.precision

(.精度,可选),通过点号(.)分隔字段的宽度和精度

  • 对于字符串,它指定打印的字符的最大个数
  • 对于整数,它指定打印的数字位数(必要时可加填充位 0 以达到宽度要求)
  • 对于转换字符为 e、E 或 f,它指定打印的小数点后的数字位数
  • 对于转换字符为 g 或 G,它指定打印的有效数字位数

length

(长度修饰符,可选)的值可以是 h、hh、l、ll 或 L

  • hh 表示将相应的参数按 signed char 或 unsigned char 类型输出
  • h 表示将相应的参数按 short 或 unsigned short 类型输出
  • l 表示将相应的参数按 long 或 unsigned long 类型输出
  • ll 表示将相应的参数按 long long 或 unsigned long long 类型输出
  • L 表示将相应的参数按 long double 类型输出

scanf——格式化输入

 格式化占位符的语法如下:

%[width][length]specifier 

specifier转换字符,必选)的内容及含义如下:

转换字符
含义
c
读取一个字符
d
读取一个十进制整数,前边可以加上符号(+ 或 -)表示正负
i
1. 读取一个整数,前边可以加上符号(+ 或 -)表示正负
2. 0 开头表示八进制数,0x 开头表示十六进制数
e
读取一个以指数形式的单、双精度浮点数(小写 e)
E
同上(大写 E)
f
读取一个单、双精度浮点数(需要使用 lf),前边可以加上符号(+ 或 -)表示正负
g
同 f、e、E
G
同上(指数显示大写 E)
a
读取一个十六进制的浮点数(以 0x 或 0X 开头)
o
读取一个八进制整数,前边可以加上符号(+ 或 -)表示正负
s
读取一连串字符,直到遇到空白字符结束。
u
读取一个无符号的十进制整数
x
1. 读取一个十六进制整数,前边可以加上符号(+ 或 -)表示正负
2. 十六进制数以 0x 或 0X 开头
p
读取一个指针的值
[characters]
1. 匹配中括号括起来的字符集
2. 可以用小横杆(-)表示范围,比如 [0-9]
[^characters]
1. 匹配除了中括号括起来的字符集
2. 可以用小横杆(-)表示范围,比如 [0-9]
n
1. 存放已经读取的字符个数
2. 不消耗任何标准输入流的字符
%
表示匹配 % 自身


注1:除了 n,其他的每次读取都会至少消耗标准输入流中的一个字符。
注2:如果读取失败,则标准输入流截断于读取失败的位置。
星号(*)、width 和 length 是可选的。

  • 星号(*)表示读取但忽略(读取但不保存);
  • width 指定当前读取操作的最大字符数;
  • length 是用于限定不同类型的宽度,具体请参考下表:
length
d 或 i
u、o 或 x
f、e、g 或 a
c、s、[] 或 [^]
p
n
默认
int*
unsigned int*
float*
char*
void**
int*
hh
signed char*
unsigned char*
     
signed char*
h
short int*
unsigned short int*
     
short int*
l
long int*
unsigned long int*
double*
wchar_t*
 
long int*
ll
long long int*
unsigned long long int*
     
long long int*
j
intmax_t*
uintmax_t*
     
intmax_t*
z
size_t*
size_t*
     
size_t*
t
ptrdiff_t*
ptrdiff_t*
     
ptrdiff_t*
L
   
long double*
     

6、数据类型

6.1 定义

  • char  字符型,占用一个字节
  • int  整型,通常反映了所用机器中整数的最自然长度
  • float  单精度浮点型
  • double  双精度浮点型
  • 布尔类型  true、false两个常量

整数类型:short int ≤ int ≤ long int ≤l ong long int

例:

#include <stdio.h>

int main()
{
        int a = 520;
        char b = 'F';
        float c = 3.14;
        double d = 3.141592653;

        printf("鱼C工作室创办于2010年的%d\n", a);
        printf("I love %cishC.com!\n", b);
        printf("圆周率是:%.2f\n", c);  //精确到小数点后两位
        printf("精确到小数点后9位的圆周率是:%11.9f\n", d);  //精确到小数点后9位,11是指总占11位宽度

        return 0;
}

6.2 sizeof运算符

sizeof运算符用于获得数据类到或表达式的长度

  • sizeof(object);  //sizeof(对象);
  • sizeof(type_name);   //lsizeof(类型);
  • sizeof object;  //sizeof对象;

6.3 signed与unsigned

类型限定符,限定char类型或任何整型的取值;signed带符号,unsigned不带符号

  • [signed] short [int]  [ ]及其中内容可省略,默认情况下int是signed类型
  • unsigned short [int]
  • [signed] int
  • unsigned int
  • [signed ] long [int]
  • unsigned long [int]
  • [signed] long long [int]
  • unsigned long long [int]

%d 有符号位

%u 无符号位

6.4 取值范围

CPU能读懂的最小单位——比特位,bit,b

内存机构的最小寻址单位——字节,Byte,B

1Byte=8bit

符号位

  • 存放signed类型的存储单元中,左边第一位表示符号位。如果该位为0,表示该整数是一个正数;如果该位为1,表示该整数是一个负数。
  • 一个32位的整型变量,除去左边第一位符号位,剩下表示值的只有31个比特位。
  • 事实上,计算机通过补码的形式来存放整数的值。

补码

  • 正数的补码是该数的二进制形式。
  • 负数的补码需要通过以下几步获得:

    1. 先取得该数的绝对值的二进制形式

    2. 再将第1步的值按位取反

    3. 最后将第2步的值加1

 

7、字符和字符串

ASCII字符表:

https://fishc.com.cn/forum.php?mod=viewthread&tid=67427&extra=page%3D1%26filter%3Dtypeid%26typeid%3D571

声明字符串

格式:char 变量名[数量];

   变量名[索引号]=字符;

//声明字符串:
char name[5];
//给字符串赋值:
name[0] = 'F';
name[1] = 'i';
name[2] = 's';
name[3] = 'h';
name[4] = 'C';
#include <stdio.h>

int main()
{
  char a[6]={'F','i','s','h','C','\0'}; //定义字符串,\0字符串结束符号
  printf("%s\n",a);
  printf("Hello world!");

  return 0;
}
等同于
  char a[]={'F','i','s','h','C','\0'}; //编译器自动计算长度
  char a[]={"FishC"}; //字符串常量""括起来

8、运算符

算术运算符

运算符 名称 说明 结果
+ 加法运算符(双目) 具有左结合性(1+2.0=1.0+2.0即整型+浮点型会自动转化为浮点型+浮点型,输出为浮点型) 5+3 8
- 减法运算符(双目) 具有左结合性  5-3 2
* 乘法运算符(双目) 具有左结合性 5*3 15
/ 除法运算符(双目) 具有左结合性。参与运算量均为整型时,结果也为整型,舍去小数。如果运算量中有一个是实型,则结果为双精度实型。 5/3 1
5.0/3.0 1.666667
% 求余运算符(双目) 有左结合性。要求参与运算的量均为整型,不能应用于float或double类型。 求余运算的结果等于两数相除后的余数,整除时结果为0 5%3 2
5.0%3.0 出错
+ 正号运算符(单目) 具有右结合性  +5 5
- 负号运算符(单目) 具有右结合性  -5 -5
?: 条件运算符(三目) 条件?结果1:结果2  可理解为条件是否为真,条件成立为结果1,否则为结果2,具有右结合性    

  所谓结合性,就是当一个表达式中出现多个优先级相同的运算符时,先执行哪个运算符:先执行左边的叫左结合性,先执行右边的叫右结合性。(C语言运算符优先级和结合性一览表)

  双目运算符+和-具有相同的优先级,它们的优先级比运算符*、/和%的优先级低,而运算符*、/和%的优先级又比单目运算符 +(正号) 和 -(负号) 的优先级低。

#include <stdio.h>

int main()
{
    printf("整型输出:%d\n",1+2.0);
    print("浮点型输出:%f\n",1+2.0);

    return 0;
}
/*结果
整型输出:0
浮点型输出:3.0
*/

  print("整型输出:%s\n",1+(int)2.0); //强制将浮点型转化为整型,结果 整型输出:3
  print("整型输出:%s\n",1+(int)1.8);  //结果 整型输出:2

关系运算符

  • 使用关系运算符来比较两个数的大小关系:

优先级(6)

>

大于

表达式>表达式

左结合性

双目运算符

 

>=

大于等于

表达式>=表达式

<

小于

表达式<表达式

<=

小于等于

表达式<=表达式

优先级(7)

==

等于

表达式==表达式

左结合性

!=

不等于

表达式!= 表达式

  • 关系表达式

    用关系运算符将两边的变量、数据或表达式连接起来,称之为关系表达式。关系表达式得到的值是一个逻辑值,即真或假,在C语言的逻辑运算中,用数字1表示真,用数字0表示假。

举个例子:

  关系表达式1<2的值为真,因此该关系表达式的值为1

  关系表达式'a' +'b'<= 'c',因为字符'a'、'b'、'c'对应的ASCII码分别是97、98、99,即97 +98<=99,因此该表达式的值为0

#include <stdio.h>

int main()
{
    int a=5,b=3;
    printf("%d\n",1<2);
    printf("%d\n",a>b);
    printf("%d\n",a<=b+1);
    printf("%d\n",'a'+'b'<='c');  //'a'、'b'、'c'对应的ASCII码分别是97、98、99
    printf("%d\n",(a=3)>(b=5));

    return 0;
}
/*
结果
1
1
0
0
0
*/

逻辑运算符

优先级

运算符

含义

使用形式

说明

2

逻辑非

!表达式a

如果a为真,!a为假;

如果a为假,!a为真。

11

&&

逻辑与

表达式a&&表达式b

只有a和b同时为真,结果才为真;

只要a 和 b 其中一个为假,结果为假。

12

||

逻辑或

表达式a||表达式b

只要a或b其中一个为真,结果为真;

只有a和b同时为假,结果才为假。

  •  用逻辑运算符将两边的变量、数据或表达式连接起来,称之为逻辑表达式:
#include <stdio.h>

int main()
{
    int a=5,b=3;
    
    printf("%d\n",3>1&&1<2);
    printf("%d\n",3+1||2==0);
    printf("%d\n",!(a+b));
    printf("%d\n",!0+1<1||!(3+4));
    printf("%d\n",'a'-'b'&&'c'); //'a '、'b'、'c'对应的ASCII码分别是97、98、99,97-98=-1不等于0即为真

    return 0;
}
结果
1
1
0
0
1

短路求值

  • 短路求值又称最小化求值,是一种逻辑运算符的求值策略。只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值。
  • C语言对于逻辑与和逻辑或采用短路求值的方式。
#include <stdio.h>

int main()
{
    int a=3,b=3;
    
    (a=0)&&(b=5); //&&左边不成立,右边不会进行运算了
    printf("a=%d,b=%d\n",a,b);
    
    (a=1)||(b=5); //||左边成立,右边不用管了
    printf("a=%d,b=%d\n",a,b);
    
    return 0;
}
结果:
a=0,b=3
a=1,b=3

9、if语句

if语句(1)

if(条件)
{
  表达式 //逻辑值为真即条件满足所执行的语句、程序块
}

if语句(2)

if(条件)
{
  表达式1   //逻辑值为真所执行的语句、程序块
}
else
{
  表达式2   //逻辑值为假所执行的语句、程序块
}

if语句(3)

if(条件1){.....}
else if(条件2){......}
else if(条件3){......}

例:分数评级

#include <stdio.h>

int main()
{
    int i;
    printf("请输入分数:");
    scanf("%d",&i);

    if(i>=90)
    {
        printf("A\n");
    }
    else if(i>=80&&i<90)
    {
        printf("B\n");
    }
    else if(i>=70&&i<80)
    {
        printf("C\n");
    }
    else if(i>=60&&i<70)
    {
        printf("D\n");
    }
    else
    {
        printf("不及格\n");
    }
    
    return 0;
}
View Code

10、switch语句和分支嵌套

switch语句

switch(表达式)
{
    case 常量表达式1:语句或程序块1
    case 常量表达式2:语句或程序块2
    ......
    case 常量表达式n:语句或程序块n
    default:语句或程序块n+1
}

例:成绩评估

#include <stdio.h>

int main()
{
    char ch;
    
    printf("请输入成绩:");
    scanf("%c",&ch);

    switch(ch)
    {
        case 'A': printf("你的成绩在90分以上\n"); break; //break跳出
        case 'B': printf("你的成绩在80~90分之间\n"); break;
        case 'C': printf("你的成绩在70~80分之间\n"); break;
        case 'D': printf("你的成绩在60~70分之间\n"); break;
        case 'E': printf("你的成绩在60分以下\n"); break;
        default: print("请输入有效成绩"); break; //这个break可不加
    }
    return 0;
}    
View Code

else悬挂

#include <stdio.h>

int main()
{
    char isRain,isFree;

    printf("是否有空? (Y/N)");
    scanf("%c",&isFree);

    getchar();  //过滤空格,如果没有,isRain值会接收回车,出错

    printf("是否下雨? (Y/N)");
    scanf("%c",&isRain);

    if(isFree == 'Y')
    {
        if(isRain == 'Y')
            {
                printf("记得带伞噢^_^\n");
            }
    }
    else
    {
        printf("女神没空!T_T\n");
    }
    
    return 0;
}    
View Code

等于号带来的问题

#include <stdio.h>

int main()
{
    char hasBF;

    printf("XXX你有男朋友吗?(Y/N)");
    scanf("%c",&hasBF);

    if(hasBF == 'Y') //=是赋值,==是等于,实战中避免出错,可以将两值对调即'Y' == hasBF,如果你用了=,会报错
    {
        printf("那...祝你们幸福咯!\n");
    }
    else
    {
        printf("那我们在一起吧!\n");
    }
    
    return 0;
}
View Code

11、循环结构

while语句和dowhile语句

  • while语句(入口条件循环)

while(表达式)

  循环体 

  • do while 语句(出口条件循环)

do

  循环体

while (表达式);

例:

  • 1+2+3+...+100前一百和
#include <stdio.h>

int main()
{
    int i=1,sum=0;

    while(i<=100){
        sum = sum + i;
        i=i+1;
    }
    printf("结果是:%d\n",sum);

    return 0;
}
View Code
  •  统计从键盘输入的一行英文句子的字符
#include <stdio.h>

int main()
{
    int count = 0;

    printf("请输入一行英文字符:");
    
    while(getchar() != '\n')
    {
        count = count + 1;
    }
    printf("你总共输入了%d个英文字符!\n", count);

    return 0;
}
View Code

for语句和循环嵌套

for语句

for(表达式1;表达式2;表达式3)

  循环体

/*表达式1:循环初始化表达式

表达式2:循环条件表达式

表达式3:循环调整表达式

表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式(即用逗号分隔开的多个表达式)*/

例:

  • 打印十次FishC!
#include <stdio.h>

int main()
{
    int count;

    for (count = 0;count < 10;count++)
    {
        printf("FishC!\n");
    }

    return 0;
}
View Code
  • 判断一个数是否为素数
#include <stdio.h>

int main()
{
    int i,num;
    _Bool flag=1;
    
    printf("请输入一个整数:");
    scanf("%d",&num);

    for(i=1;i<num/2;i++)
    {
        if(num % i==0)
        {
            flag=0;
        }
    }
    if(flag)
    {
        printf("%d是一个素数\n",num);
    }
    else
    {
    printf("%d不是一个素数",num);
    }
        
    return 0;
}
View Code
  • 灵活的for语句

表达式1,表达式2和表达式3可以按照需要进行省略(但分号不能省):

for(表达式1;表达式2 ; )

for( ; 表达式2;表达式3)

for(表达式1; ; )

for( ; ; )   //死循环

  • C99新标准

C99允许在for语句的表达式1中定义变量

    int i,j;
    
    for(i=0,j=10;i<j;i++,j--)
    {
        printf("%d\n",i);
    }
//C99新标准形式:
    for(int i=0,j=10;i<j;i++,j--)
    {
        printf("%d\n",i);
    }

循环嵌套

先执行内层循环,再执行外层循环

#include <stdio.h>

int main()
{
    int i,j;

    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("i=%d,j=%d\n",i,j);
        }
    }

    return 0;
}
//结果:
i=0,j=0
i=0,j=1
i=0,j=2
i=1,j=0
i=1,j=1
i=1,j=2
i=2,j=0
i=2,j=1
i=2,j=2
View Code
  • 九九乘法表
#include <stdio.h>

int main()
{
    int i,j;

    for(i=1;i<=9;i++)
    {
        for(j=1;j<=i;j++)
        {
            printf("%d*%d=%-2d",i,j,i*j);
        }
        putcha("\n");
    }
    
    return 0;
}
//结果:
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6  3*3=9
4*1=4 4*2=8  4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6 7*7
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6 8*7 8*8
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6 9*7 9*8 9*9=81
View Code

 

 

 

 

 

 

 

posted @ 2021-03-12 19:18  奔跑的snail  阅读(207)  评论(0编辑  收藏  举报