目录
1.字符串不能直接修改,需要使用指针/strcpy函数才能修改
2.当使用函数/结构体时,需要从上往下定义,因为编译时,会从上往下编译
static 修饰的变量 会本地化 其他文件无法直接调用该变量/函数
(2)返回指定数据 如果返回0 main()函数正常结束 返回-1 异常结束
8.#include 会进行文本的替换 将stdio.h头文件中的内容粘贴到include位置
(2) 可以从函数中返回指针,但是不要返回指向局部变量的指针,因为该变量的内存在函数返回后会被释放,此类函数又被称为指针函数
(2)数组元素下标访问的本质就是首元素地址做指针计算 然后解引用
(3)数组名是个指针常量,不能通过再次赋值令其指向其他的数据
11.常量指针:指针变量保存的地址可以改变,指向的内存值不能修改
(1)getcahr()、putchar() ctrl+Z停止(EOF) ctrl+D(EOF)-->Linux操作系统
(3)char*是字符串吗?字符串可以表达为char* 但是char*不一定是字符串 只有当所指的字符数组的结尾有0,才能说是指向字符串
(3)静态本地变量只会在第一次进入这个函数时进行初始化,之后进入函数时会保持上次离开时的值
(4)静态本地变量时间上是特殊的全局变量,二者位于相同的内存区域
1.结构体的声明与变量的声明一样,如果声明在函数内部,则是局部结构体,声明在函数之外,则是全局结构体
注意:和数组不同,结构变量的名字并不是结构变量的地址,需要用&才能取到地址
(1) 结构中每个成员的起始地址,必须是其自身大小的整数倍,超过4字节的按4字节算(32位系统),为此,可能要在中间填充若干字节
第一阶段![](https://img-blog.csdnimg.cn/2631ca09515348a0a1ece667ee42e955.png)
快捷键:
1.ctrl + d -->复制一行到下面
2.ctrl + delete-->删除右边的内容
3.shift+delete-->快速删除一行
4.ctrl + k + c-->添加注释
ctrl + k + u-->取消注释
注意:
1.字符串不能直接修改,需要使用指针/strcpy函数才能修改
2.当使用函数/结构体时,需要从上往下定义,因为编译时,会从上往下编译
一、基本概念
C语言核心:一堆变量(包括数组)+ 一堆函数 前者负责分配内存,后者负责操作访问内存
1.C语言是面向过程的语言
2.C语言绝大多数记录在.c的源文件中 以.h结尾的是头文件
3.stray --->这个报错是提示有中文标点
十三、多文件编程
1.出现原因 --- 将一个.c文件分成多个.c文件
(1)main()函数中的代码太长了,适合分成几个函数
(2)源代码文件太长,适合分成几个文件
(3)两个独立的源代码文件不能编译成可执行的程序
一个.c文件是一个编译单元,编译器每次编译只会处理一个编译单元,最后链接在一起
#include 编译预处理指令,在编译之前就处理的,它把那个文件的全部文本内容原封不动地插入到它所在地地方,所以也不一定要在.c文件地最前面#include
3.头文件卫士
#include -文件包含 将后面的文件包含到当前文件中
eg:#include <stdio.h> 将stdio.h拷贝到当前位置 如果不使用输入输出函数,可以不包含
#include<stdio.h> Linux系统会在/user/include下寻找stdio.h,再拷贝到当前位置
#include "stdio.h" 先在当前目录找,再去/user/include下找 语法上可以 但是会增加运算时间
自定义的头文件 使用"" 引用比较好, 但是系统头文件,最好使用<>
4.main()函数
C语言程序里必须包含一个main()函数,有且只有一个main函数 程序从main开始,从上往下执行
以;号结尾
5.Linux命令操作 .c文件
保存退出:
gcc hello.c -->a.out -->./a.out
6.gcc编译器:
计算机只能看懂二进制代码
gcc编译器,人看明白代码,再编译成二进制,给计算机看
过程:gcc hello.c 得到 a.out a - application - 应用 out -- output -输出
a.out --编译程序所得到的输出应用程序--可执行--二进制--计算机可以看明白
hello.c -->gcc -->a.out 这个过程就是编译
弊端 :
gcc xx.c -> a.out
默认得到a.out - 目的性及其不明确
gcc hello.c -> a.out
gcc world.c -> a.out
后面的a.out将前面的a.out覆盖
最后将.c文件编译成.o文件(二进制文件),计算机才能理解
连接各路大神的文件 --》变成一个.o文件给计算机
该过程称为链接
|xxxxxxxxxxxxxxxxx|.o + |yyyyyyyyyyyyyyyy|.o = 二进制可执行程序
自己写的代码 各种大神代码
gcc hello.o -o hello
此时可执行程序名字为hello
二、变量
注意:
局部变量需要初始化,否则会报错 全局变量可以不用初始化(会有默认值)
1.常量
(1)
(2)
(3)
2.局部、全局变量
局部变量:定义在函数中的变量 {}
全局变量:定义在函数外的变量 全局的
(1)在执行过程中,值可以发生改变的量
(2)定义变量的语法:数据类型 变量名 = 初始值;
int a = 10 ;
int 4个字节
(3)Windows 驼峰命名 Linux 下划线命名
int stuAge = 10 ;
(4)变量的输入输出
printf() 输出 print format
scanf()输入 scan format
没有对变量初始化,变量的值是随机数
3.静态变量(全局、局部)
static 修饰的变量 会本地化 其他文件无法直接调用该变量/函数
三、 数据类型
unsigned修饰 无符号 只有非负数
1.int
2.short
3.long
4.long long
8位系统 32 64
int 2 4 4
long 4 4 8
long的字节数>= int 类型 不同位数的计算机 字节数不同
输出内存大小 ---》 %lu 或者 %u
5.char
-- 用单引号括起来表示 eg:'A'
本质内存存储的是一个整数 即字符的ASCII码
A --- 65 a -- 97
%c
字符串 %s
int a = -20 %d
signed int a = -20
unsigned int a = 20 --》unsigned 只有 0 和 正数 %u
short int --> half int %hd
unsigned short --> %hd
long int --> %ld
6.float
7.double
四、进制转换
四、 流程控制:
1.运算符的优先级
单目高于双目 单目:--a 三目 a>b?a:b
乘除高于加减
算数高于关系高于逻辑
条件高于赋值高于逗号
2.类型转换
(1)隐式转换
gcc自动转换 小转大,整转浮,有转无(unsigned 无符号类型)
五、 循环:
六、关键字
1.void ---不需要参数
2.int --整型返回值
3.return
(1)结束当前函数
(2)返回指定数据 如果返回0 main()函数正常结束 返回-1 异常结束
4.unsigned 无符号 没有正负
5.goto 跳转到标号处,执行代码
破坏了三大结构:顺序结构、分支结构、循环结构
6.break 结束循环
7.continue 中断本次循环,继续下一次循环
8.#include <stdio.h> 会进行文本的替换 将stdio.h头文件中的内容粘贴到include位置
头文件与头文件卫士:
头文件卫士的功能:防止重定义
#ifndef _COMMON_H
#define _COMMON_H
中间就是头文件要包含的内容
#endif // _COMMON_H
9.typedef关键字:给数据类型起别名
方便struct 结构体的使用 进行定义变量
七、 函数
目的:减少开发工作量,提高代码可维护性
一、自定义函数
返回值类型 函数名(形参表){
函数体 ;
}
extern 连接外部函数 ---变量的声明
函数调用:(1) 值传递 (2) 地址传递
二、 库函数
1.printf() 将双引号中的内容输出到显示器上
2.main函数
当main函数结束 程序结束
地址:
1.
3.首地址:
存储单元的第一个字节的地址称为首地址
任何程序在访问内存之前,需要先分配地址
位运算:先转为二进制,在计算
1.按位与&运算 两位都是1才是1
2.位或(|) 两位都是 0 才是 0
3.异或 ^ 相同为 0 不同为1
4.位反~ 1 变成 0 0 变成 1
5.左移位 << 有符号数 右补 0
无符号位 右补 0
十、字符串常量
注意:
1.返回本地变量的地址是危险的(因为函数生命周期结束时,局部变量的内存会被释放),返回全局变量/静态本地变量的地址是安全的
返回在函数内malloc的内存是安全的,但是任意造成问题
最好的做法是返回传入的指针
1.概念
C语言的字符串是以字符数组的形态存在,不能用运算符对字符串做运算
可以用数组方式遍历字符串
用字符'\0'作为结束符(ASCII码也是0)
字符串 是常量 只能读 不能写
2.C语言存储字符串的方式
pstr指针可以修改指向地址 但是指向的字符串值 无法修改 因为字符串在常量池中
3.字符串输出:
4.字符串表示方式:
(1) 字符指针方式
(2) 字符数组方式
数组名就i是字符串首地址
可以用字面值初始化,也可以用{}初始化,用{}初始化,需要\0标注结束,否则是一个数组
可以任意修改
可以使用字符数组来存储字符串,但是字符数组不是字符串 是数组
(3)字符串的输入和输出
5.字符串常用函数:
C语言字符串常用函数总结(持续更新)_c语言字符串函数_文刀宝宝的博客-CSDN博客
(1)getcahr()、putchar() ctrl+Z停止(EOF) ctrl+D(EOF)-->Linux操作系统
(2)String.h 头文件
(2)strlen-->
返回字符串长度
(3)strcmp 比较两个字符串 返回1、 0、-1
(4)strcpy()函数 拷贝字符串
char* strcpy(char* restrict dst ,const char* restrict src); // 第一个是目的地址 第二个是源地址
将src拷贝到dst上,C99 src与dst不重叠 返回的地址是dst地址
(5)字符串中找字符
char* strchr(const char* s ,int c ) -->从左往右找
char* strrchr(const char* s ,int c )--->从右往左找
返回NULL表示没有找到
6.用指针还是数组表达字符串?
(1)数组:这个字符串就在这,作为本地变量空间自动被回收
(2)指针:这个字符串不知道在哪,处理参数、动态分配空间
(3)char*是字符串吗?
字符串可以表达为char* 但是char*不一定是字符串 只有当所指的字符数组的结尾有0,才能说是指向字符串
十一、define定义宏
1.概念
#开头的就是编译预处理指令
它们不是C语言的成分,但是C语言程序离不开他们
#define用来定义一个宏
2.特点
在编译之前会进行预处理 傻傻地替换
在C语言的编译器开始编译之前,编译预处理程序(cpp),会把程序中的名字换成值
完全的文本替换
3.定义方式:
#define <名字> <值>
名字必须是一个单词,值可以是任何东西
4.带参数的宏
带参宏的原则:
十二、static静态变量
1、特点、
(1)static修饰的变量-->静态本地变量
(2) 当函数离开时,静态本地变量会继续存在并且保持其值
(3)静态本地变量只会在第一次进入这个函数时进行初始化,之后进入函数时会保持上次离开时的值
(4)静态本地变量时间上是特殊的全局变量,二者位于相同的内存区域
十四、结构体---结构类型-->复合类型
1.结构体的声明与变量的声明一样,如果声明在函数内部,则是局部结构体,声明在函数之外,则是全局结构体
2.三种结构体声明方式:
3.结构变量
4.结构体访问成员属性的方式
(1)使用 . 来访问
(2)使用->来访问
5.结构体的运算:
注意:和数组不同,结构变量的名字并不是结构变量的地址,需要用&才能取到地址
6.指针变量访问结构体
语法:指针变量 -> 成员名
7.结构体最常用的写法 -- typedef 起别名
8.标记初始化
9.结构体数组
10.结构体和函数
(1)结构体作为函数参数 --->建议使用指针 效率更高
(2)结构体作为函数返回值
11.结构体嵌套结构体 包含不同类型的成员:
注意:结构体变量/结构体指针 只能访问自己的成员
12.联合
(1) 结构中每个成员的起始地址,必须是其自身大小的整数倍,超过4字节的按4字节算(32位系统),为此,可能要在中间填充若干字节
如:4字节对齐
如:8字节对齐
(2) 联合的特点
联合的所有成员从同一个地址开始,共享同一块内存区域
联合变量的字节数就是最大成员的字节数
利用联合可以将同一份数据解释为不同的类型
(3)联合体判断电脑的存储方式 -- 能节省内存
大端模式 ---- 网络传输、交换机。。。
数据的高数位放在低地址上
小端模式---- 笔记本、ipad
数据的低数位放在低地址上
判断电脑是大端模式还是小端模式?
十五、枚举
1枚举的概念:
枚举是一个整型常量的列表,每个枚举值都是一个符号常量,默认是从0开始,可以通过赋值改变
没有赋值的枚举 = 上一个枚举值+1
语法格式:
enum 枚举类型名称 {枚举值列表};
例如: enum COLOR {RED,GREEN,BLUE};
结果:
RED = 0 , GREEN= 1 ,BLUE = 2 //就是给 0,1,2取别名
2.与宏的区别:
宏没有数据类型--》文本的替换
枚举--》有数据类型 int类型数据
3.对枚举赋值
举例:enum COLOR {RED,GREEN=200 ,BLUE};
结果: RED = 0 ;GREEN = 200 , BLUE = 201
4.枚举的意义
提高代码的可读性
十六、指针函数与函数指针