
目录
1、什么是C语言
C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。其中Clang是苹果公司所采用的,GCC是Linux系统,我们平常使用的VS集成开发环境就是采用MSVC的。
2、第一个C语言程序
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
首先说明一下这个main函数,main函数是一个程序的入口,而且一个工程(可能有多个.c文件)也只能有一个main函数。
3、数据类型
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数
【注】C语言里没有字符串类型
下面打印各个数据类型的长度:
#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
printf("%d\n", sizeof(long double));//8
return 0;
}
【注】这里的长度单位为字节。
计算机常见的单位:bit,byte,KB,MB,GB,TB,PB,其换算关系如下图:
![]()
4、变量,常量
4.1 定义变量方法
//类型名 变量名 = 所赋的值
int age = 18;
float weight = 60.0f;
char ch = 't';
4.2 变量的命名
- 只能由字母(包括大写和小写)、数字和下划线( _ )组成。
不能以数字开头。- 变量名中区分大小写的。
变量名 不能使用关键字 。
4.3 变量的分类
- 局部变量
- 全局变量
#include <stdio.h>
int tt = 2020;//全局变量
int main()
{
int ff = 2021;//局部变量
//下面定义的tt会不会有问题?
int tt = 2022;//局部变量
printf("tt = %d\n", tt);
return 0;
}
【注】 当局部变量和全局变量同名的时候, 局部变量优先使用 。
4.4 变量的使用
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0;
}
【注】scanf 和 printf
- scanf:按照指定的格式,输入数据
- printf :按照指定的格式,输出数据
【问题】指定格式有哪些呢?
//%c - 字符
//%s - 字符串
//%d - 整型
//%f - float浮点数
//%lf - double 浮点数
//%p - 打印地址的
//%x - 以16进制的形式打印【注】getchar() 和 putchar()
- getchar() -输入一个字符(当输入错误或者结束后会返回EOF)
- putchar() -输出一个字符
4.5 变量的作用域和生命周期
4.5.1 作用域
- 局部变量的作用域是该变量所在的局部范围。
- 全局变量的作用域是整个工程。
4.5.2 生命周期
- 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
- 全局变量的生命周期是:整个程序的生命周期。
4.6 常量
- 字面常量
- const修饰的常变量
- #define 定义的标识符常量
- 枚举常量
#include <stdio.h>
//举例
enum Sex
{
MALE,
FEMALE,
SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
//字面常量演示
3.14;//字面常量
1000;//字面常量
//const 修饰的常变量
const float pai = 3.14f; //这里的pai是const修饰的常变量
pai = 5.14;//是不能直接修改的!
//#define的标识符常量 演示
#define MAX 100
printf("max = %d\n", MAX);
//枚举常量演示
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
//注:枚举常量的默认是从0开始,依次向下递增1的
return 0;
}
【注】const修饰的是常变量,本质还是变量,可以用数组来检测,因为C99之前没有引入变长数组的概念。
#include <stdio.h> int main() { int n = 5; int arr[n]={1,2,3,4,5}; printf("%d", arr[0]); return 0; //编译失败,应输入常量表达式 }
5、字符串+转义字符+注释
5.1 字符串
由双引号引起来的一串字符称为字符串字面值,或者简称字符串。
【注】 字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。![]()
打印出这两个数组:
因为printf打印'\0'前面的内容,而ch1的‘\0’的位置是随机,所以会打印出乱码,而ch2是字符串,字符串以'\0'结尾,所以之间打印。
#include <stdio.h>
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{
char arr1[] = "ttt";
char arr2[] = {'t', 't', 't'};
char arr3[] = {'t', 't', 't', '\0'};
printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);
return 0;
}
5.2 转义字符
转义字符 释义 \? 书写连续个问号时,防止被转化为三字母词 \' 用于表示字符常量' \" 用于表示字符串内部的双引号 \\ 用于表示一个反斜杠 \a 警告,发出蜂鸣 \b 退格符 \f 进纸符 \n 换行 \r 回车 \t 水平制表符 \v 垂直制表符 \ddd ddd 表示 1~3 个八进制的数字。\xdd dd 表示 2 个十六进制数字。
#include <stdio.h>
int main()
{
printf("%d\n", strlen("abcdef"));
// \62被解析成一个转义字符
printf("%d\n", strlen("c:\test\628\test.c"));
return 0;
}
5.3 注释
- C语言注释风格:/*xxxxxxxx*/
- C++语言注释风格://xxxxx (可以注释一行也可以注释多行)
6、选择语句
#include <stdio.h>
int main()
{
int code = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &code);
if(code == 1)
{
printf("坚持下去\n");
}
else
{
printf("半途而废\n");
}
return 0;
}
7、循环语句
while(举例)
for (后期整理)
do while(后期整理)
//while循环的实例
#include <stdio.h>
int main()
{
printf("好好学习吧!\n");
int score = 0;
while(score<=90)
{
score++;
printf("我要继续努力\n");
}
if(score>90)
printf("好成绩!\n");
return 0;
}
8、函数
特点:简化代码,实现代码的复用
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0;
}
上述代码,写成函数如下:
#include <stdio.h>
int Add(int x, int y)
{
return (x+y);
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = Add(num1, num2);
printf("sum = %d\n", sum);
return 0;
}
9、数组
定义:一组相同元素的集合
9.1 数组定义
int arr[5] = {1,2,3,4,5};
9.2 数组的下标
数组的每个元素都有一个下标,下标是从 0 开始的。 数组可以通过下标来访问的。
int arr[5] = {1,2,3};
//下标范围 0~4
9.3 数组的使用
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(i=0; i<10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
10、操作符
- 算术操作符:+ - * /
- 移位操作符:>> <<
- 位操作符:& ^ |
- 赋值操作符:= += -= *= /= &= ^= |= >>= <<=
- 单目操作符:! - + & sizeof ~ -- ++ * (类型)
- 关系操作符:> >= < <= != ==
- 逻辑操作符: && ||
- 条件操作符:exp1 ? exp2 : exp3
- 逗号操作符:exp1, exp2, exp3, …expN
- 下标引用,函数调用和结构成员: [ ] ( ) . ->
11、关键字(初识阶段 了解即可)
- typedef
- static

11.1 关键字typedef
typedef:类型的重命名
//将unsigned int 重命名为tt, 所以tt也是一个类型名
typedef unsigned int tt;
int main()
{
//观察num1和num2,这两个变量的类型是一样的
unsigned int num1 = 0;
tt num2 = 0;
return 0;
}
11.2 关键字static
static可以 修饰变量和函数的:1. 修饰局部变量 - 称为静态局部变量2. 修饰全局变量 - 称为静态全局变量3. 修饰函数 - 称为静态函数
11.2.1 修饰局部变量
//代码1
#include <stdio.h>
void test()
{
int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
//代码2
#include <stdio.h>
void test()
{
//static修饰局部变量
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
【总结】
1、static 修饰局部变量改变了变量的生命周期2、让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
11.2.2 修饰全局变量
//代码1
//add.c
int g_val = 2018;
//test.c
int main()
{
printf("%d\n", g_val);
return 0;
}
//编译正常
//代码2
//add.c
static int g_val = 2018;
//test.c
int main()
{
printf("%d\n", g_val);
return 0;
}
//编译错误
【总结】一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。
11.2.3 修饰函数
//代码1
//add.c
int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//编译正常
//代码2
//add.c
static int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//编译错误
【总结】一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
12、#define定义常量和宏
//define定义标识符常量
#define MAX 1000
//define定义宏
#define ADD(x, y) ((x)+(y))
#include <stdio.h>
int main()
{
int sum = ADD(2, 3);
printf("sum = %d\n", sum);
sum = 10*ADD(2, 3);
printf("sum = %d\n", sum);
return 0;
}
13、指针
- 内存
- 指针变量的大小
13.1 内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。 内存是计算机上的一种存储空间,程序运行时会载入内存,程序中如果有数据需要存储也会申请内存空间。
【注】
1. 指针就是地址
2. 口头语中指针一般指的是指针变量
变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。取出变量地址如下:#include <stdio.h> int main() { int num = 10; # //取出num的地址 //注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址) printf("%p\n", &num);//打印地址,%p是以地址的形式打印 return 0; }
那么地址是如何存储的呢?//需要定义指针变量
int num = 10; int *p;//p为一个整形指针变量 p = #
举例(1):
int main() { int a = 1;//向内存申请4个字节 int * pa = &a; *pa = 20;//解引用操作 - 作用就是通过pa中的地址,找到a, *pa就是a //a = 20; printf("%d\n", a); //以下两个是等价的,都打印a的第一个字节地址 printf("%p\n", &a); printf("%p\n", pa); return 0; }
【注】
1. pa是一个变量,这个变量是用来存放地址的,而地址又叫指针
2. 所以在C语言中把pa叫指针变量(指针变量是存放指针的变量)
3.& 取地址操作符
4. printf("%p\n", &a);而&a 取出的是a所占内存的4个字节中第一个字节的地址
举例(2):
#include <stdio.h> int main() { char ch = 'w'; char* pc = &ch; *pc = 'q'; printf("%c\n", ch); return 0; }
13.2 指针变量的大小
int main() { char* pc; int* pi; printf("%zd\n", sizeof(pc));//这里格式的zd是根据当前编译器VS运行提醒时改的 printf("%zd\n", sizeof(pi)); //x86是32位环境 //x64是64位环境 return 0; }
14、结构体
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
//定义一个学生类型 struct Stu { char name[20]; char sex[5]; int age; };void Print(struct Stu* ps) { //printf("%s %s %d\n", (*ps).name, (*ps).sex, (*ps).age); //-> //结构体的指针->成员名 printf("%s %s %d\n", ps->name, ps->sex, ps->age); } int main() { int num = 0; struct Stu s = {"zhangsan", "男", 20}; struct Stu s2 = { "如花", "女", 18 }; Print(&s); //结构体变量.成员名 //printf("%s\n", s2.name); //printf("%s\n", s2.sex); //printf("%d\n", s2.age); return 0; }

