04内存与指针

文章详细阐述了内存的五大分区,包括栈区、堆区、全局区(静态区)、文字常量区和代码区,并举例说明了C/C++程序中不同类型的变量在内存中的分布。同时,讲解了指针的概念,包括常量指针、指针常量和两者皆常量的用法。此外,还讨论了数组的基本概念,包括一维和二维数组的特性。最后,提到了利用异或法解决找出数组中只出现一次的数字的问题。
摘要由CSDN通过智能技术生成

一、内存

1.五大区

内存这里详细情况可以参考五大内存分区(笔记)_内存有那5部分_深海中的咸鱼的博客-CSDN博客计算机内存五大分区(笔记)_内存有那5部分https://blog.csdn.net/weixin_44364057/article/details/126541545

一个由C/C++编译的程序占用的内存分为以下几个部分 :堆区、栈区、全局区(静态区)、文字常量区、代码区五部分

 在执行一个C/C++语言程序时,此程序将拥有唯一的“内存四区”——栈区、堆区、全局区、代码区。每个程序都有唯一的四个内存区域。

        1、一个可执行程序在存储(没有调入内存)时分为代码段、静态区和文字常量区三部分;

        2、可执行程序(调入内存后)在运行时又多出两个区域:栈区和堆区。

int   a   =   0;   存放在全局初始化区
 
char   *p1;   存放在全局未初始化区
 
main()
 
{
 
int   b;   栈区
 
char   s[]   =   "abc";   栈区
 
char   *p2;   栈区
 
char   *p3   =   "123456";   123456\0在常量区,p3在栈区。
 
static   int   c   =0;   全局(静态)初始化区
 
p1   =   (char   *)malloc(10);
 
p2   =   (char   *)malloc(20);
 
分配得来得10和20字节的区域就在堆区。
 
strcpy(p1,   "123456");   123456\0放在常量区,编译器可能会将它与p3所指向的
                            "123456"优化成一个地方。
 
}

2.全局区的一些细节

全局区也叫静态区,全局区比较特殊,里面还分成了全局变量区,静态变量区,常量区。全局变量区用来存放全局变量,静态变量区用来存放带有static修饰的变量(包括静态局部变量和静态全局变量),只要含有static就存在这个区。全局变量和静态变量的主要区别是看作用域。常量区是用来存放字符常量的,还有const修饰的全局变量的,const 修饰的局部变量不存在这里,别搞混了。全局区存放的一切都是由操作系统管理,等程序结束由操作系统释放。常量区里存放的数据不可更改,就算你用指针也不行,你可能会说const修饰的局部变量都可以用指针改,但是局部变量可不是存放在常量区,这点搞清楚。

3. 堆区栈区的区别

* 生长方向不同,堆区栈区空间都是弹性大小,堆区从高到低,栈区从低到高
* 分配方式不同,堆区是人为申请的,栈区是操作系统根据类型自动分配
* 分配效率不同,栈区变量在函数启动时,就会分配好空间,堆区空间,执行到代码时才会分配
* 存储内容不同,栈区相对来说空间小,通常存放临时变量,堆区空间大,适合创建大数据量
* 管理方式不同,堆区人为管理,人为回收空间,栈区是操作系统自动管理
* 能否产生碎片,栈区不会产生碎片,堆区人为可能会产生碎片。

二、指针

1.一些基本概念

指针:就是一个装地址的变量  指针自身也是有地址的 指针里面装的地址目的是可以访问该地址指向的空间。

这里详细可见【c++】指针_c++指针_小田加油!!的博客-CSDN博客

1.定义指针

语法:数据类型 *指针变量名;eg:int *p;

让指针记录变量a的地址                   p=&a;

2.使用指针

可以通过解引用(指针前面加个*)的方式来找到指针指向的内存,即代表的是指针指向内存中的数据。

3.const修饰指针

1.const修饰指针----常量指针

eg:int a=10;int b=20; const int *p=&a;(const后面是int *,所以*的操作不能做)

特点:指针的指向可以修改,指针指向的值不可以修改

*p=20;--错

p=&b;--对

2.const修饰常量----指针常量

eg:int * const p=&a;(const后面是p,所以p的操作是错的)

特点:指针的指向不可以修改,指针指向的值可以修改

3.即修饰指针又修饰常量

