day01-C语言概述
1.编写helloworld.c
#include <stdio.h>
int main(int argc,char *argv[]){
printf("hello world");
return 0;
}
gcc helloworld.c -o hello
2.Windows下载QT之后,在文件夹的tools下会有一个mingw文件夹,这个文件夹的意思是迷你的gnu for Windows。
3.gcc的编译过程:
(a)预处理(不做语法检查)
在这个阶段,程序做的事情:宏替换、条件编译、头文件包含;
这个阶段生成.i文件。
命令:gcc -E hello.c -o hello.i
(b)编译(做语法检查)
在这个阶段,程序做的事情:将预处理文件编译成汇编文件;
这个阶段生成.s文件。
命令:gcc -S hello.i -o hello.s
(c)汇编
在这个阶段,程序做的事情:将汇编文件生成二进制文件;
这个阶段生成.o文件。
命令:gcc -c hello.s -o hello.o
(d)链接
在这个阶段,程序做的事情:将各个二进制文件+库函数+启动代码-》生成可执行文件。
这个阶段生成可执行文件。
命令:gcc hello.o -o hello
1.png
day02-变量和数据类型
1.寄存器是cpu和内存之间的桥梁,起到了一定的缓和作用;
image.png
image.png
2.数据类型
合理的使用内存空间,提高存储效率。
3.变量的显示声明
extern int a;//显示声明
void test(){
printf("%d",a);
}
int a = 10;
int main(){
test();
}
4.scanf的原理
image.png
day03-运算符
1.限定修饰符
register:定义寄存器变量,频繁使用的变量可以定义寄存器变量,这样编译器会尽量把变量放在寄存器中。
volatile:防止编译器优化; 有时候编译器会做好事,高频繁使用的变量会复制一份到寄存器中;但假如这个变量是高频繁使用的,但是也是时刻变化的,我们就不需要编译器优化。
volatile int num;//强制访问内存,不允许给我放到寄存器里边。
2.字符串常量
单引号取ASCII值,双引号取首元素地址
3.putchar和getchar的区别
getchar():获取键盘的一个字符
char c = '\0';
c = getchar();
printf("%c",c);
image.png
day04-程序结构
1.常用运算符分类
image.png
2.运算符优先级
image.png
image.png
image.png
image.png
运算符优先级:算术运算符>比较运算符>逻辑运算符>赋值运算符
3.数组
数组的定义:
先确定是数组,有几个元素:arr[5]
再确定是什么类型:int a
替换:int arr[5];
4.口诀
标识符与[]结合是数组
标识符与*结合是指针变量
标识符与()结合是函数
day05-数组
1.冒泡排序
image.png
image.png
2.一维数组详解
数组名是字符常量,不可以被赋值。
数组名作为类型代表数组总大小;
数组名作为地址,代表的是数组首元素地址(&arr[0]),(arr+1)跳过一个元素。
数组的地址:&arr,&arr+1将跳过整个数组
3.字符数组
char arr[5] = {'h','e','l','l','o'};//不推荐,不好遍历
char arr[16] = "hello";//以字符串的方式初始化
4.获取带空格的字符串(字符数组的操作)
需求:我们想要从键盘获取带空格的字符串
(a)scanf获取%s字符输入时,遇到空格、回车会结束输入,因为scanf会把空格和回车当做空字符处理,所以scanf不能获取带空格的字符串。
char arr[12] = "";
scanf("%s",arr);//hello world 只能获取到hello
(b)gets()函数读取字符数组(不推荐)
gets()不安全,不会检测空间的长度
char arr[32] = "";
gets(arr);
printf("%s",arr);
(c)fgets()函数(推荐,可以检查字符数组的空间大小)
char arr[32] = "";
fgets(arr,sizeof(arr),stdin);
5.段错误
编译正常,运行错误:操作非法内存。
6.puts和fputs函数
image.png
7. strlen()和sizeof()
strlen 测量字符串的实际长度(遇到'\0'结束统计,不包含'\0')
sizeof()测量的是空间的大小(重要)
image.png
8.设置随机数
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
srand(time(NULL));
int a = 0;
a = rand();
printf("%d",a);
}
9.生成随机字符串
#define N 10
srand(time(NULL));
char arr[N+1] = "";
for(int i = 0;i<N;i++){
arr[i] = rand()%26 + 'a';
}
printf("%s",arr);
10.不用敲回车就获取字符_getch()
day06-函数和指针
1.函数名
函数名代表函数的入口地址
2.指针变量的两个类型
int num = 10;
int *p = #
指针变量自身的类型,把p涂黑,自身是int类型
指针变量指向的类型,把p和离它最近的涂黑,指向的是int类型
3.指针变量所取内容宽度
int num = 10;
int *p = #
printf("%d",*p);//输出10,为什么能输出10呢,它是怎么取的呢?知道num变量的首地址,
//那我取多宽取决于指针变量所指向变量的类型,是int,取4个字节
4.指针变量+1的跨度由指针变量所指向的类型的大小确定
指针变量+1或者+2等等,不是单纯的地址编号+1,+2,而是加一个单位,要乘以单位的字节数。
p+1 等于 p+ 1*指向变量的类型的字节数
image.png
5.void修饰指针变量
image.png
6.const修饰指针变量
image.png
day07-函数
1.字符串指针变量 与 字符数组的区别
char *p = "hello world";//字符串指针变量
char arr[] = "hello world";//字符数组
字符串指针变量的大小是4个字节,它只保存了字符串首地址,而字符串保存在文字常量区,是可读不可写的,通过指针不能修改字符串。而字符串指针变量本质是一个变量,可以+-的,p++指向下一个字符。
而字符数组是在栈区或者全局区开辟的空间保存字符串,可以进行读写。但数组名本质是符号常量,不能+-。
2.主函数传参
image.png
3.字符串操作函数(只要函数以str开头,都是遇到’\0‘结束操作)
(a)strcpy()
char arr[32];
arr = "hello" //错误,数组名是字符常量,不能对其赋值。
strcpy(arr,"hello woeld");
image.png
(b)strncpy()
image.png
(c)strcat() 字符串拼接,两端必须是字符串才能拼接
image.png
(d)strncat()
image.png
(e)sprintf() --- 组包
image.png
image.png
(f)sscanf() --- 解包
image.png
(g)strchr() --- 字符查找
image.png
image.png
image.png
(h)strstr() --- 字符串查找
image.png
image.png
day08-内存管理
1.内存管理
普通局部变量
普通全局变量(所有文件都可以使用,加extern修饰)
静态局部变量(static修饰)
静态全局变量(只能对当前源文件使用)
普通函数和静态函数的区别:静态函数只能当前源文件使用
2.内存分区详解
运行状态下的内存:
image.png
非运行状态下的内存:
image.png
这时候,对比运行时的内存和非运行时的内存,多了一个堆区、栈区和文字常量区,运行的时候才开辟。
对比图:
image.png
文字常量区其实是在全局区里面,只不过根据可读可写的性质把它区分开来。
3.内存操作函数
(a)memset():一般用来清空内存。
image.png
char arr[32] = "hello world";
memset(arr,'a',31);
//清空内存
memset(arr,0,sizeof(arr));
(b)memcpy()
image.png
image.png
(c)如果空间重叠,不要用memcpy,要用memmove
什么是空间重叠、?
image.png
就是不确定拷贝第二个元素时,是拷贝20还是30.
用memmove():
image.png
(d)memcmp():内存比较
image.png
4.堆区操作函数:
(a)malloc()
image.png
malloc函数申请的空间,没有清0,所以需要自己用memset清0;
其次,malloc函数申请的空间的生命周期是整个进程,需要自己free()手动释放;最后malloc返回的地址是void*,需要强制转换后使用。
image.png
5.不要多次释放同一个堆空间。
image.png
6.字符串函数
(a)字符串切割函数
image.png
day09-复合类型
1.结构体定义(3种)
image.png
image.png
定义了结构体,要清0
struct stu lili;
memset(&lili,0,sizeof(lili));
2.为结构体成员赋值
struct stu lilei;
scanf("%d %s %d",&lilei.age,lilei.name,&lilei.money);
3.相同类型结构体变量可以整体赋值
//1
struct stu stu1 = {18,"stu1",20};
struct stu stu2;
stu2.age = stu1.age;
strcpy(stu2.name,stu1.name);
stu2.money = stu1.money;
//2
stu2 = stu1;
//3
memcpy(&stu2,&stu1,sizeof(struct stu1));
4.结构体数组
//定义
struct stu arr[5];
5.结构体嵌套结构体
struct a {
int age;
int money;
}
struct b{
int cc;
struct a str1;
}
6.结构体指针
//定义一个指针变量
struct stu *p = NULL;
7.通过结构体指针变量访问结构体成员
struct stu *p = NULL;
p = &stu1;
//(*p).num (*p).name (*p).age
//p->num p>name p->age
image.png
8.在堆区开辟结构体
image.png
9.共用体、联合体 union
结构体成员拥有独立的空间;
共用体成员共享同一块空间
union的定义和结构体的定义是一样的
image.png
image.png
image.png
image.png
image.png
10.枚举
image.png
image.png
image.png
day10-标准文件
1.【typedef】为已有的类型重新取个别名。
步骤:
先用已有的类型定义一个变量
然后用别名替换变量
最后前边加上typedef
typedef int INT16;
2.文件
分为磁盘文件和设备文件
磁盘文件:
物理上都是二进制文件
逻辑上分为文本文件(字符编码,一个字节,一个意思)和二进制文件(值编码,不确定按几个字节翻译,需要特定的应用取打开)













网友评论