2.20 2.21 黑马C提高 第一天

1、概述(学习要求,学习标准)
2、数据类型和变量
3、内存四区(栈、堆、全局、代码区)

image
1.接口设计(测试)

cs 客户端 服务器
bs 浏览器 服务器

image

2.数据类型的本质
数据类型可理解为创建变量的模具:是固定内存大小的别名。
只有有了它编译器才知道给你多少字节
`int main(void)
{
int a = 10; //告诉编译器,分配4个字节的内存
int b[10]; //告诉编译器,分配4*10 = 40 个字节的内存

printf("b:%p, b+1: %p, &b:%p, &b+1: %p\n", b, b + 1, &b, &b + 1);

//b+1 和 &b+1的结果不一样 
//是因为 b 和 &b 所代表的数据类型不一样
//b  代表数组首元素的地址
//&b 代表整体数组的地址

return 0;}

1.1.4 数据类型的别名

点击查看代码
typedef struct People
{
    char name[64];
    int age;
} people_t;

typedef unsigned int u32;   //给unsigned int类型取别名

1.1.5 数据类型的封装
void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。

void print_array(int a[], int n)
数组为形参

点击查看代码
//如果数组作为函数参数,数组形参退化为指针
//void print_array(int a[1], int n)
//void print_array(int a[], int n)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//如果数组作为函数参数,数组形参退化为指针
//void print_array(int a[1], int n)
//void print_array(int a[], int n)
void print_array(int* a, int n)
{
	// a, 当做指针用,指针类型,32位,长度4个字节

	n = sizeof(a) / sizeof(a[0]); //元素个数
	printf("print_array: n = %d\n", n);

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


int main(void)
{
	int a[] = { 10, 7, 1, 9, 4, 6, 7, 3, 2, 0 };
	int n;
	int i = 0;
	int j = 0;
	int tmp = 0;

	n = sizeof(a) / sizeof(a[0]); //元素个数
	printf("n = %d\n", n);
	printf("排序前:\n");
	print_array(a, n);

	printf("\n");
	system("pause");
	return 0;
}

变量的概念
概念:既能读又能写的内存对象,称为变量;若一旦初始化后不能修改的对象则称为常量。

1 对内存,可读可写;
2 通过变量往内存读写数据;
3 不是向变量读写数据,而是向变量所代表的内存空间中写数据
变量只是个名字,真实的是它的地址 它的地址内有我们需要的数据

程序的内存四区模型
image
image

全局区分析

点击查看代码
#include <stdio.h>

char * getStr1()
{
    char *p1 = "abcdefg2";
    return p1;
}
char *getStr2()
{
    char *p2 = "abcdefg2";
    return p2;
}
int main(void)
{
    char *p1 = NULL;
    char *p2 = NULL;
    p1 = getStr1();
    p2 = getStr2();

    //打印p1 p2 所指向内存空间的数据
    printf("p1:%s , p2:%s \n", p1, p2);

    //打印p1 p2 的值
    printf("p1:%p , p2:%p \n", p1, p2);

    return 0;
}

全局区 存放地址 分析图 https://img2023.cnblogs.com/blog/3001071/202302/3001071-20230221122157412-541786060.png

堆区

利用 malloc 或者new 创建的一片可以存储数据的地址 就是堆区
堆 0x00D3FCE0
堆栈
0x00FAF844
堆区
image
堆栈
image
1.4 函数的调用模型
image
这说明了为什么在入口函数处生名的变量可以被函数使用
1.6 栈的生长方向和内存存放方向
image
作业

点击查看代码
1. 数据类型的本质是什么? (从编译器的角度考虑)
//告诉编译器 开辟内存的大小 还有编译器进行一些处理

2. 如何为一个数据类型起别名?
typedef char* to;
3. 既然有栈空间,为何要有堆空间?
	存储更多的数据

栈的空间由谁分配和回收?
	堆的空间又由谁分配和回收?

	堆栈 出函数自动销毁 编译器进行分配
	堆 由系统底层函数进行销毁 和分配

4. 有一个函数,数组做函数函数
	void print_array(int a[128])
	{
		//sizeof(a) = ? 4
	4个字节
	}
	
5. 有一个数组,如何求出元素个数?
	int main(void)
	{
		int a[] = {1, 5, 7, 0, 10, 7, 3};
		sizeof(a) / sizeof(a[2]);
		
	}
	
	
6. 在32位平台上
	char ************p = NULL;
	int *q = NULL;
	sizeof(p) = ?
	sizeof(q) = ?
		都是四字节


7. 画出下面代码的内存四区图
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *get_mem(int size)
{
    char *p2 = NULL;            //分配4个字节的内存 栈区也叫临时区
    p2 = (char *)malloc(size);//堆空间

    return p2;
}

int main(void)
{
    char buf[100]; // 分配400个字节的内存 栈区也叫临时区
    int a = 10;     //分配4个字节的内存 栈区也叫临时区
    int *p;         //分配4个字节的内存
    p = &a;   

    *p = 20;

    char *mp = get_mem(100);
    strcpy(mp, "ABCDEFG");

    if (mp != NULL)
    {
        free(mp);
		mp = NULL;
    }

    return 0;
}

posted @ 2023-02-20 20:38  逆向狗  阅读(20)  评论(0)    收藏  举报