首页 > 系统相关 >C语言中的指针:掌握内存的钥匙

C语言中的指针:掌握内存的钥匙

时间:2024-07-16 17:26:37浏览次数:19  
标签:变量 指向 元素 C语言 地址 内存 数组 指针

C语言中的指针:掌握内存的钥匙

引言

       C语言是一种结构化编程语言,它提供了对硬件底层的直接访问,其中最强大的特性之一就是指针。指针允许程序员直接操作内存地址,这对于理解程序的内部工作原理以及优化代码性能至关重要。本文将深入探讨C语言中指针的概念、使用方法以及一些高级技巧。

什么是指针

       指针就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其声明。

声明形式:

type *pointName;

其中type是指针的基类型,它必须是一个有效的C数据类型,pointName是指针变量的名称。用来声明指针的星号*与乘法中使用的星号是相同的,但是在c语句中,星号是用来指定一个变量是指针。
C语言中的指针
例如:指针简单使用
C语言中的指针
输出结果
C语言中的指针

指针与变量

内存区的每一个字节都有一个编号,这就是"地址",如果在程序中定义了一个变量,在对程序进行编译运行时,系统就会给这个变量分配一个内存单元,并确定它的内存地址也就是一串这个地址独有的编号,指针是内存单元的编号,指针变量是存放地址的变量,通常我们会把指针变量称为指针,其实指针与指针变量含义式不一样的。

指针变量赋值

指针变量在使用之前, 一定要先赋值,也就是让指针变量指向一个地址。注意,给指针变量赋值只能式地址,通过"&"符号来获取普通变量的地址。“&” - 取地址运算符,“*” - 指针运算符,或称为间接访问运算符,取地址的值。
例子:
C语言中的指针
输出结果:上面代码演示了如何在C语言中使用指针,第一步定义一个整型变量i和一个指向整型变量的指针p。然后将i的值初始化为10,并将p指向i的地址,然后打印出i,和p的内存地址以及i的值和通过指针p访问到的值。
C语言中的指针
i = 0x7ffd55fc953c 变量i的存储地址, p = 0x7ffd55fc953c是指针变量p指向的地址,以为代码中把i的地址赋给了p,所以p指向i的存储地址。i=10i赋值10*p = 10 指针变量p指向地址里的值,p指向的是地址0x7ffd55fc953c,而这个地址里存储的值为10,所以*p=10

通过地址取值:*((unsigned char *)p))

C语言中的指针
输出结果:((unsigned char *)7c3d726c))代表把 0x7c3d726c 这个值,强制转换成一个无符号字符类型指针,相当于告诉编译器,这是一个地址,强制转换的类型和变量a的数据类型保持一致,因为要通过地址,把变量i的值读出来,最后通过*把这个地址的数据读出来,结果7c3d726c = 10
C语言中的指针

通过指针改变某个内存地址里的值

上面说了如何获取内存地址的值,那也可以通过指针改变某个内存地址里面的值。格式: *指针变量 = 数值; 【*p = 20】
C语言中的指针
输出结果:
C语言中的指针
案例2:输入a和b两个整数,然后按先大后小顺序输出a和b。不交换整型变量的值,而是交换两个指针变量的值。
C语言中的指针
分析:输入a=5,b=6,由于a<b,将p1和p2交换,注意的是,a和b的值并未交换,他们仍然保持原值,但是p1和p2的值改变了,p1的值原来为&a,后来变成了&b, p2的值原来为&b后来变成了&a,这样在输出p1和p2的时候,实际上是输出了变量b和a的值,所以先输出6后输出5。
C语言中的指针

指针变量作为函数参数

函数的参数不仅可以是整型,浮点型,字符型,还可以是指针类型,它的作用将一个变量的地址传送到另一个函数中。

案例:通过指针类型的数据作为函数的参数,对输入的两个整数按大小顺序输出。【通过指针实现交换两个变量的值】
C语言中的指针
案例:输入三个整数a,b,c,要求按由大到小的顺序输出。
C语言中的指针

指针与一维数组

