美文网首页
01-C开发基础实战

01-C开发基础实战

作者: 每天写点东西呗 | 来源:发表于2020-05-03 01:06 被阅读0次

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 = &num;

指针变量自身的类型,把p涂黑,自身是int类型
指针变量指向的类型,把p和离它最近的
涂黑,指向的是int类型

3.指针变量所取内容宽度
int num = 10;
int *p = &num;
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.文件

分为磁盘文件和设备文件
磁盘文件:
物理上都是二进制文件
逻辑上分为文本文件(字符编码,一个字节,一个意思)和二进制文件(值编码,不确定按几个字节翻译,需要特定的应用取打开)

相关文章

网友评论

      本文标题:01-C开发基础实战

      本文链接:https://www.haomeiwen.com/subject/dwdlghtx.html