C语言

Hello World程序

1
2
3
4
5
6
7
8
9
10
11
12
//std 标准,i input 输入,o output输出,标准输入输出库
#include <stdio.h>

//main函数,主函数,是程序的入口,有且只能有一个
int main() {

// printf是一个库函数,用来打印数据的
printf("Hello World\n");

//返回值
return 0;
}

数据类型

数据类型 描述 大小
char 字符型 1字节(-128~127)
short 短整型 2字节
int 整型 4字节
long 长整型 Windows为4字节
long long 更长的整型 8字节
float 单精度浮点型 4字节
double 双精度浮点型 8字节
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main() {
printf("%d\n",sizeof(char)); //1
printf("%d\n",sizeof(short )); //2
printf("%d\n",sizeof(int)); //4
printf("%d\n",sizeof(long)); //4
printf("%d\n",sizeof(long long)); //8
printf("%d\n",sizeof(float)); //4
printf("%d\n",sizeof(double )); //8
return 0;
}

标识符

标识符命名规则

  • 标识符不能是关键字
  • 标识符只能由字母、数字、下划线组成
  • 第一个字符必须为字母或下划线
  • 标识符中字母区分大小写

变量和常量

变量

变量分为局部变量和全局变量
局部变量:在{}内定义的变量
全局变量:在{}外定义的变量
当全局变量和局部变量名字一样的情况下,局部优先

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main() {
int num1=0;
int num2=0;
scanf("%d %d",&num1,&num2); //100 200
int result = num1 + num2;
printf("result:%d",result);
return 0;
}

>>>
result:300

对scanf函数的理解

在上面的代码中scanf定义的输入格式为scanf("%d %d",&num1,&num2),两个数字,中间空格隔开,但是我在终端或者编译器中输入时,可以是两个数字中间空格隔开,也可以是两个数字换行输入,而且中间空格的数量也没有限制。

变量作用域和生命周期

作用域
局部变量的作用域是变量所在的局部范围内。
全局变量的作用域是整个工程。
生命周期
局部变量:进入作用域生命周期开始,出作用域生命周期结束。
全局变量:整个程序的生命周期。

extern声明

修饰变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>

// 函数外定义变量 x 和 y
int x;
int y;
int addtwonum()
{
// 函数内声明变量 x 和 y 为外部变量
extern int x;
extern int y;
// 给外部变量(全局变量)x 和 y 赋值
x = 1;
y = 2;
return x+y;
}

int main()
{
int result;
// 调用函数 addtwonum
result = addtwonum();

printf("%d\n",result);
printf("%d\n",x);
printf("%d\n",y);
return 0;
}

>>>
3
1
2

extern “C” …
表示后续的代码以C语言的方式进行编译,不进行符号修饰

常量

  • 字面常量
  • const 修饰的常变量
    1
    2
    const int a = 10;
    //c语言中const修饰的a,本质是变量,但是不能直接修改,有常量的属性。
  • #define定义的标识符常量
    1
    #define MAX 100
  • 枚举常量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    enum Color
    {
    RED,
    YELLOW,
    GREEN,
    BLUE
    };

    enum Sex
    {
    MALE,
    FEMALE
    };

字符串

由双引号引起来的一串字符称为字符串字面值或字符串。
字符串结束标志是\0的空字符。在计算字符串长度时,不算做字符串内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int main(){
// c语言没有字符串类型,只有字符数组
char arr1[]="abcdef";
char arr2[]={'a','b','c','d','e','f'};
printf("%s\n",arr1);
printf("%d\n",strlen(arr1)); //strlen 求一个字符串的长度
printf("%s\n",arr2);
printf("%d\n",strlen(arr2));
return 0;
}

>>>
abcdef //arr1在遇到\0之后字符串结束
6
abcdefabcdef //arr2没有\0,后面会无规则输出
12

转义字符

转义字符 释义
\? 在书写连续多个问号时使用,防止他们被解析成三字母词
\‘ 表示字符常量 ‘
\“ 用于表示一个字符串内部的 “
\\ 用于表示一个斜杠,防止它被解释为一个转义序列符
\a 警告字符,蜂鸣
\b 退格符
\f 进纸符
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ddd ddd表示1~3个八进制的数字。如:\130X
\xdd dd表示2个十六进制数字。如:\x30 0

占位符

占位符 释义
%d 整型
%o 八进制
%x 十六进制
%p 指针
%c 字符
%s 字符串
%f float类型数据
%lf double类型数据
%zu sizeof的返回值

注释

  • //:单行注释
  • /*...*/:多行注释

printf格式化输出

%d

1
2
3
4
5
6
7
int main(){
printf("%-8d??????????",123456);
return 0;
}

>>>
123456 ??????????