一个变量有地址,一个数组包含若干个元素,每个数组元素都在内存中占有存储单元,它们都有相应的地址,指针变量既然可以指向变量,当然也可以指向数组元素,把某一元素的地址放到一个指针变量中,所谓的数组元素的指针就是数组元素的地址。c语言定义数组时,编译器会分配连续地址的内存,来存储数组里的元素,实际上数组本质上也是指针。

分别打印了arr&arr[0]的地址,发现地址是一样的,既然是个地址,那就可以使用指针的形式,去访问地址里存储的值,然后打印*arr的值,得到的结果为1,正好和arr[0]的值对应,最后得出数组也可以使用指针的形式去使用。

数组元素的引用

        引用数组元素可以使用下标法,也可以使用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使程序质量高,占用内存少,运行速度快。

	p = &a; // p的值是a[0]的地址
	p = a; // p的值是数组a首元素即a[0]的地址

C语言中的指针
注意:程序中的数组名不代表整个数组,只代表数组首元素的地址。上面的p = a的作用是把a数组首元素的地址赋给指针变量p,而不是把数组a各元素的值赋给p,可以简写为 int *p = &a[0];也可以写成int *p = a; 也可以写成两行的形式int *p; p = &a[0];他们都有一个作用:将a数组首元素即a[0]的地址赋给指针变量p(而不是*p)。
C语言中的指针

  • 下标法 a[i]的形式
  • 指针法如*(a+i)*(p+i)。其中a是数组名,p是指向数组元素的指针变量。
    C语言中的指针
    或者用指针变量指向数组元素
    C语言中的指针
    注意:在使用指针变量指向数组元素的时候,可以通过改变指针变量的值指向不同的元素,例如上面代码中的方法是使用指针变量p来指向元素,用p++使p的值不断改变宠儿指向不同的元素。
    换一种想法,如果不用p变化的方法而用数组名a变化的方法如a++行不行呢。for(p=a;a<(p+10);a++) printf("%d",*a);答案是不行的,因为数组名a代表数组首个元素的地址,他是一个指针型常量,它的值在程序运行期间是固定不变的,既然a是常量,所以a++是无法实现的。
    例:通过指针变量输出整型数组a的10个元素。
    C语言中的指针
    很明显,输出的数值并不是a数组中各个元素的值,因为在执行第二个for循环读入数据后,p已指向a数组的末尾,因此在执行第二个for循环时候,p的起始值不是&a[0]了,而是a+10
    C语言中的指针
    解决上面问题只要在第二个for循环之前加一个赋值语句即可
    C语言中的指针

常用指针引用数组元素的情况

  • (1) p++; p; p++使p指向下一个元素a[i],然后再执行p,则得到下一个元素a[i]的值。
  • (2) p++; 由于++和同优先级,结合方向为自右而左,因此它等价于*(p++)。先引用p的值,实现*p的运算,然后再使p自增1。
  • (3) (p++)与(++p)作用,前者先取p值,然后使p加1。后者是先使p加1,再取p。若初始值为a即&a[0],若输出*(p++)得到a[0]的值,而输出*(++p)得到a[1]的值。
  • (4) ++(*p) 表示p所指向的元素值加1,如果p = a,则++(*p)相当于++a[0],若a[0]的值为3,则在执行++(*p)即++a[0]后的值为4。
  • (5) 如果p当前指向a数组中第i个元素a[i],则:
            *(p--) 相当于a[i--],先对p进行运算(求p所指向的元素的值),再使p自减。
            *(++p) 相当于a[++i],先使p自加,在进行
    运算。
            *(--p) 相当于a[–i],先使p自减,再进行*运算。
    将++和–运算符用于指针变量十分有效,可以使指针变量自动向前或向后移动,指向下一个或上一个数组元素。

在引用数组元素时指针的运算

