c基础

基本数据类型以及打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void main() {
int i = 100;
double d = 200;
float f = 200;
long l = 200;
short s = 100;
char c = 'D';
// 字符串 char *

printf("i = %d\n" ,i);
printf("d = %lf\n" ,d);
printf("f = %f\n" ,f);
printf("l = %ld\n" ,l);
printf("s = %d\n" ,s);
printf("c = %c\n" ,c);
getchar();//
}

指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

// 指针(变量)地址:任何的数据 (变量)都会有地址(住址门牌号)
// &+变量名就是地址
// *+地址就是取值
void main() {
int i = 100;
//获取地址
printf("i的地址是: %p\n", &i);//xxxxxx
printf("i的值是: %d\n", i);//100
//获取地址的值
printf("i的值是: %d\n", *&i);//100

//指针(地址)变量:指针存放(指向)的就是变量的地址
int* p = &i;
//取值
printf("i的值是: %d\n", *p) //100

double d = 200;
double* p1 = &d;


//通过指针修改值
*p = 200;
printf("i的值是: %d\n", i) // 200

getchar();
}

指针为什么要有类型?

指针其实就是一块地址而且值都差不多,为什么要有类型?
1.取值的时候我要知道怎么取?int 4个字节取 double8个字节取
2.取值的偏移?int偏4个字节 double偏8个字节

常量指针 指针常量

1
2
3
常量变量:被常量修饰的变量,不能再次被赋值 (Java)
常量指针:const 在 * 之前,指针的地址是可以被再次赋值的(可以修改的),指针地址上面的值(变量)是不能被修改的,常量指针的常量是不能被改变的。
指针常量:const 在 * 之后,指针的地址是不可以被再次赋值的(不可以修改的),指针地址上面的值(变量)能被修改的,指针常量的指针地址是不能被改变的。

基本数据类型所占字节数

1
2
3
4
5
6
void main() {
printf("int 数据类型所占字节数: %d\n",sizeof(int));//4
printf("double 数据类型所占字节数: %d\n", sizeof(double));//8
printf("char 数据类型所占字节数: %d\n", sizeof(char));//1
getchar();
}

二级指针

1
2
3
4
5
6
7
8
9

void main() {
int num = 142;
int* p = #
int** s_p = &p;
printf("p = %p, s_p = %p", p, s_p);
printf("num = %d ", **s_p); //142
getchar();
}

数组与数组指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//数组与数组指针
void main() {
int arr[] = { 1, 2, 3, 4 };

//arr的值=arr取地址的值 , arr地址的值 = arr[0]的地址的值(首地址) 他们三个是一个地址
printf("arr = %p\n", arr); // arr = 000000137F6FFAA8
printf("arr& = %p\n", &arr);// arr& = 000000137F6FFAA8
printf("arr[0]& = %p\n", &arr[0]);// arr[0]& = 000000137F6FFAA8

//如何获取数组的指针(首地址)
int* arr_p = arr;

printf("%d \n", *arr_p); // 1

//对数组指针++
arr_p++;
printf("%d \n", *arr_p); // 2

arr_p += 2;
printf("%d \n", *arr_p); // 4

arr_p ++;
printf("%d \n", *arr_p); // -858993460 这里因为已经超出数组长度了

//遍历
int arr2[] = { 5, 8, 9, 4 };

// for (i = 0; i < 4; i++) {
// printf("%d\n", arr2[i]);
// }

//注意for循环的写法,要写成下面这个 写成java的那种,可能会造成操作系统(Linux)不一样而编译不了
//c拿不到arr长度
int i = 0;
for (; i < 4; i++) {
printf("%d\n", arr2[i]);
}

//通过指针来循环遍历
int* arr2_p = arr2;
int j = 0;
for (; j < 4; j++) {
arr2_p++;
printf("%d\n", *arr2_p);
}

//数组指定长度
int arr3[4];
int* arr3_p = arr3;
int k = 0;
for (; k < 4; k++) {
*(arr3_p + k) = k*10;
}
k = 0;

for (; k< 4; k++) {
printf("%d\n", arr3_p[k]);
}

getchar();
}

