内存四区模型与指针

数据类型的封装

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一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 16:29:10

内存四区模型与指针的相关文章

c语言内存四区模型

c语言内存四区模型:代码区,全局区(常量区),栈区,堆区 在全局区(常量区),两个字符串完全一样c++编译器只会定义一份 char * getBuf() { char buf[20]; strcpy(buf, "abcde"); return buf; } abcdX?  有乱码! 确实把内存地址返回了,但不能用 被调函数调用完毕,在临时区分配的内存统统消失 char *buf= (char *)malloc(sizeof(char)*20); 手动malloc申请一份内存,由程序员手

C语言的内存四区模型和函数调用模型

首先是操作系统将代码程序加载到内存中 然后将内存分为4个区 栈区,程序的局部变量区,函数传递的参数,由编译器自动进行内存资源的释放. 堆区,动态内存申请,如果不手动释放内存,则这块内存不会进行析构. 全局区,静态区,常量区(字符串存放的位置),程序结束后,有操作系统释放 代码区,存放函数体的二进制代码. 最后,操作系统找到main函数的入口,就开始代码的执行. 一般内存四区中的栈的开口方向是向下的.为什么要这样设计呢,因为设计栈的方向向下,可以给应用程序设定栈的大小,这样就可以避免栈溢出. 不管

内存四区模型

注:一个程序只建立一个内存四区,所有函数共用这个内存四区. 内存四区如下: 一.全局区 全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域, 该区域在程序结束后由操作系统释放: 常量区——字符串常量和其他常量的存储位置,程序结束后由操作系统释放. 在代码运行期间,C编译器会做优化处理, 1).当定义两个不同字符串时,全局区会开辟两个内存空间存放字符串, 2).当定义两个相同的字符串时,全局区只开辟一个内存空间,变

C语言提高之技术模型层次、学习标准、特点、内存四区、函数调用模型

1.C语言技术模型分层: 其中,接口的封装和设计尤为重要! 2.着重需要培养的能力 (1)接口的封装和设计(业务模型的抽象.功能抽象和封装) ---重中之重! a.接口api的使用能力: b.接口api的查找能力(快速上手): c.接口api的实现能力: // SOCKETCLIENT_H,一个简单信息系统的封装接口 #ifndef _SOCKETCLIENT_H #endif _SOCKETCLIENT_H #ifdef __cplusplus extern "C" { #endif

C语言 内存四区与函数调用模型

C语言提高笔记 标签(空格分隔): C++ C语言 day1 数组做函数参数的退回问题 数组做函数参数会退回为一个指针, 正确做法:把数组的内存首地址和数组的有效长度传给被调用函数. 实参的a 和 形参的a 的数据类型本质不一样, 形参中的数组,编译器会把它当成指针处理 只会分配四个字节. 形参写在函数上,和写在函数内是一样的,只不过是具有对外的属性而已. 数据类型本质分析 数据类型可理解为创建变量的模具(模子):是固定内存大小的别名: 数据类型的作用:编译器预算对象(变量)分配的内存空间大小

面向过程—面向对象(C++的封装,this)_内存四区_变量生命周期

1.面向对象主要涉及  构造函数.析构函数.虚函数.继承.多态等. 2.对各种支持 的底层实现机制 c语言中,数据 和 处理数据的操作(函数) 是分开来声明,即语言本身并没有支持 “数据和函数”的关联性. 在C++中,通过抽象数据类型(abstract data type, ADT),在类中定义数据和函数,来实现数据和函数直接的绑定. C++成员数据:static.nonstatic C++成员函数:static.nonstatic.virtual C++中的类class从面向对象理论出发,将变

C++ 数据类型提高+内存四区

# 这一章节全部是C语言的内容# 数据类型提高**注意**1.数组作为形参会退化为指针(验证,传参后用sizeof进行打印,可以看出打印出数组的字节为一字节)2.形参在函数上和函数内是一样的,只不过对外开放 # 内存四区 ##### 数组和数组元素指针```void main(){ int a;//告诉编译器分配4个字节内存 int b[10];//告诉编译器自己分配40个内存 printf("b:%d,b+1:%d,&b:%d,&b+1:%d",b,b+1,&

深入理解数据类型、变量类型属性、内存四区和指针

数据类型可理解为创建变量的模具(模子):是固定内存大小的别名. 数据类型的作用:编译器预算对象(变量)分配的内存空间大小. 既能读又能写的内存对象,称为变量:若一旦初始化后不能修改的对象则称为常量. 变量本质:(一段连续)内存空间的别名. 内存四区 栈区(stack):也叫临时区,由编译器自动分配释放,存放函数的参数值,局部变量的值等. 堆区(heap):一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回收. 全局区(静态区)(static):全局变量和静态变

C 提高1 内存四区 变量本质 栈开口方向 指针铁律1

C 提高第一天复习 内存四区,变量常量的本质,函数调用模型,栈开口方向,指针铁律1,指针是一种数据类型 C 提高学员标准:写一个标准的冒泡排序 选择法或者冒泡法排序 在一个函数内排序 通过函数调用的方式排序 数组做函数参数的技术盲点和推演 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int i = 0; int j = 0; int tmp = 0; int a[] =