C
常量的定义:
1、const 数据类型 常量名
2、【宏定义】#deifne 常量名 值
注意:
1、通过#define 定义的常量 是根据值来匹配数据类型的
2、const 修饰的常量是不安全 可以通过指针来修改
注意:在程序中没有办法表示一个二进制数
%d 将数据按照十进制输出
%o将数据按照八进制输出
%x将数据按照十六进制小写输出
%X将数据按照十六进制大写输出
%u 10进制无符号数 l ll c
原码、反码、补码
一个有符号的整型数据可以分为两部分一部分是符号位、一部分是数字位
无符号数据类型只包含数字位部分
signed int a= 1986(有符号标识 signed可以不用写)
二进制:11111000010
1986原码:0000 0000 0000 0000 0000 0111 1100 0010
-1986原码:1000 0000 0000 0000 0000 0111 1100 0010
1986反码: 0000 0000 0000 0000 0000 0111 1100 0010
-1986反码:1111 1111 1111 1111 1111 1000 0011 1101
1986补码: 0000 0000 0000 0000 0000 0111 1100 0010
-1986补码:1111 1111 1111 1111 1111 1000 0011 1110
负数反码->补码+1
溢出:在数据进行操作的时候会导致超出数据类型大小,会向前位进1,多于原始数据类型大小,会被系统自动舍弃 保留从后面开始数据类型大小的位数
无符号整型取值:0-4294967295(2^32-1)
无符号的字符型:0-255
sizeof()
求出数据类型在内存中占的大小(BYTE)
int value =sizeof(变量名);
int value = sizeof(数据类型) / sizeof 数据类型
注意:根据32位操作系统获取的数据类型大小
char(字符型)【1】<short(短整型)【2】
<=int(整型)【4】|float (单精度浮点型)【4】|long(长整型)【4】
<long long(长长整型)【8】|double(双精度浮点型)【8】
输出和输入:
输出字符的两种方式:
1、printf(“%c”,变量)
2、putchar(字符)
输入字符的两种方式:
1、scanf(”%c”,&b变量)
2、变量=getchar()
字符型:
char 用于存储一个单一的字符
在格式化输入printf(“%c”,变量)通过占位符%c来接收的
每一个char类型都对应在ASCII中有具体的值
转义字符:计算机会使用一些字符来完成程序设计,如果在编程中想使用这些字符的本意,需要通过【\】来转义 \ddd \xhh
注意:想在控制台中输出% 需要使用【%%】
浮点型:
float 用于存储带有小数的数据
在格式化输入printf(“%f”,变量)通过占位符%f来接收的
double 用于存储带有小数的数据 数据长度比float更长
注意:因为将小数转化为二进制时不是一个精确的值,所以浮点型都会有数据偏差
求出数组元素个数:
int (size_t) unsigned int 个数 = sizeof(数组名)/sizeof(数组元素 | 数组数据类型)
求行数:sizeof(数组名)/sizeof(数组名[0]);
求列数:sizeof(数组名[0])/sizeoef(数组名[0][0])
#pragma once 头文件只包含一次
#ifndef SOMEFILE_H
#define SOMEFILE_H
#endif___SOMEFILE_H__
头文件作用:
1. 函数,变量的声明
extern int myMax(int a, int b);
1. 系统库的调用
指针的定义和使用:
1、指针:是一种数据类型 指针变量也是一种变量
2、指针格式: 对应的数据类型 * p:指针类型变量 用来指向一个变量的地址
3、通过指针修改变量的值
p = 200;
4、指针类型在内存中的大小 : 在32位操作系统中所有指针大小都是4个字节大小
打印指针内存大小格式: sizeof(int *) || sizeof(p)
5、内存按照 unsignned int 为每个一个内存分配编号
6、讲解:
①定义变量 int a =10; 数值10 存在内存 为a开辟的空间中 a的地址为0xff00
②定义指针 int * p = &a 指针变量p 在内存中存贮的是 a的地址 0xff00,指针变量p 在内存中的大小在32位系统中都是4个字节大小
③p = 200 通过操作指针变量p 所存储的 a的地址 来改变a的值
④指针p 有一个自己的内存地址 指针p地址 与 定义变量a的地址 0xff00不同
野指针、空指针与 万能指针
1、野指针:野指针是指向一个未知的内存空间,可能在读写的时候出现错误。
0-255都是系统保留的 不可以读,不可以写
2、空指针 没有指向任何的地址(其指向0的地址)
空制指针就是指向内存编号为零的空间,操作该内存空间会报错,一般情况空指针用于程序条件判断
3、万能指针:void * 指针可以指向任意变量的内存空间
int a=1;void * p = &a; (int *)p=100;printf(“”%d\n”,(int )p);
int arr[10] = {0};void * p = &a; *((int *)p+0)=100;((int *)p+1)=200;
const修饰指针
1.通过指针修改const修饰的常量
const int a = 10;
int *p += &a;
*p = 100;
a =100;
可以通过1级指针修改一个常量的值
2.const修饰指针类型 int * 不能改变指针变量指向的内存地址的值 但是可以改变指针指向的地址
const int *p = &a
p=&b
*p = 100
可以改变指针指向的地址
3.const修饰指针变量 能改变指针指向地址的值,但不能改变指针指向的地址
int * const p = &a;
*p = 100;
p=&b
可以修改指针指向地址的值
4.const修饰指针类型修饰指针变量 不能改变指针指向的的值 也不能改变指针指向的地址
const int * const *p = &a;
*p =100;
p = &b;
指针和数组、指针运算:
1、数组名是数组的首地址,这是一个常量
2、指向数组的指针
格式int arr [10] = { 0 } ;
int * p = arr;
当操作指针的时候 间接操作了数组 arr[i] = p[i];
3、指针的降级操作 ,取当前地址的值:p[5]、p
4、对指向数组的指针进行加减操作,可能会导致数组下标越界 。
5、相同的类型的指针相减 结果是两个指针相差的长度
区别:数组名通过sizeof可以求出数组大小,指针只包含数组的首地址信息
课后练习题:输入格式:【 空格 你好 空格 】输出格式为【你好】
指针数组
1、存储char *类型的地址数组
char * arr[] ={“hello”,”world”,”niao”,”baobei”};
2、指针数组,它是数组,数组的每个元素都是指针类型。
多级指针:
1、如果二级指针前面加一个 代表一级指针的值
2、二级指针前面加** 代表指针指向一级指针指向地址的值,加降维度
3、如果n级指针在前面加n个就是指针指向一级指针指向地址的值
函数参数中如果有数组 都会转化为指针 sizeof(数据类型) 所以求出来的值不作为循环的值使用, 在传递数组时需要加上数组的个数
两种方式求出字符串长度 (图4)
①利用函数strlen();
②通过while循环遍历字符串直至遇到字符串结果\0结束,遍历中定义一个整型变量i,进行记录循环次数,同时也是字符串长度;
v指针作为返回值
①字符串数组 存放在栈区
②字符串常量 会在程序运行时 放在常量区 不能被修改 可以读取 程序结束时会被销毁
全局和局部变量
1、局部变量作用域:从创建到所在函数结束
2、如果在函数中 函数创建顺序从右往左,打印变量地址结果:从高向低增长
3、全局变量:作用在整个项目中,使用的前提是需要在使用的文件中进行声明
4、声明变量就是可以使用这个变量,声明不会分配内存空间 extern
注意:如果在函数外部是全局变量 在函数外面是局部变量
如果全局变量写在主函数下面,想使用需要声明
静态全局和局部变量
1、静态局部变量static和局部变量 可以被赋值
2、静态局部变量和局部变量区别: 只能被初始化一次,可以被多次赋值
全局静态变量只能作用于当前文件中,不能在全部文件中使用
3、auto区分局部变量和全局变量 注意:定义的时候自带声明,但只能在使用它的函数之上
内存布局
- 程序没有加载到内存前,可执行程序内部已经分好3段信息,分别为代码区(text)、初始化数据区(data)和未初始化数据区(bss)
size testfile - malloc在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域
格式:malloc(分配大小) char* p=(char*)malloc(1);
注意:创建完的堆空间,在使用完之后不释放,会占用内存空间 free(p);
释放空间流程 先判断在释放 释放完成 变成空指针
strcopy操作对空间,会将拷贝的字符串全都放到堆空间中,这样就会导致超出堆空间 使程序出现错误;
重置 memset 参数:目标 值 字节大小
注意:①memset可以重置内存区域的值 初始化值为0 但在char类型中可以初始化相同的值
②memset 重置内存的值,前提是重置区域可读可写
memcpy拷贝:拷贝src所指的内存内容的前n个字节到dest所值的内存地址上
①可以从栈区拷贝到堆区 也可以从堆区拷贝到栈区注意:源地址与目标地址不能发生重叠
strcpy 与mencpy的不同
①函数参数不同
②strcpy拷贝字符串 memcpy 可以拷贝一块内存
③strcpy与memcpy拷贝结束标志不同 (“\0”) 与个数
memmove()功能用法和memcpy()一样,
区别在于:dest和src所指的内存空间重叠时,memmove()仍然能处理,不过执行效率比memcpy()低些。
memcmp:比较s1和s2所指向内存区域的前n个字节,类型不同,但在内存中存的ASCII码相同,所以比较的内容相同
栈遵从规则:后进先出 先进后出
stdio.h
string.h
gets() 输入允许有空格,注意缓冲区溢出
scanf()输入不允许有空格,注意缓冲区溢出scanf(“%[^\n]”,arr);scanf(“%2d %d”,&a,&b);%,%[ – ]屏蔽内容
print()
fgets(指针,大小,输入流) 从stream指定的文件内读入字符,保存到指定的内存,可stdin键盘输入,>加\n\0 ,=加\0
puts() 输出一个字符串并换行
fputs() 将str指定的字符串写入到stream指定的文件中,结束符\0不写入
strlen() 字符串长度,不能处理字符数组
strcpy() 拷贝,\0也一同拷贝
strncpy()拷贝前n个字符
strcat()追加到尾部\0也一同追加
strncat()追加前n个到尾部\0也一同追加
strcmp() 按ASCII码比较大小
strncmp()按ASCII码比较前N个大小
sprintf()根据参数将源字符串来转换并格式化数据
sscanf()根据参数将源字符串来转换并格式化数据
sscanf与scanf一样需要在程序开始加入警告
strchar(字符串,‘字符’) // 失败返回空的值(UNLL)
注意 :①找汉字时格式 “ 汉字 ”,是双引号非单引号
② 字符使用单引号引起来
strstr(源字符串,“匹配字符串”)匹配字符串使用双引号引起来
strtok(目标字符串,“目标字符串中所包含的字符”)
① 将切割点用\0表示,切完之后会破坏原先字符串样式
②当连续出现多个分割字符时只替换第一个为\0
atoi 转整形 /atof转 双精度 /atol转long类型 :
跳过前面的空格字符,直到遇到数字或正负号才开始做转换,而遇到非数字或字符串结束符(‘\0’)才结束转换
定义结构体变量:
①struct 结构体名称 结构体变量名
②结构体变量名.机构体成员列表 = 值
注:如果是字符串类型 需要使用strcpy;
赋值方式
按照结构顺序赋值,.加成员名赋值,结构体变量名.成员名赋值,直接在结构体后面定义变量名;,
结构体需要根据数据类型进行内存对齐;
所有数据类型的大小在内存中存储的资质一定是他的类型的倍数
写结构体位置根据数据类型从大到小的方式书写
有利于节省空间,不利于输出格式的阅读;利于输出格式的阅读,不利于节省空间;需要根据当时权重进行排列
联合union是一个能在同一个存储空间存储不同类型数据的类型;
格式:union 共用体名称 成员列表 共用体变量名
枚举
enum 将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。
typedef
作用:为一种数据类型(基本类型或自定义数据类型)定义一个新名字,不能创建新类型
结构体在.h头文件中定义,在当前它文件中引用其头文件可直接使用
文件操作
1、文件分类:
①文本文件(例:记事本)、
②二进制文件(例:视频文件),优点:所占内存较小
操作文件地址的两种方式:①相对路径 ②绝对路径
2、文件打开与关闭
①格式:FILE *fp = fopen(“路径”,“r”) 做判断 文件是否为空;
打开失败情况:
①找不到文件②没有权限 ③程序打开文件超出上线;
关闭文件操做:fclose(fp);
3、按字符写文件
格式:fputc(‘A’,fp)
4、按字符读取文件
格式:fgetc( fp) 读取整篇文件使用EOF作为判断结束标志
3、按行符写文件
格式:fputcs(‘A’,fp) \0换行
4、按行符读取文件
格式:fgetcs(buf,size, fp)
打开模式:
w:文件不存在会创建一个新文件,如果有文件则清空文件原始内容;
r以只读形式打开,不会创建新文件 如果文件不会存在会报错
a以追加的方式打开文件 文件不存在则创建文件 有文件则在文件结尾追加文件
feof判断文件流是否到结尾, eof判断字符是否到结尾
格式:feof(fp)
格式化文件
①写文件fprintf()
②读文件fscanf()
二进制读写:
fwrite写入
fread读取
fseek() 移动光标为位置,参数(文件流 ,移动字节,模式) 模式: SEEK_SET 以文件开头
SEEK_CUR 以文件当前位置 SEEK_END 以文件结尾
ftell (文件流) 获取光标当前为位置 返回值是long类型 -1代表失败
rewind(文件流 ) 重置光标到文件起始位置
文件删除remove
重命名 移动剪切 rename
文件缓冲区更新flush(文件流)
stdlib.h
system() 调用其它程序
windows.h
WinExec(“calc”,SW_HIDE) 系统调用时默认隐藏黑窗口
time.h
1、添加头文件 time.h stdlib.h
2、添加随机数种子 srand((unsigend int )time(NULL));
3、生成随机数 rand() %
生成随机数 int num=rand()%100+1;1-100
VS 汇编
int a,b,c;
__asm{
mov a,3
mov b,4
mov eax,a
add eax,b
mov c,eax
}
QT
Ctrl+i自动格式化代码
Ctrl+/注释取消注释
Alt+Enter 自动完成函数定义
F4 .h .cpp文件切换
VS
Ctrl+k,f自动格式化代码
Ctrl+k,c注释
Ctrl+k,u取消注释
工具
dependency walker 分析库 ldd
错误
处理由C语言函数的警告操作:
1、#define _CRT_SECURE_NO_WARNINGS
放在程序第一行
2、#pragma warning(disable:4996
3、在项目中右击选择属性,在打开对话框中选择C/C++处理器
在预处理器定义中编辑 _CRT_SECURE_NO_WARNINGS