数组指针操作的常用几种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
//数组指针操作的常用几种方式
void main() {
int arr[] = { 1,3,5,7 };
int i = 0;
for (; i < 4; i++) {
//第一种
printf("位置%d的值是:%d\n", i, *(arr + i));
//第二种
printf("位置%d的值是:%d\n", i, arr[i]);
//....
}
getchar();
}

函数指针(回调)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//函数指针
void main() {

//方法的返回类型(*方法的名称)(方法的参数)
void(*add_p)(int, int) = add;
// void(*add_p)(int, int) = &add; //这个一样的
//正常调用
add(1, 2);
//指针调用
(*add_p)(1, 2);


opeate(add, 1, 2);
opeate(mins, 1, 2);


getchar();
}

void add(int num1, int num2) {
printf("num1+num2=%d\n", num1 + num2);
}

void mins(int num1, int num2) {
printf("num1-num2=%d\n", num1 - num2);
}

//方法的返回类型(*方法的名称)(方法的参数)
void opeate(void(*method)(int, int), int num1, int num2) {
method(num1, num2);
}

内存开辟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <stdio.h>
#include <Windows.h>

//静态开辟内存 方法结束会自动回收
void staticlloc() {
int arr[5];
int i = 0;
for (; i < 5; i++) {
arr[i] = i;
printf("%d %p\n", *(arr + i),arr+i);
}
}
//动态开辟内存 方法结束不会自动回收
void dynamiclloc() {
//malloc申请需要的内存返回void* 这里强转成你需要的指针类型
int* arr = (int*)malloc(10 * 1024 * 1024 * sizeof(int));//40M
}

//动态开辟内存 方法结束不会自动回收 手动释放
void dynamiclloc2free() {
//malloc 申请需要的内存返回void* 这里强转成你需要的指针类型
int* arr = (int*)malloc(10 * 1024 * 1024 * sizeof(int));//40M
//手动释放
free(arr);
}



//内存开辟
void main(){
//Stack overflow 栈溢出
// int arr[10*1024*1024];//占用内存?数组大小10M,int占用4字节,40M的内存空间

//c里面有四驱模型
//栈:占用的内存空间大小 ,开辟内存的方式是静态内存开辟 int arr[10*1024*1024],方法结束会自动回收
//堆:占用内存空间最大值 80% ,开辟内存的方式是动态内存开辟,方法结束不会自动回收,需要手动回收

//静态开辟内存,函数结束会自动回收 内存开辟后不可变
/*
//这里运行 内存不会上升,staticlloc()函数结束会自动回收
while (true){
Sleep(100);
staticlloc();
}
*/

//动态内存开辟 内存开辟后可变
/*
//这里运行 内存会持续上升
while (true) {
Sleep(100);
dynamiclloc();
}
*/

//这里运行 内存不会持续上升,因为手动释放了
while (true) {
Sleep(100);
dynamiclloc2free();
}

getchar();
}

内存开辟使用场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#include<stdio.h>
#include<Windows.h>

//使用场景
void main() {
//假设我们现在需要接受用户所输入的数,然后进行排序

int num;
printf("请输入数的个数: ");
//获取用户输入的值
scanf_s("%d",&num);

//定义一个数组来存放用户的数据
//int arr[num]; 静态开辟

int* arr =(int*) malloc(sizeof(int) * num);

int print_num;
int i = 0;
for (; i < num; i++) {
printf("请输入第%d个的值: ", i);
scanf_s("%d", &print_num);
arr[i] = print_num;//arr[i] = *(arr+i);
}

//对arr排序
//....

//回收动态开辟的内存
free(arr);

getchar();
}

改变内存大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

