C语言 内存
2016-06-26 00:00
351 查看
char *func() {
char string[] = "iPhone";
return string;//这种写法是非常愚蠢的!
//string存在与函数内部,是栈区的变量,栈区的地址。当函数执行结束之后,string会被系统自动回收。当我们再去访问这块内存区域的时候,已经没有权限了。
//举个例子:丽德酒店318宿舍,之前一直都是你住,有一天你搬走了,住进去另外的人,此时你已经不是318宿舍的主人了,不能访问。
}
void test() {
static int a = 10;//此时a存在与静态区,只初始化一次,函数执行结束,并不会被系统回收,只有当程序结束时才会被回收。
printf("%d\n",a++);
}
typedef struct student {
char name[20];
int age;
float score;
}Student;
int main(int argc, const char * argv[]) {
//iOS内存分为五个区:按照内存大小从高到低的顺序分别为栈区、堆区、静态区(全局区)、常量区、代码区。
//栈区:存放所有的局部变量,包括函数的形参。
//栈区的特点:栈区的内存是由系统自动开辟和回收的,采用先进后出的原则管理局部变量。栈区变量只要函数执行完毕,就会被系统回收,所以返回栈区变量是一种非常愚蠢的操作。
//堆区:是系统留给开发者使用的内存。这块内存完全由程序员掌握。程序猿去决定什么时候使用,使用多大,什么时候回收,系统不做任何干预。如果只开辟不回收,那么堆区域内存就会越来越少,当可用内存没有时,程序就会崩溃,crash。如果开辟回收之后,又访问了这块被回收的内存,也会出现,崩溃,这叫野指针。
//所以说,堆区域的内存我们必须秉持着一个原则,有回收必须有释放。
//常量区:存放所有的常量。比如15、’A‘、3.3、“iPhone”
//常量区我们平常不会干预。常量区是禁止程序员做任何修改的。一旦改了常量区的内容,程序会立即崩溃,crash。
//常量区中存储的常量只有一份,并且是只读的。
//静态区:也可以叫做全局区。主要用来存放静态全局变量和局部变量。
//由系统为变量分配内存空间,程序猿不能控制。静态区的变量有一个特点,只会初始化一次,并且只有当程序运行结束时才会被系统回收,并不会随着函数的执行结束被系统回收!
//代码区:代码区存放的是代码,函数 编译之后形成的CPU指令(二进制文件),并非源代码。代码区与常量区一样我们不会干预,代码区与我们即将学到的函数指针有很大的关联。
/*
for (int i = 0; i < 10; i ++) {
test();
}
int a = 20;
int b = 10;
printf("a = %p, b = %p\n",&a, &b);
printf("%d\n",sum(a, b));
*/
/*
//堆区域操作函数
//内存分配函数 malloc void *malloc(unsigned int size);
//此函数的作用为 返回一个新开辟的堆区域的首地址。
//其中void *代表泛型指针,具体是什么类型由我们自己定。参数size表示 从 首地址 开辟多少字节大小的空间,来储存信息。
int *p = malloc(4);
*p = 20;
printf("%d\n",*p);
int *q = malloc(sizeof(int) * 5);
q[0] = 1;
q[1] = 2;
*(q + 3) = 3;
for (int i = 0; i < 5; i ++) {
printf("%d\t",q[i]);
}
short *p1 = malloc(4);
p1[0] = 2;
p1[1] = 3;
printf("%d %d %d\n",*p, *p1, *(p1 + 1));
char *str = malloc(8);
// while (string[i] != '\0') {
// str[i] = string[i];
// i ++;
// }
strcpy(str, "iPhone");
printf("%s\n",str);
Student *stu = malloc(sizeof(Student) * 5);
strcpy((stu + 1)->name, "gujuju");
printf("%s\n",stu[1].name);
free(stu);//回收开辟的堆区域内存,采用free函数。
*/
/**
* 有一字符串,其中包含 数字 ,提取其中的 数字 .要求动态分配内存保存
提示: 先计算出有几个数字,然后根据数字的个数来开辟空间.
*/
/**
* 1、遍历字符串,得到其中的数字字符个数
2、根据得到的数字个数 动态分配内存空间(堆区域)
3、再次遍历字符串,将数字字符 - 48 得到的数字 放入开辟好的堆区域空间中
4、遍历结束,打印堆区域中的整型数字。
*/
/*
char string[] = "iPhone6s2GPlus12A";
//遍历的循环增量、记录数字字符的计数
int i = 0, count = 0;
while (string[i] != '\0') {
if (string[i] >= '0' && string[i] <= '9') {
count ++;
}
i ++;
}
printf("%d\n",count);
int *p = malloc(sizeof(int) * count);
i = 0;
int j = 0;
while (string[i] != '\0') {
if (string[i] >= '0' && string[i] <= '9') {
p[j] = string[i] - '0';
j ++;
}
i ++;
}
for (int i = 0; i < count; i ++) {
printf("%d\t",p[i]);
}
free(p);
*/
/*
//输入3个单词,动态分配内存保存单词,并在最后输出
//定义一个包含三个字符指针的数组,他们默认值都为NULL
char *word[3] = {0};
//定义一个临时数组 来接收用户从控制台输入的值
char temp[50] = {0};
printf("请输入三个单词,中间以空格隔开:");
for (int i = 0; i < 3; i ++) {
scanf("%s",temp);//接收时不要加取地址符&,因为数组名就是首地址
unsigned long length = strlen(temp);//获取输入的每个字符串的长度
//动态分配内存,让指针数组中的字符指针指向 开辟的堆区域空间的首地址
word[i] = malloc(length + 1);
//通过strcpy函数完成赋值
strcpy(word[i], temp);
}
for (int i = 0; i < 3; i ++) {
printf("%s\n",word[i]);
free(word[i]);
}
*/
/**
* 定义两个 整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行 赋值 随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则打印Failed...
*/
int *p = malloc(sizeof(int) * 3);
int *q = calloc(3, sizeof(int));
memset(p, 0, sizeof(int) * 3);
for (int i = 0; i < 3; i ++) {
p[i] = arc4random() % (3 - 1 + 1) + 1;
q[i] = arc4random() % (3 - 1 + 1) + 1;
printf("p = %d,q = %d\n",p[i], q[i]);
}
int result = memcmp(p, q, sizeof(int) * 3);
if (0 == result) {
printf("Good!\n");
}else {
printf("Failed!\n");
}
char *str1 = "iPhone";
char *str2 = "gujuju";
printf("%d\n",memcmp(str2, str1, 6));
NSString *str = @"45";
NSInteger a = [str integerValue];
NSLog(@"%ld",a);
char string[] = "iPhone";
return string;//这种写法是非常愚蠢的!
//string存在与函数内部,是栈区的变量,栈区的地址。当函数执行结束之后,string会被系统自动回收。当我们再去访问这块内存区域的时候,已经没有权限了。
//举个例子:丽德酒店318宿舍,之前一直都是你住,有一天你搬走了,住进去另外的人,此时你已经不是318宿舍的主人了,不能访问。
}
void test() {
static int a = 10;//此时a存在与静态区,只初始化一次,函数执行结束,并不会被系统回收,只有当程序结束时才会被回收。
printf("%d\n",a++);
}
typedef struct student {
char name[20];
int age;
float score;
}Student;
int main(int argc, const char * argv[]) {
//iOS内存分为五个区:按照内存大小从高到低的顺序分别为栈区、堆区、静态区(全局区)、常量区、代码区。
//栈区:存放所有的局部变量,包括函数的形参。
//栈区的特点:栈区的内存是由系统自动开辟和回收的,采用先进后出的原则管理局部变量。栈区变量只要函数执行完毕,就会被系统回收,所以返回栈区变量是一种非常愚蠢的操作。
//堆区:是系统留给开发者使用的内存。这块内存完全由程序员掌握。程序猿去决定什么时候使用,使用多大,什么时候回收,系统不做任何干预。如果只开辟不回收,那么堆区域内存就会越来越少,当可用内存没有时,程序就会崩溃,crash。如果开辟回收之后,又访问了这块被回收的内存,也会出现,崩溃,这叫野指针。
//所以说,堆区域的内存我们必须秉持着一个原则,有回收必须有释放。
//常量区:存放所有的常量。比如15、’A‘、3.3、“iPhone”
//常量区我们平常不会干预。常量区是禁止程序员做任何修改的。一旦改了常量区的内容,程序会立即崩溃,crash。
//常量区中存储的常量只有一份,并且是只读的。
//静态区:也可以叫做全局区。主要用来存放静态全局变量和局部变量。
//由系统为变量分配内存空间,程序猿不能控制。静态区的变量有一个特点,只会初始化一次,并且只有当程序运行结束时才会被系统回收,并不会随着函数的执行结束被系统回收!
//代码区:代码区存放的是代码,函数 编译之后形成的CPU指令(二进制文件),并非源代码。代码区与常量区一样我们不会干预,代码区与我们即将学到的函数指针有很大的关联。
/*
for (int i = 0; i < 10; i ++) {
test();
}
int a = 20;
int b = 10;
printf("a = %p, b = %p\n",&a, &b);
printf("%d\n",sum(a, b));
*/
/*
//堆区域操作函数
//内存分配函数 malloc void *malloc(unsigned int size);
//此函数的作用为 返回一个新开辟的堆区域的首地址。
//其中void *代表泛型指针,具体是什么类型由我们自己定。参数size表示 从 首地址 开辟多少字节大小的空间,来储存信息。
int *p = malloc(4);
*p = 20;
printf("%d\n",*p);
int *q = malloc(sizeof(int) * 5);
q[0] = 1;
q[1] = 2;
*(q + 3) = 3;
for (int i = 0; i < 5; i ++) {
printf("%d\t",q[i]);
}
short *p1 = malloc(4);
p1[0] = 2;
p1[1] = 3;
printf("%d %d %d\n",*p, *p1, *(p1 + 1));
char *str = malloc(8);
// while (string[i] != '\0') {
// str[i] = string[i];
// i ++;
// }
strcpy(str, "iPhone");
printf("%s\n",str);
Student *stu = malloc(sizeof(Student) * 5);
strcpy((stu + 1)->name, "gujuju");
printf("%s\n",stu[1].name);
free(stu);//回收开辟的堆区域内存,采用free函数。
*/
/**
* 有一字符串,其中包含 数字 ,提取其中的 数字 .要求动态分配内存保存
提示: 先计算出有几个数字,然后根据数字的个数来开辟空间.
*/
/**
* 1、遍历字符串,得到其中的数字字符个数
2、根据得到的数字个数 动态分配内存空间(堆区域)
3、再次遍历字符串,将数字字符 - 48 得到的数字 放入开辟好的堆区域空间中
4、遍历结束,打印堆区域中的整型数字。
*/
/*
char string[] = "iPhone6s2GPlus12A";
//遍历的循环增量、记录数字字符的计数
int i = 0, count = 0;
while (string[i] != '\0') {
if (string[i] >= '0' && string[i] <= '9') {
count ++;
}
i ++;
}
printf("%d\n",count);
int *p = malloc(sizeof(int) * count);
i = 0;
int j = 0;
while (string[i] != '\0') {
if (string[i] >= '0' && string[i] <= '9') {
p[j] = string[i] - '0';
j ++;
}
i ++;
}
for (int i = 0; i < count; i ++) {
printf("%d\t",p[i]);
}
free(p);
*/
/*
//输入3个单词,动态分配内存保存单词,并在最后输出
//定义一个包含三个字符指针的数组,他们默认值都为NULL
char *word[3] = {0};
//定义一个临时数组 来接收用户从控制台输入的值
char temp[50] = {0};
printf("请输入三个单词,中间以空格隔开:");
for (int i = 0; i < 3; i ++) {
scanf("%s",temp);//接收时不要加取地址符&,因为数组名就是首地址
unsigned long length = strlen(temp);//获取输入的每个字符串的长度
//动态分配内存,让指针数组中的字符指针指向 开辟的堆区域空间的首地址
word[i] = malloc(length + 1);
//通过strcpy函数完成赋值
strcpy(word[i], temp);
}
for (int i = 0; i < 3; i ++) {
printf("%s\n",word[i]);
free(word[i]);
}
*/
/**
* 定义两个 整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行 赋值 随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则打印Failed...
*/
int *p = malloc(sizeof(int) * 3);
int *q = calloc(3, sizeof(int));
memset(p, 0, sizeof(int) * 3);
for (int i = 0; i < 3; i ++) {
p[i] = arc4random() % (3 - 1 + 1) + 1;
q[i] = arc4random() % (3 - 1 + 1) + 1;
printf("p = %d,q = %d\n",p[i], q[i]);
}
int result = memcmp(p, q, sizeof(int) * 3);
if (0 == result) {
printf("Good!\n");
}else {
printf("Failed!\n");
}
char *str1 = "iPhone";
char *str2 = "gujuju";
printf("%d\n",memcmp(str2, str1, 6));
NSString *str = @"45";
NSInteger a = [str integerValue];
NSLog(@"%ld",a);
相关文章推荐
- C语言 结构体指针
- C++基础备忘
- C++的类型转换
- 【C/C++】:string到double和string到int的转换
- 【C/C++】:函数返回结构体的写法
- C语言 链表排序
- C++中构造函数、拷贝构造、赋值函数
- c++11 条款21:尽量使用std::make_unique和std::make_shared而不直接使用new
- 高效effective C++ 55条款之个人学习笔记1
- c++设计模式之单例模式下的实例自动销毁(垃圾自动回收器)
- c,c++中字符串处理函数strtok,strstr,strchr,strsub
- c语言学习笔记37之字符串
- 程序执行的时间计算
- C++独孤九剑第八式——平沙落雁(运行时浅剖析)
- [c语言学习]关于指针
- C++中的友元(二)
- 309. Best Time to Buy and Sell Stock with Cooldown
- c语言笔记
- 使用VS2015进行C++开发的6个主要原因
- C语言反转数组(reverse函数)