内存四区模型与指针

这里写图片描述

数据类型的封装
1、void的字面意思是“无类型”,void 则为“无类型指针”,void 可以指向任何类型的数据。
2、用法1:数据类型的封装
int InitHardEnv(void **handle);
典型的如内存操作函数memcpy和memset的函数原型分别为
  void * memcpy(void *dest, const void *src, size_t len);
  void * memset ( void * buffer, int c, size_t num );
3、用法2: void修饰函数返回值和参数,仅表示无。
如果函数没有返回值,那么应该将其声明为void型
如果函数没有参数,应该声明其参数为void
int function(void)
{return 1;}
4、void指针的意义
C语言规定只有相同类型的指针才可以相互赋值
void*指针作为左值用于“接收”任意类型的指针
void*指针作为右值赋值给其它指针时需要强制类型转换
int *p1 = NULL;
char p2 = (char )malloc(sizoeof(char)*20);
5、不存在void类型的变量
C语言没有定义void究竟是多大内存的别名

数据类型总结与扩展
1、数据类型本质是固定内存大小的别名;是个模具,c语言规定:通过数据类型定义变量。
2、数据类型大小计算(sizeof)
3、可以给已存在的数据类型起别名typedef
4、数据类型封装概念(void 万能类型)

程序的内存四区模型
这里写图片描述
流程说明
1、操作系统把物理硬盘代码load到内存
2、操作系统把c代码分成四个区
3、操作系统找到main函数入口执行

各区元素分析
这里写图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>


char *getMem() {
    int len = 4;
    char *p = (char*)malloc(sizeof(char)*len);
    return p;
}

char *getStr1() {
    char *p1 = "24nbcf";
    return p1;
}

char *getStr2() {
    char *p2 = "24nbcf";
    return p2;
}

int main() {

    int a; //分配4个字节
    int b[10];  //分配40个字节
    printf("b:%d, b+1:%d, &b:%d, &b+1:%d\n", b, b + 1, &b, &b + 1);//b是数组首元素地址,&b是数组地址
    //b:4652740, b + 1 : 4652744, &b : 4652740, &b + 1 : 4652780

    printf("sizeof(b):%d\n", sizeof(b));
    printf("sizeof(a):%d\n", sizeof(a));
    printf("sizeof(b[0]):%d\n", sizeof(b[0]));



    char *p1, *p2;
    p1 = getStr1();
    p2 = getStr2();
    printf("p1:%s,p2:%s\n", p1, p2);
    printf("p1:%d,p2:%d\n", p1, p2);//结果相等




    char* p = getMem();
    strcpy(p, "4444444");
    printf("p:%s\n", p);


    printf("\n");
    printf("%d,%d\n", sizeof(int), sizeof(char));//4,1
    printf("%d,%d", sizeof(int*), sizeof(char*));//4,4

    return 0;
}

指针是一种数据类型
1) 指针也是一种变量,占有内存空间,用来保存内存地址
测试指针变量占有内存空间大小
2)*p操作内存
在指针声明时,*号表示所声明的变量为指针
在指针使用时,*号表示 操作 指针所指向的内存空间中的值
*p相当于通过地址(p变量的值)找到一块内存;然后操作内存
*p放在等号的左边赋值(给内存赋值)
*p放在等号的右边取值(从内存获取值)
3)指针变量和它指向的内存块是两个不同的概念
//含义1 给p赋值p=0x1111; 只会改变指针变量值,不会改变所指的内容;p = p +1; //p++
//含义2 给*p赋值*p=’a’; 不会改变指针变量的值,只会改变所指的内存块的值
//含义3 =左边*p 表示 给内存赋值, =右边*p 表示取值 含义不同
//含义4 =左边char *p
//含义5 保证所指的内存块能修改
4)指针是一种数据类型,是指它指向的内存空间的数据类型
含义1:指针步长(p++),根据所致内存空间的数据类型来确定
p++=(unsigned char )p+sizeof(a);
结论:指针的步长,根据所指内存空间类型来定。

void copy_str21(char *from, char *to)
{

    if (*NULL = '\0' || *to!=’\0’) 
    {
        Printf(“func copy_str21() err\n”);
        return; 
    }


    for (; *from!='\0'; from++, to++)
    {
        *to = *from;
    }
    *to = '\0';
}
//字符串逆序
int main()
{
    //char p[1024] ={0};
char *p  ={0}; p = NULL;

    char to[100];
    copy_str21(p, to);
//char *p = "abcd11111abcd2222abcdqqqqq"; 
//字符串中"abcd"出现的次数。
//写一个函数接口。
//完成功能为:求出“abcd”字串出现的次数
int getSubCount(char *str, char *substr, int *   mycount)
{
    int ret = 0;
    char *p = str;
    char *sub = substr;
    int count = 0;

    if (str==NULL || substr==NULL || mycount == NULL)
    {
        ret = -1;
        return ret;
    }

    //char *p = "abcd11111abcd2222abcdqqqqqabcd";
    //char *p2 = NULL;
    //p2 = p;
    do 
    {
        p = strstr(p, sub);
        if (p!= NULL)
        {
            count++;
            //++后缀操作符优先级高,所以先执行*p操作 然后地址++
            *mycount++;

            p = p + strlen(sub);
        }
        else
        {
            break;
        }
    } while (*p != '\0');
    //printf("count:%d \n", count);

    //mycount是实参的地址 *(实参的地址)
    *mycount = count;
    return ret;
}

const

int main()
{
const int a;  //
int const b; 

const char *c;
char * const d; char buf[100]
const char * const  e ;

return 0;
}

Int func1(const )
初级理解:const是定义常量==》const意味着只读
含义:
//第一个第二个意思一样 代表一个常整形数
//第三个 c是一个指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改)
//第四个 d 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
//第五个 e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值