//改变内存空间大小
void main() {
int num;
printf("请输入数的个数: \n");
//获取用户输入的值
scanf_s("%d", &num);
int* arr = (int*)malloc(sizeof(int) * num);
printf("arr的指针: %p \n",arr);

int print_num;
int i = 0;
for (; i < num; i++) {
arr[i] = i;//arr[i] = *(arr+i);
}

int new_num;
//在加点内存
printf("请输入新增的个数: \n");
//获取用户输入的值
scanf_s("%d", &new_num);
//改变内存大小空间
int new_size = sizeof(int)* (num + new_num);
//ptr - 指向需要重新分配的内存区域的指针
//new_size - 数组的新大小(字节数)
//tip1. 这里默认new_arr的指针和arr的指针是同一个,后面赋值可以接着后面的赋值
//tip2. 如果连续内存不足的话返回的话可能是新的指针,那么将要全部重新赋值
//tip3. 新增内存有可能会失败(内存被系统占用或者内存不够用了),失败的时候返回的是 NULL
//tip4. realloc的arr 释放的时候也务必要进行判断NULL,释放完我们最好把指针致为NULL
//tip5. 不要反复去释放
int* new_arr =(int*) realloc(arr, new_size);
printf("new_arr的指针: %p \n", new_arr);
if (new_arr) {// if(new_arr!=NULL)
//tip 1. 这里默认new_arr的指针和arr的指针是同一个,后面赋值可以接着后面的赋值
for (; i < num + new_num; i++) {
arr[i] = i;//arr[i] = *(arr+i);
}
//tip 2. 如果连续内存不足的话返回的话可能是新的指针,那么将要全部重新赋值
i = 0;
for (; i < num + new_num; i++) {
arr[i] = i;//arr[i] = *(arr+i);
}

i = 0;
for (; i < num + new_num; i++) {
printf("%d \n", arr[i]);
}
}

getchar();

if (new_arr) {
//这里arr将不手动回收
//free(arr);
free(new_arr);
new_arr = NULL;
}else {
free(arr);
}
getchar();
}

字符串定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void main() {
//第一种 字符串数组
char str[] = {'a','b','c','d','\0'};
printf("%s", str);//字符串结尾是 '\0'

//第二种 常用的
const char *str1 = "abcde";
printf("%s", str1);

//区别 前者能修改 后面不能修改
// str[1] = 'x';
// strstr11] = 'x'; //报错
getchar();
}

字符串基本api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>


//自己实现 获取字符串长度
int strlen_(const char *str) {
int len = 0;
while (*str != '\0') {
len++;
str++;
}
return len;
}




//大小写转换
void lower(char* dest,const char* source) {
while (*source!='\0') {
//当前字符串
char ch = *source;
//转完复制给dest
*dest = tolower(ch);
source++;
dest++;
}
*dest = '\0';
}


//字符串截取 动态内存开辟 用了需要free ndk使用需要静态开辟
char* substr(const char* str, int startIndex, int endIndex) {
//开辟一个内存来存数据 ndk里面使用静态开辟内存 这里vs编辑器会报错所以动态开辟了
//char* subStr[endIndex - startIndex + 1];
int len = endIndex - startIndex;
//这里要注意free
char* subStr = (char*)malloc(len * sizeof(char) + 1);

//赋值
int i = 0;
str += startIndex;
for (; i < len; i++) {
subStr[i] = *str;
str++;
}

subStr[len] = '\0';//标记字符串结尾,否则printf无法判断结尾
return subStr;
}

const char* replace(const char*oldChar, const char*newChar,const char*source) {
//1. 有没有oldChar
const char* pos = strstr(source, oldChar);
if (!pos) {
return source;
}
//2. 计算新的数组大小
int newArraySize = strlen(source) - strlen(oldChar) + strlen(newChar);
//vs不能这样 as最好用静态的
//char result[newArraySize];
char* result = (char*)malloc(sizeof(char)*newArraySize);
//3. 进行拼接
int startIndex= pos - source;
char* start = substr(source,0, startIndex);
char* end = substr(source, startIndex + strlen(oldChar), strlen(source));

strcpy(result,start);
strcat(result, newChar);
strcat(result, end);

//释放资源
free(start);
free(end);

//全部替换 while或者递归
return replace(oldChar, newChar, result);
}


