c语言九(3) 数组

指针

const 关键字保护数组内容

​ 如果一个数组作为函数的形参传递,那么这个数组内容可以在被调用函数内部修改,有时候不希望这种事情发生,就需要用const来修饰,进行保护,防止修改

void func (const int array[]);

函数指针

一个函数在编译的时候会分配一个入口地址,这个入口就是函数的指针,函数名称就代表函数的入口地址.

1.指针定义方式
函数返回类型 (* 指针变量 ) (参数列表);
int (*p)();

2.函数可以通过函数指针调用
3.int (*p)()代表指向一个函数,但不是固定哪一个函数.
#include <stdio.h>
#include <stdlib.h>
void man()
{
    printf("男人\n");
}
void woman()
{
    printf("女病人\n");
}
int main(){
    int  (*p)();
    int i;
    scanf("%d",&i);
    if(i!=0)
        p=man;
    else
        p=woman;
    p();
    system("pause");
    return 0;
}

在回调函数和运行期动态绑定的时候大量的用到了指向函数的指针.

2.回调函数

将函数指针作为另外一个函数的参数称为回调函数.

#include <stdio.h>
#include <stdlib.h>
int add(int x, int y)
{
    return x + y;
}
int sub(int x, int y)
{
    return x - y;
}
int mul(int x, int y)
{
    return x * y;
}
int divi(int x, int y)
{
    return x / y;
}
void func(int(*p)(int, int), int x, int y)
{
    int res = p(x, y);
    printf("%d\n", res);
}
int  main() {
    int x, y;
    char temp;
    int (*p1)(int x,int y);
    scanf("%d%c%d", &x, &temp, &y);
    printf("=");
    switch (temp)
    {
        case '+':
            func(add, x, y);
            break;
        case '-':
            func(sub, x, y);
            break;
        case '*':
            func(mul, x, y);
            break;
        case '/':
            func(divi, x, y);
            break;
    }
    system("pause");
    return 0;
}

memset,,memcpy,memmove函数

(头文件: string.h)

这三个函数分别实现内存设置,内存拷贝和内存移动

使用memcpy的时候,一定要确保内存没有重叠区域。

memset函数主要用于给数组或结构体进行初始化
char str[10];
char *p=str;
memset(str,0,sizeof(str));	//这里只能写sizeof(str)(可以写数字,但不专
							//业),不能用写sizeof(p);
							//别想把0换成'a',我试过了,人家把
							//他当ascii码97赋值了,只能数字赋值,主要还是初始化
for(int i;i<sizeof(str)/sizeof(str[0]);i++)
{
    printf("%d\n",str[i]);
}
memcpy函数主要用于数组拷贝,要注意!!!内存没有重叠区域
#include <string>
char array[]="一个汉字几个字节?word和dword的区别";
char array1[34];
memcpy(array1,array,strlen(array));
//被粘贴者array1,复制了arrar,且拷贝字节为strlen(array)个
printf("%s\n",arrary1);
memmove函数主要用于移动内存块
该函数不检查源中是否有任何终止空字符--始终精确地复制数字字节
与memcpy的差别就是mememove函数处理峰内存块和目标内存块是可以重叠的
...老师不讲,百度看不懂....

通过指针访问字符串数组

char buf[100] = "hello world";
	char *p = buf;
	//*(p + 5) = 'a';
	//p[5] = 'b';
	p += 5;
	*p = 'c';
	p[3] = ' ';				//主要是这里需要注意一下变化
	printf("buf = %s\n", buf);
输出显示   buf = hellocwo ld

指针数组作为main函数的形参

int main(int argc, char *argv[]);

main函数是操作系统调用的,所以main函数的参数也是操作系统在调用时候自动填写的

argc代表命令行参数的数量

argv代表命令行的具体参数,是char *类型的

内存管理

作用域

一个C语言变量的作用域可以是代码块 作用域,函数作用域或者文件作用域。

代码块是{}之间的一段代码。

出现在{}之外的变量,就是全局变量

auto自动变量

一般情况下代码块内部定义的变量都是自动变量。当然也可以显示的使用aotu关键字

register寄存器变量

通常变量在内存当中,如果能把变量放到CPU的寄存器里面,代码执行效率会更高

register int i;

代码块作用域的静态变量

静态变量是指内存位置在程序执行期间一直不改变的变量,一个代码块内部的静态变量只能被这个代码块内部访问。

全局变量

全局变量的存储方式和静态变量相同,但可以被多个文件访问.

外部变量与extern关键字

extern int i;

全局函数和静态函数

在C语言中函数默认都是全局的,使用关键字static可以将函数声明为静态.

内存四区

栈区 堆区 静态区 代码区

代码区

代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也 叫代码段,这块内存是不可以在运行期间修改的。

静态区

所有的全局变量以及程序中的静态变量都存储到静态区,比较如下两段代码的区别

int a = 0;
	int main()
	{
		static int b = 0;
		printf("%p, %p\n", &a, &b);
		return 0;
	}

int a = 0;
	static int b = 0;
	int main()
	{
		printf("%p, %p\n", &a, &b);
		return 0;
	}

栈区

栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。

对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器实现

栈不会很大,一般都是以K为单位的

栈溢出

当栈空间以满,但还往栈内存压变量,这个就叫栈溢出

对于一个32位操作系统,最大管理管理4G内存,其中1G是给操作系统自己用的,剩下的3G都是给用户程序,一个用户程序理论上可以使用3G的内存空间,

堆区

堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。

堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。

堆的分配和释放

操作系统在管理内存的时候,最小单位不是字节,而是内存页

malloc

void * malloc(size_t _Size);

malloc函数在堆中分配参数_Size指定大小的内存,单位:字节,函数返回void *指针。

free

void free(void *p);

free负责在堆中释放malloc分配的内存。参数p为malloc返回的堆中的内存地址

calloc

void * calloc(size_t _Count, size_t _Size);

calloc与malloc类似,负责在堆中分配内存。

第一个参数是所需内存单元数量,第二个参数是每个内存单元的大小(单位:字节),calloc自动将分配的内存置0

int *p = (int *)calloc(100, sizeof(int));//分配100个int

reallor

重新分配用malloc或者calloc函数在堆中分配内存空间的大小。

void * realloc(void *p, size_t _NewSize);

第一个参数 p为之前用malloc或者calloc分配的内存地址,_NewSize为重新分配内存的大小,单位:字节。

成功返回新分配的堆内存地址,失败返回NULL.

如果参数p等于NULL,那么realloc与malloc功能一致

posted @ 2022-10-13 14:56  追梦的那些孩子  阅读(18)  评论(0)    收藏  举报