在引入数组元素时会遇到指针的算术运算,当指针指向数组元素的时候,譬如指针变量p指向数组元素a[0],我想用p+1表示指向下一个元素a[1],如果能实现这种运算会对引用数组元素提供很大的便利。
在指针指向一个数组元素时可以进行以下运算

  • 加一个整数用+或者+=,如p+1
  • 减一个整数用-或者-=,如p-1
  • 自加运算,如p++,++p
  • 自减运算,如p--,--p
  • 两个指针相减,如p1-p2 如果p1p2都指向同一个数组中的元素时才有意义。
      解释:
        (1)如果指针变量p已经指向数组中的一个元素,则p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素,执行p+1时并不是将p的值或地址简单的加1而是加上一个数组元素所占用的字节数,例如数组元素是float型,每个元素占4个字节,则p+1意味着p的值是地址加上4个字节,使它指向下一个元素,p+1实际上代表p+1*dd是一个数组元素所占的字节数。
        (2)如果p的值为&a[0],则p+ia+i就是数组元素a[i]的地址,或者说他们指向a数组序号为i的元素。这里要注意的是a代表数组首元素地址,a+1也是地址,它的计算方法同p+1,即它的实际地址为a+1*d
        (3)*(p+i)*(a+i)p+ia+i所指向的数组元素,即a[i]。实际上在编译的时候,对数组元素a[i]就是按*(a+i)处理的,即按数组首元素的地址加上相对位移量得到要找的元素地址,然后找出该单元中的内容。
        (4)如果指针变量p1和p2都指向同意数组中的元素,如果执行p2-p1,结果是p2-p1的值两个地址之差,除以数组元素的长度。两个地址不能进行p1+p3是毫无意义的。
        
  • 指针的解引用:可以通过指针的解引用来访问它所指向的变量的值,解引用的操作符是"*",与乘法运算符不同。
    例如:
            int value = 10;
            int *p = &value;
            printf(“The value is %d”,*p); // 输出value的值
  • 指针的加减法:我们可以对指针进行加减操作,让指针移动到数组中的其他元素上。
            int arrPtr = arr;
            printf(“The second element is %d\n”,
    (arrPtr+1)); // 这里*(arrPtr+1)实际上就是指向数组第二个元素的地址,并解引用获取其值。
    值得注意的是,指针算数的步长取决于指针所指向的数据类型。例如arrPtr指向的是一个整型的指针,那么arrPtr+1实际上是在当前地址基础上加上了整型的大小。
  • 指针 - 指针 :得到的数值的绝对值是指针和指针之间元素的个数。
    C语言中的指针:掌握内存的钥匙

其他指针使用方法:

C语言中的指针

指针与一维数组地址关系

C语言中的指针
指针与一维数组值的关系
C语言中的指针

用数组名做函数参数的情况

第一种,数组元素做实参的情况,假设swap是将两个形参x,y进行交换使用

swap(a[0],a[1]);
void swap(int x,int y);

得出:与用变量作为实参的情况一样,是”值传递“方式,将a[0]a[1]的值单向传递给xy。当xy的值改变时a[0]a[1]的值不改变。

第二种: 数组名做函数形参的情况,实参数组名代表该数组首元素的地址,而形参是用来接受实参传递过来的数组首元素地址的。因此形参应该是一个只恨变量,只有指针变量才能存放地址,实际上c语言的编译都是将形参数组名作为指针变量来处理的。

void fun(int arr[],int n); === void fun(int *arr,int *n);

C语言中的指针
在函数被调用时,系统会在fun函数中建立一个指针变量arr,用来存放从主调函数传递过来的实参数组元素的地址。如果在fun函数中用运算符siezof确定arr所占字节数,可以发现sizeof(arr)的值为8,这就这个名了系统把arr作为指针变量来处理的。当arr接受了实参数组的首元素地址后,arr就指向实参数组的首元素,也就是指向了brr[0]。因此,arr就是brr[0]
注意: 实参数组名代表一个固定的地址,或者说是指针常量,但形参数组名并不是一个固定的地址,而是按指针变量处理。在函数调用进行虚实结合后,形参的值就是实参数组首元素的地址,在函数指向期间,它可以在被赋值。
C语言中的指针
常用这种方法通过调用一个函数来改变实参数组的值。