void main() {
//字符串长度获取
const char *str = "HelloGirl\0";
//#include <string.h>
printf("len = %d \n", strlen(str)); // len = 9
printf("len_ = %d \n", strlen_(str)); // len_ = 9

//字符串转换
const char *intStr = "5";
//#include <stdlib.h>
//int num = 0 如果不能转换为int的就会返回0,后面如果不是数字的会被干掉 “12xxx”-> 12
printf("int num = %d \n", atoi(str));
printf("int num = %d \n", atoi(intStr));//int num = 5


const char *floatStr = "0.012";
//#include <stdlib.h>
//float num = 0.000000 如果不能转换为float的就会返回0.000000,后面如果不是数字的会被干掉 “0.012xx”-> 0.012000
printf("float num = %f \n", atof(str));
printf("float num = %f \n", atof(floatStr));//float num = 0.012000

//strol strod ...

//字符串比较
const char *str1 = "Hello";
const char *str2 = "hello";

//区分大小写比较
int rc = strcmp(str1,str2);
if (rc == 0) {
printf("相等\n");
}else {
printf("不相等\n"); // 不相等
}

//不区分大小写比较
rc = _strcmpi(str1,str2); // c->strcmpi c++->_strcmpi android ndk -> strcasecmp
if (rc == 0) {
printf("相等\n");//相等
}else {
printf("不相等\n");
}

//比较前几个
const char *str11 = "Hello";
const char *str21 = "Hello girl";
rc = strncmp(str11, str21,5);//5->_MaxCount 代表的是比较字符串前几个是否相等
if (rc == 0) {
printf("相等\n");//相等
}
else {
printf("不相等\n");
}

//字符串查找 计算位置
const char *str0 = "Hello";
const char *subStr0 = "e";
const char* s= strstr(str0, subStr0);//返回字符串第一次出现的位置(位置指针),如果没有返回NULL
int pos = s - str0;
if (s) {//代表包含
printf("%s 第一次位置在%d\n ", s, pos);// ello 第一次位置在1
}else {
printf("%s", "没有找到");
}

//copy
const char * strh = "hello";
//char dst[strlen(strh)+1]; //不知道为什么要报错 在as里面可以的
char dst[6];
// error C4996 : 'strcpy' : This function or variable may be unsafe.Consider using strcpy_s instead.To disable deprecation, use _CRT_SECURE_NO_WARNINGS.See online help for details.
strcpy(dst, strh);
printf("%s\n", dst); //hello

//拼接
const char *str001 = "Gril";
strcat(dst,str001);
printf("%s\n", dst); //helloGril

//截取
char *subStr = substr(dst,1,4);
printf("%s\n", subStr); //ell
free(subStr);


//大小写转换
const char *hello = "HELLO";
char helloLower[6];
lower(helloLower, hello);
printf("%s\n", helloLower);//hello

//字符串替换
const char* rs= replace("LL","AA","HELLOLL");
printf("%s", rs); // HEAAOAA
//free(rs);

getchar();
}

结构体 java的class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdio.h>
#include <string.h>

//第一种方式
struct Worker {//定义一个结构体 相当于java的class
char name[10];
int age;
double salary;
};


//第二种方式,可以直接取名字
struct Worker2 {//定义一个结构体 相当于java的class
char name[10];
int age;
double salary;
}zhangsan, lisi = {"李四",25,20};


struct Work{
char name[10];
char grade[10];
};
//第三种方式,结构体的嵌套
struct Worker3{
char name[10];
int age;
double salary;
Work work;
};

//第四种方式,结构体的嵌套,直接在内部定义 java内部类 这种不测了 一样的道理
struct Worker4 {
char name[10];
int age;
double salary;
Work work;
struct Work {
//...
}work;

//struct Work{
// //...
//}work;
};