eg:const int * const p=&a;(const后面是int *,const 后面也是p)

特点:指针的指向不可以修改,指针指向的值不可以修改

2.一些与指针相关的例题

1.

void fun(char * q)
{
    q=malloc(100);
}
int main(){
    char * p =NULL;
    fun(p);
    strcpy(p,"Hello");
}

这样的话会直接崩溃,C语言里,fun(p)是函数参数传递,只有值传递和地址传递,C++才有引用。

这里p是char *指针 q也是char*指针,二者类型相同,就是把内容给拷贝过去,是值传递。

要改成这样的形式才能够正常的传递。

void fun(cahr ** q)
{
    *q=malloc(100);
}
int main()
{
    char * p =NULL;
    fun(&p);
    strcpy(p,"Hello");
}

2.

void fun(char * q)
{
    strcpy(q,"Hello");
}
int main(){
    char * p =malloc(100);
    fun(p);
    printf(p);
}

这个没啥问题 可以正常传递。

3.

char* fun()
{
    char q[100];
    return q;
}
int main()
{
    char*p=NULL;
    p=fun();
    strcpy(p,"Hello");
}

这个不行,这个申请的空间是在栈区申请的,出了栈区就被回收掉了,所以没法运行。

三、数组

1.一些数组的基本概念

以一维数组 array[3] = {0, 1, 2} 为例。

1、数组的首元素地址

    &array[0]

2、数组的地址

    &array

3、数组名 array 代表数组首元素的地址

    即 array  与  &array[0] 等价

2.一些与数组相关的问题

1.int arr[ ]={1,2,3,4,5};

这里*(arr+1)=2;

*(arr++)=? 这个是错的

arr只是数组第一个元素的首地址

+1可以 ++不行 因为++相当于 arr=arr+1 是个赋值过程 但是她是常量 不能赋值

*(&arr+1)=? 这里的话
&arr相当于整个数组的首地址   &arr这里是int[5],5个int的空间, 也是整个数组的指针 *(&arr+1) 会直接偏移到整个数组的后面 你就不知道是啥了

2.*((int*)((int)&arr+1))

这里的+1不是偏移 就只是数字+1

这里有两个考点,一个是强制类型转换,一个是大小端。

注意整个数组的首地址跟首个元素的首地址值是一样的

小端存储 低字节存进地址里

0000 00010000 00000000 00000000 00000000 00100000 00000000 00000000 0000

0x10          0x11               12                13               

这里的话就是地址+1 即首地址变成0x11

然后是*访问地址  地址是int型的 所以要访问4个字节

访问到的就是

0000 00000000 00000000 00000000 0010

又因为是小端存储,读的时候读取到的就是0000 0010 0000 0000 0000 0000 0000 0000

即2^25

3.二维数组

int a[5][2]={1,2,3,4,5,6};

int (*p)[2]=a;

a就是首元素的首地址 就是{1,2} 是一个int[2]型的 故其指针是int(*p)[2]。

这里如果是int a[5][2]={{1,2},{3,4},{5,6}};

a[1][0]=3;

但是如果是int a[5][2]={(1,2),(3,4),(5,6)};

a[1][0]=6。这里是经典的逗号表达式。因此实际上a[5][2]={2,4,6};

逗号表达式,是c语言中的逗号运算符,优先级别最低,它将两个及其以上的式子联接起来,从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值。如:(3+5,6+8)称为逗号表达式,其求解过程先表达式1,后表达式2,整个表达式值是表达式2的值,如:(3+5,6+8)的值是14;a=(a=3*5,a*4)的值是60,其中(a=3*5,a*4)的值是60, a的值在逗号表达式里一直是15,最后被逗号表达式赋值为60,a的值最终为60。

四、找到只出现一次的数字

1.一组数据,其中一个元素仅出现一次,其他元素均出现两次,请找出只出现一次的元素

这里的话可以用三种方法

1.排序法

2.计数法

3.异或法

2.一组数据,其中有两个元素仅出现一次,其他元素均出现两次,请找出只出现一次的元素

在异或法的基础上进行,步骤为

1.整体进行异或

2.找到非0位

3.根据非0位分组各组异或

3.一组数据,其中有两个元素仅出现一次,其他元素均出现两次,请找出只出现一次的元素(附加 -2147483648如果在数组里怎么办?)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值