第三种:变量名做函数参数和用数组名做函数参数比较

  • 1.当实参类型是变量名时,要求形参类型也是变量名,通过形参传递的信息是变量的值,通过函数调用不能改变实参量的值。
  • 2.当实参类型是数组名时,要求形参的类型是数组名或者指针变量,通过形参传递的信息是实参数组首元素地址,通过函数调用能改变其实参变量的值。

总结 :说明c语言调用函数时虚实结合的方法都是采用“值传递”方式,当变量名作为函数参数时传递的是变量的值。当用数组名作函数参数的时候,由于数组名代表的是数组首元素的地址,因此传递的值是地址,所以要求形参为指针变量。

第四种:数组名和指针变量作为函数的形参,在c语言中,用下标法和指针法都可以访问一个数组,如果有一个数组a,则a[i]*(a+i)无条件等价,用数组名作形参,以便于实参数组对应,比较直观便于理解。从应用的角度看,用户可以认为有一个形参数组,他从实参数组哪里得到起始地址,因此形参数组与实参数组共占同一段内存单元,在调用函数期间,如果改变了形参数组的值,也就改变了实参数组的值,在主调函数中就可以利用这些已经改变的值。
例:将数组an个整数按相反顺序存放,用一个函数reversal来实现交换。实参用数组名a,形参可用数组名,也可以用指针变量。
C语言中的指针
上面代码中,在main函数中定义整型数组a,并赋初值,函数reversal形参数数组名为x。在定义reversal函数时,可以不指定形参数组x的大小。因为形参数组名实际上是一个指针变量,并不是真的开辟一个数组空间。reversal函数的形参n用来接受需要处理的元素个数。在main函数中有函数调用语句reversal(a,10);表示要求将a数组的10个元素颠倒排列。
改写上面代码 ,将reversal中的形参改成指针变量,函数reversal的形参有数组名x[]变为指针变量*x,相应的实参仍是数组名a,即数组a首元素的地址,将它传递给形参指针变量x,这个时候x就指向x[0]x+ma[m]元素的地址。
C语言中的指针
总结归纳:
C语言中的指针
C语言中的指针
C语言中的指针
C语言中的指针
例:用选择排序+指针方法对是个整数由大到小顺序排序:
C语言中的指针

通过指针引用多维数组

        指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素,多维数组的指针比一维数组的指针要复杂一些。

多维数组元素的地址

以二维数组为例:int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}a是二维数组名,a数组包含三行,即三个元素,每一行元素又是一个一维数组,它包含4个元素即4列元素。可以看出二维数组是数组的数组,即二维数组a是由3个一维数组组成的。
C语言中的指针
从二维数组角度来看,a代表二维数组首元素的地址,现在的元素不是一个简单的整型元素,而是由四个整型元素所组成的一维数组,因此a代表的是首行即序号为0的行的起始地址。a+1代表序号为1的行的起始地址。如果二维数组的首行的起始地址为2000,一个整型数据占4个字节,则a+1的值应该是2000+4*4=2016 因为第0行有4个整型数据。a+1指向a[1],或者说a+1的值是a[1]的起始地址。a+2代表a[2]的起始地址,它的值是2032
C语言中的指针
上面说了如何表示首行地址,那么a[0]是一维数组名,该一维数组中序号为1的元素的地址显然应该用a[0]+1来表示。此时a[0]+1中的1代表一列元素的字节数,即4个字节。a[0]的值是2000,a[0]+1的值是2004而不是2016,这是因为现在在一维数组范围内讨论问题的,正如有一个一维数组x,x+1是其第一个元素x[1]的地址一样。a[0]+0,a[0]+1,a[0]+2,a[0]+3分别是a[0][0],a[0][1],a[0][2],a[0][3]元素的地址,即(&a[0][0],&a[0][1],&a[0][2],&a[0][3])
C语言中的指针
一维数组与指针的时候已经说了a[0]*(a+0)无条件等价,a[1]*(a+1)无条件等价,a[i]*(a+i)无条件等价。因此a[0]+1*(a+0)+1都是&a[0][1]a[1]+2*(a+1)+2的值都是&a[1][2]。但是要注意不要将*(a+1)+2错写成*(a+1+2),后者相当于a[3]
        再深一步解析,既然a[0]+1*(a+0)+1a[0][1]的地址,那么*(a[0]+1)就是a[0][1]值。同理,*(*(a+0)+1)*(*a+1)也是a[0][1]的值。*(a[i]+j)*(*(a+i)+j)a[i][j]的值。*(a+i)a[i]是无条件等价。
        a[i]从形式上看是a数组中序号为i的元素。如果a是一维数组名,则a[i]代表a数组序号为i的元素存储单元。a[i]是一个有确定地址的存储单元。但是如果a是二维数组,则a[i]是一维数组名,它只能是一个地址,并不代表一个存储单元,也不代表存储单元中的值如同一维数组名只有一个指针常量一样。a,a+i,a[i],*(a+i),*(a+i)+j,a[i]+j都是地址,而*(a[i]+j)*(*(a+i)+j)是二维i数组元素a[i][j]的值。