//第一种方式
void test1() {
// struct Worker worker;//第一种方式没有初始化的情况下,里面的属性都没有初始值的
struct Worker worker = { "张三",25,120 };
printf("name = %s,age = %d ,salary = %lf \n", worker.name, worker.age, worker.salary);//name = 张三,age = 25 ,salary = 120.000000

//赋值
worker.age = 85;
// worker.name = "李四";
strcat_s(worker.name, "李四");
printf("修改之后了name = %s,age = %d ,salary = %lf", worker.name, worker.age, worker.salary);//修改之后了name = 张三李四,age = 85 ,salary = 120.000000
}

//第二种方式
void test2() {
//这种方式有默认的初始值
printf("name = %s,age = %d ,salary = %lf \n", zhangsan.name, zhangsan.age, zhangsan.salary);//name = ,age = 0 ,salary = 0.000000
strcat_s(zhangsan.name, "张三");
zhangsan.age = 50;
printf("修改之后了name = %s,age = %d ,salary = %lf \n", zhangsan.name, zhangsan.age, zhangsan.salary);//修改之后了name = 张三,age = 50 ,salary = 0.000000

printf("name = %s,age = %d ,salary = %lf \n", lisi.name, lisi.age, lisi.salary);// name = 李四,age = 25 ,salary = 0.000000
}

void test3() {
struct Worker3 worker = { "张三",50,10000,{ "Android","mid"}};
//name = 张三,age = 50 ,salary = 10000.000000 ,worker.name = Android,worker.grade = mid
printf("name = %s,age = %d ,salary = %lf ,worker.name = %s,worker.grade = %s \n", worker.name, worker.age, worker.salary, worker.work.name,worker.work.grade);
}


void main() {

// test1();
// test2();
test3();
getchar();
}

结构体指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <string.h>
#include <malloc.h>

struct Worker
{
char name[10];
int age;
};


//第一种方式
void test1()
{
struct Worker worker = { "张三",56 };
Worker* worker_p = &worker;
//结构体一般用worker.name ="" 指针一般用worker_p->name =""
worker_p->age = 24;
strcpy(worker_p->name, "李四");
printf("name = %s,age= %d \n", worker_p->name, worker_p->age);//name = 李四,age= 24

}
//第二种方式 比较常用
void test2() {
Worker *worker_p =(Worker*) malloc(sizeof(Worker));
strcpy(worker_p->name, "李四");
worker_p->age = 24;
printf("name = %s,age= %d \n", worker_p->name, worker_p->age);//name = 李四,age= 24

//释放
if (worker_p) {
free(worker_p);
worker_p = NULL;
}
}

int main() {
// test1();
test2();
getchar();
return 0;
}

结构体内存开辟以及内存计算
内存大小参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

#include <stdio.h>
#include <string.h>
#include <malloc.h>

struct Worker
{
char name[10];
int age;

//计算大小:
//1. char name[10] -> sizeof(char) = 1 * 10 =10;
//2. int age -> sizeof(char) = 4 之前的偏移是10,不是4的整数,偏移两个单位到12 然后+4 = 16
//3. 16是 结构体里面基本数据类型最大int 4的整数,所以最终结果为16
};


//静态开辟
void test1() {
Worker worker[10] = { {"张三",35} };//静态开辟
worker[9] = {"lisi",25};

printf("name0 = %s ,age0 = %d \n",worker[0].name,worker[0].age);//name0 = 张三 ,age0 = 35
printf("name9 = %s ,age9 = %d \n",worker[9].name,worker[9].age);//name9 = lisi ,age9 = 25

}

//动态开辟
void test2() {
Worker* worker =(Worker*) malloc(sizeof(Worker) * 10);

strcpy(worker->name,"张三");
worker->age = 25;

printf("name= %s ,age = %d \n",worker->name,worker->age);//name= 张三 ,age = 25


//对第9个数做操作
worker += 9;
strcpy(worker->name, "李四");
worker->age = 35;
printf("name= %s ,age = %d \n", worker->name, worker->age);//name= 李四 ,age = 35

}

