C语言的指针类型详细解析_C 语言

指针存储了内存的地址,同时指针是有类型的,如int*,float*,那么,一个自然的猜想就是指针变量应该存储这两方面的信息:地址和指针类型,比如,就像下面的结构体:

复制代码 代码如下:

struct pointer{
    long address;
    int type;
}

举个例子:打印sizeof(int*),值为4,可见4字节是存储内存地址用的,反过来就说明指针并没有存储类型信息的地方,那么指针的类型信息存放在哪儿呢?
下面剖析一段简单的代码。

复制代码 代码如下:

// ma.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
char gi;
char *pi;

void main()
{
pi=&gi;
*pi=12;
}

反汇编结果:

复制代码 代码如下:

pi=&gi;
0041137E C7 05 78 71 41 00 7C 71 41 00 mov         dword ptr [pi (417178h)],offset gi (41717Ch)
*pi=12;
00411388 A1 78 71 41 00   mov         eax,dword ptr [pi (417178h)]
0041138D C6 00 0C         mov         byte ptr [eax],0Ch
}

可见byte就说明了指针类型的信息。
总结:C语言的指针类型包括两方面的信息:一是地址,存放在指针变量中;二是类型信息,关乎于读写的长度,没有存储在指针变量中,位于用该指针读写时的mov指令中,不同的读写长度对应的mov指令不同。

另外:在指针强制转换时,也是这个原理。就是指针强制转换的影响不是在转换的时候发生,而是在用转换后的身份去访问内存时体现到了指令中。

那么指针在什么情况下转换是安全的呢?就是看用这个转换后的身份去访问内存是否安全。简要的说有以下原则:如果转换后指针指向的数据类型大小小于原数据类型大小,那么用该转换后的指针访问就不会越过原数据的内存,是安全的,否则危险,要越界。

时间: 2024-10-27 12:53:38

C语言的指针类型详细解析_C 语言的相关文章

C#委托所蕴含的函数指针概念详细解析_C 语言

原则: 1.函数指针,实际上是函数编码后的指令在内存中的首地址,在C++/C中,这个地址可以用函数名直接使用 一个函数调用另一个函数的时候,就可以把被调用函数以函数指针的形式作为参数传入 2.回调函数callback使用的技术就是函数指针: 回调函数就好像是一个中断处理函数,系统在符合你设定的条件时自动调用.为此,你需要做三件事: 1). 声明: 2). 定义: 3). 设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于DLL调用. 回调函数是应用程序提供给Windo

C语言static修饰函数详细解析_C 语言

在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条.介绍它的第一条也是最重要的一条:隐藏.当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.为理解这句话,我举例来说明.我们要同时编译两个源文件,一个是a.c,另一个是main.c. 下面是a.c的内容 复制代码 代码如下: char a = 'A'; // global variablevoid msg() {    printf("Hello\n"); } 下面是main.c的

C++指向类成员函数的指针详细解析_C 语言

首先 函数指针是指向一组同类型的函数的指针:而类成员函数我们也可以相似的认为,它是指向同类中同一组类型的成员函数的指针,当然这里的成员函数更准确的讲应该是指非静态的成员函数.前者是直接指向函数地址的,而后者我们从字面上也可以知道 它肯定是跟类和对象有着关系的. 函数指针实例: 复制代码 代码如下: typedef int (*p)(int,int);//定义一个接受两个int型且返回int型变量的函数指针类型int func(int x,int y){ printf("func:x=%d,y=%

c++中的4种类型转化方式详细解析_C 语言

具体归纳如下: (1)reinterpret_cast该函数将一个类型的指针转换为另一个类型的指针.这种转换不用修改指针变量值存放格式(不改变指针变量值),只需在编译时重新解释指针的类型就可做到.reinterpret_cast 可以将指针值转换为一个整型数,但不能用于非指针类型的转换.例://基本类型指针的类型转换double d=9.2;double* pd = &d;int *pi = reinterpret_cast<int*>(pd);  //相当于int *pi = (in

C++中的friend函数详细解析_C 语言

为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率.如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数.具体来说:为了使其他类的成员函数直接访问该类的私有变量.即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数. 实际上具体大概有下面两种情况需要使用友元函数:(1)运算符重载的某些场合需要使用友元.(2)两个类要共享数据的时候. 使用友元函数的优缺点 优点:能够提高效率,表达简单.清晰. 缺点:友元函数破环

C++ new/delete相关知识点详细解析_C 语言

每个程序在执行时都占用一块可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的自由存储区(free store)或堆(heap).C语言用一堆标准库函数malloc和free在自由存储区中分配存储空间,而C++则用new和delete表达式实现相同的功能. 一.new和delete创建和释放动态数组:数组类型的变量有三个重要的限制:数组长度固定,在编译时必须知道其长度,数组只在定义它的语句内存在.动态数组:长度固定,编译时不必知道其长度,通常是运行时确定:一直存在,直到程序显示释放它.

用typedef定义类型详细总结_C 语言

除了可以直接使用C提供的标准类型名(如:int ,char ,float,double,long等)和自己声明的结构体.共用体.枚举类型外,还可以使用typedef声明 新的类型名 来代替 已有的 类型名.如: typedef int INTEGER; typedef float REAL; 指定用INTEGER代表int类型,REAL代表float类型,这样,下面的两行等价: 1)int i,j;  float a,b; 2)INTEGER i,j;   REAL a,b; 可以声明结构体类型

C语言 if else 语句详细讲解_C 语言

前面我们看到的代码都是顺序执行的,也就是先执行第一条语句,然后是第二条.第三条--一直到最后一条语句. 但是对于很多情况,顺序结构的代码是远远不够的,比如一个程序限制了只能成年人使用,儿童因为年龄不够,没有权限使用.这时候程序就需要做出判断,看用户是否是成年人,并给出提示. if-else语句 在C语言中,使用if和else关键字进行判断.请先看下面的代码: #include <stdio.h> int main() { int age; printf("请输入你的年龄:"

指向变量的常指针与指向常变量的指针详细解析_C 语言

常(量)指针常指针就是我们说的指向常量的指针,顾名思义,它是用来指向常量的. 用常指针指向常变量实际上,C++规定只能用指向常变量的指针指向常变量,普通指针指向它就会报错,原因也很容易理解,我们用普通指针指向常变量之后,有可能就会进行改变常变量数值的操作,这样做是不被允许的. 常指针的定义方法: 复制代码 代码如下: const 类型名  * 常指针名; 下面是它的一个简单的使用示例:程序1.1.1 复制代码 代码如下: #include<iostream>using namespace st