f格式符,指定宽度和小数位数 %m.nf

m表示输出数据的宽度,即占m列,n表示小数点后保留n位小数。
输出数据左对齐,用%-m.nf

1
2
3
4
5
6
7
int main(){
printf("%-5.2f??????????",1/3.0); //这里要注意是浮点数类型,如果两个整数相除,结果是整型
return 0;
}

>>>
0.33 ??????????

分支结构

if-else结构

1
2
3
4
5
6
7
8
9
if (表达式){
语句;
}
else if(表达式){
语句;
}
else {
语句;
}

switch语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
switch(){
case 表达式1:
语句1;
break;
case 表达式2:
语句2;
break;
case 表达式3:
语句3;
break;
...
default:
语句n;
break;
}

无条件分支语句 goto

1
2
3
Loop: 语句;
...
goto Loop;

结束语句

break语句

跳出当前循环

continue语句

结束本次循环,执行下一次循环

循环结构

while循环

1
2
3
while (表达式){
语句;
}

do-while循环

1
2
3
do {
语句;
} while(表达式);

for 循环

1
2
3
for(表达式1;表达式2;表达式3){
语句;
}

函数

1
2
3
4
函数类型 函数名(参数){
语句;
return 表达式;
}

数组

一组相同类型元素的集合

定义

type arrayName[arraySize];

1
int arr[10]={0,1,2,3,4,5,6,7,8,9};

访问数组元素

每个元素有一个下标,下标从0开始,数组可以通过下标来进行访问。

获取数组长度

数组长度可以使用 sizeof 运算符来获取数组的长度

1
2
int arr[10]={0,1,2,3,4,5,6,7,8,9};
int length = sizeof(arr)/sizeof(arr[0]);

数组名

在 C 语言中,数组名表示数组的地址,也是数组首元素的地址。

多维数组

二维数组
type arrayName[ x ][ y ];

操作符

算术操作符

1
+ - * / %

移位操作符

1
>> <<

位操作符

1
& ^ |

赋值操作符

1
= += -= *= /= &= ^= |= >>= <<=

单目操作符

1
2
3
4
5
6
7
8
9
10
!       逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度
~ 一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符
(类型) 强制类型转换

关系操作符

1
2
3
4
5
6
>
>=
<
<=
!=
==

逻辑操作符

1
2
&&  逻辑与
|| 逻辑或

条件操作符(三目运算符)

1
exp1?exp2:exp3

逗号表达式

由逗号隔开的一串表达式
从左向右依次计算,整个表达式的结果是最后一个表达式的结果

下标引用、函数调用和结构成员

1
2
3
4
[]
()
. # 结构体对象.成员名
-> # 结构体指针变量->成员名

常见关键字

1
2
3
auto    break   case    char    const   continue    default do double   else
enum exter float for goto if int long register return short
signed sizeof static struct switch typedef union unsigned void volatile while

typedef:类型重命名
extern:声明外部符号
static:修饰变量和函数

  • static修饰局部变量:
    本质上修改了局部变量的存储位置,从栈区变成了静态区,变量的生命周期也发生了改变,和本程序的生命周期一样。
  • static修饰全局变量:
    普通的全局变量是有外部链接属性的,可以在其他源文件中通过extern声明,但是被static修饰的全局变量不能被其他源文件使用,外部链接属性变成了内部链接属性。
  • static修饰函数:
    一个函数也是有外部链接属性的,当函数被static修饰时,其外部链接属性也变成了内部链接属性。

define:定义常量和宏

  • 常量
    1
    #define MAX 100
  • 1
    #define ADD(x+y) ((x)+(y))

register:寄存器

指针

&:取地址
*:解引用
NULL:空指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>

int main(){
int *p = NULL;
printf("%p\n",p);
return 0;
}
>>>
0000000000000000
```
指针是内存单元的地址
32位机器上,指针变量的大小是4字节
64位机器上,指针变量的大小是8字节
```c
#include <stdio.h>

int main(){
int a = 1;
int *p = &a;
char *pp = (char *)p;
printf("%d\n",*pp);
printf("%d\n",*(pp+1));
printf("%d\n",*(pp+2));
printf("%d\n",*(pp+3));
return 0;
}
>>> //小段序存储
1
0
0
0

结构体

结构体是一种用户自定义的可用的数据类型,允许存储不同类型的数据项。

  • 定义结构
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
    struct Stu{
    char name[20];
    int age;
    char gender[10];
    char id[20];
    };

    int main(){
    struct Stu s={"zhangsan",21,"male","1234567"};
    printf("%s %d %s %s\n",s.name,s.age,s.gender,s.id);
    return 0;
    }

enum

枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量。

定义格式

enum 枚举名 {枚举元素1,枚举元素2,……};

1
2
3
4
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};