下面是二维数组常用a的有关指针:
C语言中的指针根据上面解释,输出二维数组的有关数据【地址和元素的值】
C语言中的指针
案例:根据输入数组下标,显示二维数组中的值
C语言中的指针

用指向数组的指针作为函数参数

一维数组名可以作为函数参数,多维数组名也可以做函数参数,用指针变量作形参,以接受实参数组名传递来的地址,两种方法:

i. 用指向变量的指针变量。
ii. 用纸箱一维数组的指针变量。

例:一个班级,三个学生,各4门课,计算总平均分数以及第n个学生的成绩。
C语言中的指针
代码解释:先调用average函数求平均值。在函数average中,形参p被升为float *类型指向float型变量的指针变量,它的基类型是float型,实参用*score,即score[0]也就是&score[0][0],即score[0][0]的地址。把score[0][0]的地址传给p,使p指向score[0][0]。然后在average函数中使用p先后指向二维数组的各个元素,p每加1就改为指向score数组的下一个元素。
C语言中的指针
函数search的形参p的类型是float(*)[4],他不是指向整型变量的指针变量,而是指向包含4个元素的一维数组的指针变量。函数开始调用时,将实参score的值也就是数组0行的起始地址传给p,使p也只想score[0]
注意:实参与形参如果是真真类型,应当注意他们的基类型必须一致,不应把int *型的指针即数组元素的地址传递给int(*)[4]型(指向一维数组)的指针变量,反之亦然。
例:在上面的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。
C语言中的指针
代码分析:实参score和形参p的类型是相同的。在调用search函数时,p得到实参score的值,即score[0]的起始地址,也就是说p也指向score数组的第一行。然后p先后指向隔行包括每行学生的几门课的成绩。

通过指针引用字符串

字符串的引用方式

在c语言中,字符串是存放在字符数组中的,像引用字符串有两种方法

  1. 用字符数组存放一个字符串,可以通过数组名和下标引用字符串中一个字符,也可以通过数组名和格式声明%s输出该字符串。
    C语言中的指针
    实际上string[7]就是*(string+7),string+7就是一个地址,它指向字符“C”.
  2. 用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。
    C语言中的指针
    在上面代码中没有定义字符数组,只定义了一个char *型的字符指针变量string,用字符串常量"I love China!"对它初始化。c语言对字符串常量是按字符数组处理的,在内存中开辟一个字符数组用来存放该字符串常量,但是这个字符数组是没有名字的,因此不能通过数组名来引用,只能通过指针变量来引用。
    注意: 有人误认为string是一个字符串变量,以为在定义时把"I love China!"这几个字符赋给该字符串变量,这是不对的,在C语言中只有字符变量,没有字符串变量。string被定义一个指针变量,基类型为字符型。它指能指向一个字符类型数据,而不能同时指向多个字符数据,更不是把I love China!这些字符存放到string中,也不是把字符串赋给*string,只是把I love China! 的第一个字符的地址赋给指针变量string