//内存怎么计算的?
void test3() {
//计算规则
//1. 每个成员的偏移量都必须是当前成员所占内存大小的整数倍如果不是编译器会在成员之间加上填充字节。
//2. 当所有成员大小计算完毕后,编译器判断当前结构体大小是否是结构体中最宽的成员变量大小的整数倍 如果不是会在最后一个成员后做字节填充。
int size = sizeof(Worker);
printf("size = %d",size);//size = 16
}

struct date //12
{
int year;
int month;
int day;

// 都是4 3*4 = 12;
};
struct student
{
int number;//4
char sex;//1
int gae;//4
char name[10];//10
struct date birthday;//12

//1. int number = 4
//2. char sex; 4+1=5;
//3. int age;之前的偏移量是5,不是int 4字节的整数,所以偏移到8,然后+4 =12
//4. char name[10] 12+10=22
//5. 12+22 = 34
//6. 34不是这里面最大基本数据类型int 4的整数,所以最终结果是36

};

void test4() {
int size = sizeof(date);
printf("date size = %d\n", size);//size = 12

size = sizeof(student);
printf("student size = %d\n", size);//size = 36
}


int main() {
// test1();
// test2();
// test3();
test4();
getchar();
return 0;
}

结构体或结构体指针别名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <string.h>
#include <malloc.h>


struct Worker
{
char name[10];
int age;

};


//对结构体指定别名
//别名
typedef Worker Worker_, Person;
void test1() {
Worker_ worker = {"李四",24};
printf("name = %s ,age = %d \n",worker.name,worker.age);//name = 李四 ,age = 24

Person person = { "张三",25 };
printf("name = %s ,age = %d \n ", person.name, person.age);//name = 张三 ,age = 25
}

//对结构体指针指定别名

typedef Worker* Worker_P;
void test2() {
Worker_P worker_p =(Worker*)malloc(sizeof(Worker));
worker_p->age = 25;
printf("age = %d \n ", worker_p->age);//age = 25
}


int main() {
//test1();
test2();

getchar();

return 0;
}

联合体定义以及大小计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#include <string.h>

//定义联合体,和结构体定义一样,联合体只能存在一个属性,这里要么是name,要么是age,设置值以最后为主
//大小计算 取最大值即可,然后判断是否整除该联合体里面最大基本数据类型长度,不够偏移到整除为止。
union Person
{
char name[10];
int age;

//计算: name是10 age是4 找最大值 ,然后10不能整除最大的基本数据类型int 4,所以为12
};

int main() {

//Person person = {"李四"};

Person person;
person.age = 25;
strcpy_s(person.name,"zhangsan");
printf("person.name = %s , person.age = %d\n",person.name,person.age); // person.name = zhangsan , person.age = 1851877498


strcpy_s(person.name, "zhangsan");
person.age = 25;
printf("person.name = %s , person.age = %d\n", person.name, person.age); // person.name =  , person.age = 25


printf("size = %d \n", sizeof(Person));//12

getchar();
return 0;
}

枚举的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>


//枚举的定义 ,如果中途有定义值得话,后面累加,前面还是从0开始
enum CommentType {
TEXT,IMAGE,TEXT_IMAGE
};

void main() {
CommentType commentType = TEXT;
CommentType commentType1 = IMAGE;
CommentType commentType2 = TEXT_IMAGE;
printf("%d , %d , %d",commentType, commentType1, commentType2);//0 , 1 , 2
getchar();
}

文件读写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>

int main() {
const char * fileName = "C:/Users/Administrator/Desktop/a.txt";
//打开文件 打开方式r,w具体看文档
FILE* afile_p = fopen(fileName,"r");
if (!afile_p) {
printf("文件打开失败!");
getchar();
return -1;
}

//fputs 写入 需要拥有写的模式

char buffer[10];
//缓冲区buffer ,长度10 ,文件指针
while (fgets(buffer, 10, afile_p)) {
printf("%s", buffer);
}
//关闭文件
fclose(afile_p);
getchar();

return 1;
}

