c复习day09

内存泄漏

  • 只申请,不释放,导致程序使用的内存空间一直增长
  • 再程序退出时,所有的内存都会释放
  • 内存污染:向没有申请的内存空间写入数据

返回变量的地址

  • 只有局部变量的地址不可以返回,应为局部变量所在的函数结束之后就被释放
  • 静态局部,全局,静态全局,这些变量,只要程序不退出,就不会释放,所以这些变量的地址是可以返回操作的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int a = 10;
int *fun()
{
//int a = 10;
//static int a = 10;
a *= 10;
return &a;
}

int main()
{
int *p = fun();
*p = 2000;//p所指向的空间没有释放(静态局部变量),则可以操作这块内存
//释放不可以操作内存(普通局部)
printf("%d\n",*p);
return 0;
}

通过函数的值传递,不能改变实参的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void mem_p(char *q)
{
q = malloc(1024);
return;
}

int main()
{
char *p = NULL;
mem_p(p);
strcpy(p,"hello");
printf("%s\n",p);
return 0;
}
  • 如果进行测试,以上代码并不能运行
  • 最终修改的代码如下所示

传实参的地址,可以在调用函数改变实参的值

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

void mem_p(char **q)
{
*q = malloc(1024);
return;
}

int main()
{
char *p = NULL;
mem_p(&p);
strcpy(p,"hello");
printf("%s\n",p);
return 0;
}

结构体

  • 将多个相同或者不同的类型的数据存在一块连续的空间中

结构体的定义和初始化

  • 定义一个结构体数据类型
  • 关键字struct 代表这是一个结构体类型
  • stu是这个结构的名字
  • 整个结构体的类型是struct stu
  • 结构体类型struct stu {} 中是结构体的成员,一共有3个成员,每个成员的类型可以是任意类型
  • 定义结构体时{}后面记得加分号
  • 定义结构体struct stu,他只是一个类型,一个模板,没有空间,不可以给结构体成员赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <string.h>
#include <strlib.h>
struct stu
{
int id;
int age;
char name[128];
} a;//定义了一个结构体变量a
int main()
{
//定义时初始化
struct stu d = {1,34,"geek"};
//给部分成员初始化,其他成员内容为0
struct stu e = {.age = 13};
//如果通过结构体变量操作结构体成员,使用点域操纵
d.id = 2;
//如果通过结构体的地址操作结构体成员
(&d)->id = 34;
return 0;
}

结构体数组

  • 是一个数组,数组的每一个元素都是结构体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct stu
{
int id;
int age;
char name[128];

}
int main()
{
//定义一个结构体数组,有5个元素,每个元素是struct stu类型
struct stu num[5] = {{1,2,"fda"},{23,43,"fa"}};
int i;
for(i = 0;i < sizeof(num),sizeof(num[0]);i++)
{
printf("%d %d %s",num[i].id,num[i].age,num[i].name);

}

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
#include <stdio.h>
#include <string.h>
struct stu
{
int id;
int age;
char name[128];
};
struct geek_stu
{
struct stu s;
char subject[128];
};

int main()
{
struct geek_stu geek;
geek.s.id = 1;
geek.s.age = 34;
strcpy(geek.s.name,"geekran");
strcpy(geek.subject,"java");
printf("%d %d %s %s\n",geek.s.id,geek.s.age,geek.s.name,geek.subject);

return 0;
}

结构体赋值

相同类型的变量是可以相互赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
int main()
{
struct stu a = {1,34,"bob"};
struct stu b;
//1 memcpy
//memcpy_str( &b,&a);
//2
//b.id = a.id;
//b.age = a.age;
////b.name = a.name;//err
//strcpy(b.name,a.name);
//3
b = a;//ok 相同类型的变量是可以相互赋值
printf("%d %d %s\n",b.id,b.age,b.name);
system("pause");
return 0;
}

结构体指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct stu
{
int id;
int age;
char name[128];
};
int main()
{
struct stu a;
struct stu *p = (struct stu *)malloc(sizeof(struct stu));
p->id = 100;
p->age = 32;
strcpy(p->name,"geekboy");
printf("%d %d %s\n",p->id,p->age,p->name);
return 0;
}

结构体套指针

示例代码一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct tea
{
int id;
char *p;
};

int main()
{
struct tea *tmp = (struct tea *)malloc(sizeof(struct tea));
tmp->id = 10;
tmp->p = "hello";//ok
//strcpy(tmp->p,"world");
printf("%s\n",tmp->p);
return 0;
}
代码一新思路
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct tea
{
int id;
char *p;
};

int main()
{
struct tea *tmp = (struct tea *)malloc(sizeof(struct tea));
tmp->id = 10;
//tmp->p = "hello";//ok
tmp->p = malloc(sizeof(128));
strcpy(tmp->p,"world");
printf("%s\n",tmp->p);
return 0;
}
示例代码二
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *p;
// p = "hello";
p = (char *)malloc(sizeof(128));
strcpy(p,"hello");

printf("%s\n",p);
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct t
{
int a;
};

struct tea
{
int id;
char *p;
struct t *b;
};
int main()
{
struct tea *tmp = (struct tea*)malloc(sizeof(struct tea));
tmp->id = 100;
tmp->p=(char *)malloc(100);
strcpy(tmp->p,"hello");
tmp->b = (struct t*)malloc(sizeof(struct t));
tmp->b->a = 143;
printf("%d %s %d",tmp->id,tmp->p,tmp->b->a);

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
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct c13
{
int id;
char name[128];
};
//void set_num(struct c13 num[5] )
void set_num(struct c13 *p,int n )
{
for (int i = 0; i < n; i++)
{
// (*(p + i)).id = i + 10;
p[i].id = i + 10;
//(p + i)->id = i + 10;
char buf[128] = "";
sprintf(buf,"%d%d%d",i,i,i);
strcpy(p[i].name,buf);
}
}
int main()
{
struct c13 num[5];
memset(num,0,sizeof(num));
set_num(num,sizeof(num)/sizeof(num[0]));// num = &num[0]
for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
{
printf("%d %s\n",num[i].id,num[i].name);

}
system("pause");
return 0;
}

const修饰的结构体指针变量

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main()
{
struct stu a;
struct stu b;
struct stu const *p1 = &a;
//const修饰的是*不能通过指针p修改p指向的那块空间
struct stu * const p2 = &b;
//const修饰的是指针变量p,不能修改p的指向
}

共用体

  • 多个变量公用一块内存空间,在同一时刻,只能有一个变量起作用

大小端问题

  • 在内存中左面是低地址,右面是高地址
  • 示例:int a = 0x01020304;
  • 小端:低位存低地址,高位存高地址 04 03 02 01
  • 大段:低位存高地址高位存低地址: 01 02 03 04
  • 大段:大型服务器,网络上的数据
  • 小端:小型的计算机
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
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
union abc
{
//char a;
short b;
char buf[2];
};
int main()
{
union abc tmp;
tmp.b = 0x0102;
if (tmp.buf[0] == 0x01)
{
printf("big\n");
}
else
{
printf("little\n");
}
system("pause");
return 0;
}
  • 可以使用上述代码实现验证

枚举

  • 将枚举类型的变量的值一一列举出来,枚举变量的值只可以赋值为{}里面的值是常量
  • 枚举{}里面列举的常量的默认值是从0开始
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum ab {SUN,RAIN,SNOW};
int main()
{
enum ab tmp = SNOW;
printf("%d %d %d\n",SUN,RAIN,SNOW);
return 0;
}

typedef

  • 用来给类型取别名
  • typedef 原类型 新类型
你的支持是我最大的动力!
0%