例:将a串复制为字符串b,然后输出字符串b。
C语言中的指针
程序分析:程序中a和b都定义为字符数组,通过地址访问其数组元素。在for语句中先检查a[i]是否为'\0'。如果不等于'\0',表示字符串尚未处理完成,就将a[i]的值赋值给b[i],即复制一个字符串。

例:将a串复制为字符串b,然后输出字符串b。(用指针变量来处理)
C语言中的指针
代码解析p1p2时指向字符型数据的指针变量,现使p1p2分别指向字符串ab的第一个字符。*p1最初的值时字母“I”。赋值语句*p2 = *p1的作用是将字符串I赋值给篇所指向的元素,即b[0]。然后p1p2分别加上1,分别指向其下面的一个元素,知道碰到'\0'为止。

字符指针作函数参数

如果想把一个字符串从一个函数"传递"到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。

  1. 字符数组名作为函数参数
    例:用函数调用实现字符串的复制,用字符数组名作为函数参数。
    C语言中的指针
    程序分析:ab时字符数组,copy_string函数的作用是将from[i]赋给to[i],直到from[i]的值等于'\0'为止。
  2. 用字符型指针变量作实参
    C语言中的指针
    分析: 指针变量from的值时a数组首元素的地址,指针变量to的值时b数组的首元素的地址。他们作为实参,把a数组首元素的地址和b数组首元素的地址传递给形参数组名fromto(它们实质上也是指针变量)。
  3. 用字符指针变量作形参和实参
    C语言中的指针
    分析: 形参使用char *类型变量即字符指针变量,main函数中a时字符指针变量,指向字符串"I am a teacher"的首字符。b时字符数组,在其中存放了字符串"You arr a student."p是字符指针变量,它的值是b数组第一个元素的地址,因此也指向字符串"You are a student."的首字符。copy_string函数的形参fromto是字符指针变量,再调用copy_string的时候,将数组a首元素地址传递给from,把指针变量p的值即数组b元素的地址传给to。因此form指向a串的第一个字符a[0],to指向b[0],在for循环中,先检查from当前所指向的字符是否为'\0',如果不是,表示需要复制此字符,就执行*to = *from,每次将*from的值赋给*to,一致遇到'\0'结束。
    其实上面的字符串复制还可以写很多形式,如下
    C语言中的指针
    输出结果都是
    ![C语言中的指针(https://i-blog.csdnimg.cn/direct/6bdbe065eafa45ce928478f034eccabb.png)

调用函数时实参与形参的对应关系

C语言中的指针

使用字符指针变量和字符数组的比较

用字符数组和字符指针变量都能实现字符串的存储和运算,但它们二者之间是有区别的,不应混淆,主要区别如下:

  • a.字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第一个字符的地址),绝不是将字符串放到字符指针变量中。
  • b.赋值方式,可以对字符指针变量赋值,但是不能对数组名赋值。
  • c.初始化的含义,对字符指针变量赋初始值,数组可以在定义时对个元素赋初始值,但不能用赋值语句对字符数组中全部元素整体赋值。
  • d.存储单元的内容。编译时字符数组分配若干个存储单元,以存放各元素的值,而对字符指针变量,只分配一个存储单元。
  • e.指针变量的值是可以改变的,而字符数组名代表一个固定的值(数组元素的地址)不能改变。
  • f.字符数组中各元素的值是可以改变的(可以不对他们再赋值),但字符指针变量指向的字符串常量中的内容是不可以被取代的(不能对他们再赋值)。
  • g.引用数组元素,对字符数组可以使用下标法(用数组名和下标)引用一个数组元素,也可以使用地址法(如*(a+5))引用数组元素a[5],如果定义了字符指针变量p,并使它指向数组a的首地址,则可以用指针变量带下标的形式引用数组元素(如p[5]),同样可以用地址法(如*(p+5))引用数组元素a[5],但是如果指针变量没有指向数组,则无法用p[5]*(p+5)这样的形式引用数组中的元素。这是若输出p[5]或者*(p+5)这样的引用形式引用数组中的元素。这时若输出p[5]*(p+5),系统将输出指针变量p所指的字符后面5个字节的内容。
  • h.用指针变量指向一个格式字符串,可以用它们替代printf函数中的格式字符串。
    C语言中的指针
    因此只要改变指针变量format所指向的字符串,就可以改变输入输出的格式。这种printf函数称为可变格式输出函数。如:
    C语言中的指针
    因此,用指针变量指向字符串的方式更为方便。

指向函数的指针

持续更新中。。。

标签:变量,指向,元素,C语言,地址,内存,数组,指针
From: https://blog.csdn.net/qq_42696432/article/details/140436883

相关文章

  • C语言指针详解(初级)
    1.指针是什么?指针理解的2个要点:        1.指针是内存中一个最小单元的编号,也就是地址(&)        2.平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量总结:指针就是地址,口语中说的指针通常指的是指针变量。那我......
  • C++(函数参数为数组与指针算术)
    目录1.函数参数为数组2.指针算术2.1arr是指向第一个元素的地址2.2arr[i]表示什么?#include<iostream>voidprintArray(intarr[],intsize){for(inti=0;i<size;++i){std::cout<<arr[i]<<"";}}intmain(){intarr[5]......
  • C语言网络编程(一对多通讯)
    使用C语言实现一个服务器对多个客户端主要技术除了网络编程几个函数的使用外,还用到了线程,实现方式是一个客户端对应一个新的线程Server:#include<pthread.h>//包含线程库的头文件#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h......
  • C++ 用智能指针这样包装 this 指针是否可行
    #include<iostream>#include<memory>usingnamespacestd;classA;classB{public:B(shared_ptr<A>a){pa=a;cout<<"B构造..."<<endl;}~B(){cout<<&quo......
  • 底软驱动 | 大厂面试爱考的C++内存相关
    文章目录C++内存相关C++内存分区C++对象的成员函数存放在内存哪里堆和栈的区别堆和栈的访问效率“野指针”有了malloc/free为什么还要new/deletealloca内存崩溃C++内存泄漏的几种情况内存对齐柔性数组参考推荐阅读C++内存相关本篇介绍了C++内存相关的知识。C++......
  • 虚函数表 和 虚函数指针
     虚函数指针vptr大小x86平台下为4个字节,x64平台下为8个字节例题:涉及内存对齐 答案:32位miaoage=264位miaoage=1核心在这句话上p【1】=q【1】;由于两个子类都继承自有虚函数的基类因此都带有虚表指针首先基类中只有一个int432位下,虚表指针也是4......
  • 4、设计共享内存管理接口
    初级代码游戏的专栏介绍与文章目录-CSDN博客我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。    系统做大了增加很多管理功能是不可避免的,绝不只是几个......
  • Swift开发基础07-内存布局
    了解Swift的内存布局和底层原理对于编写高性能和内存高效的应用非常重要。接下来,我将更详细地介绍Swift的内存管理机制和一些底层实现细节,包括内存布局、ARC(自动引用计数)、引用类型和值类型的区别,及其在底层的实现。内存布局(MemoryLayout)栈(Stack)栈内存用于存储函数调用帧(Call......
  • 嵌入式C语言指针面试题大全(持续更新)
    什么是指针?指针在C语言中的作用是什么?在C语言中,指针是一种变量类型,它存储的是其他变量或数据结构的内存地址,而不是实际的数据值。指针允许程序员直接操作和管理内存,这是C语言的一个重要特性,也是它能够高效地处理资源和进行底层编程的原因之一。指针在C语言中有多种作用,包括......
  • C语言 ——— 浮点数类型 在 内存中 的 存储模式
    浮点数存储规则根据国际标准IEEE754(电气和电子工程协会)规定:任意一个浮点数F的二进制都可以表示成以下形式:科学计数法(-1)^S*M*2^E解析科学计数法: 1.解析:(-1)^S(-1)^S 表示的是浮点数F的符号位当S=0时,原式=(-1)^0= 1,此时的 1就表示浮点数F为......