文件复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
int main() {
const char * srcFileName = "C:/Users/Administrator/Desktop/ee.png";
const char * copyFileName = "C:/Users/Administrator/Desktop/ee2.png";
//打开文件 打开方式r,w具体看文档
FILE* afile_p = fopen(srcFileName, "rb");
FILE* copyfile_p = fopen(copyFileName, "wb");
if (!afile_p) {
printf("文件打开失败!");
getchar();
return -1;
}

int buffer[512];
int len;
while ((len = fread(buffer, sizeof(int), 512, afile_p))!=0) {
fwrite(buffer, sizeof(int), len, copyfile_p);
// fflush(copyfile_p);
}

//关闭文件
fclose(afile_p);
fclose(copyfile_p);
return 1;
}

获取文件大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
void main() {
//获取文件大小
const char * srcFileName = "C:/Users/Administrator/Desktop/ee.png";

FILE* afile_p = fopen(srcFileName, "rb");

if (!afile_p) {
printf("文件打开失败!");
getchar();
return;
}


//将文件的指针移动到最后,然后再去计算偏移量
fseek(afile_p,0,SEEK_END);

long fileSize = ftell(afile_p);
printf("原文件大小:%d", fileSize);

fclose(afile_p);
getchar();

}

文件加密解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
//文件加密解密
void main() {
const char * srcFileName = "C:/Users/Administrator/Desktop/ee.png";
const char * encrpyFileName = "C:/Users/Administrator/Desktop/encrpyee.png";

FILE* afile_p = fopen(srcFileName, "rb");
FILE* encrpyfile_p = fopen(encrpyFileName, "wb");
if (!afile_p) {
printf("文件打开失败!");
getchar();
return;
}
//思路,把每一个字节都拿出来,对每一个字节都处理;把某一部分字节拿出来进行处理
// 加密 10^5 异或
// 1010
// ^0101
// 1111
int c;
while ((c = fgetc(afile_p)) != EOF) {
fputc(c^5, encrpyfile_p);
}
fclose(afile_p);
fclose(encrpyfile_p);


//解密 异或
// 1111
// ^0101
// 1010
FILE* encrpySrcFile_p = fopen(encrpyFileName, "rb");
const char * deFileName = "C:/Users/Administrator/Desktop/deee.png";
FILE* defile_p = fopen(deFileName, "wb");
while ((c = fgetc(encrpySrcFile_p)) != EOF) {
fputc(c ^ 5, defile_p);
}
fclose(encrpySrcFile_p);
fclose(defile_p);

}

文件分割

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <Windows.h>

//类似断点下载
//文件的切割
void main() {
const char * srcFileName = "C:/Users/Administrator/Desktop/ee.png";

FILE* srcFile_p = fopen(srcFileName, "rb");
int file_number = 3;
//二维数组内存开辟
char** file_names =(char**) malloc(sizeof(char*)*file_number);

//进行数组内存开辟
int i = 0;
for ( ; i < file_number; i++) {
file_names[i] =(char*) malloc(sizeof(char)*100);
char *fileName = file_names[i];
sprintf(fileName, "C:/Users/Administrator/Desktop/image%d.png",i);
printf("%s\n", fileName);
}

int file_size = getFileSize(srcFileName);
if (file_size == -1) {
return;
}
int preFileSize = file_size / file_number;
//往切割文件中写入数据

i = 0;
for (; i < file_number; i++) {
FILE* cur_file_p = fopen(file_names[i],"wb");
int start = i * preFileSize;
int end = (i + 1)*preFileSize;
if (i == file_number-1) {
end = file_size;
}
int index = start;
printf("\ni=%d,start=%d,end=%d,name=%s", i, start, end, file_names[i]);
for (; index < end; index++) {
fputc(fgetc(srcFile_p),cur_file_p);
}
fclose(cur_file_p);
// free(file_names[i]);
}

fclose(srcFile_p);
free(file_names);
getchar();
}

-------------The End-------------