C语言_地址与指针类型不兼容造成的影响

【C语言】指针详解:概念、类型与解引用 在C语言中,指针是一个至关重要的概念。理解指针是理解C语言内存管理和高效编程的基础。指针使得程序可以直接操作内存,进行动态内存分配和高效的数据访问。许多C语言程序设计中的高级操作都依赖于指针,如数组操作、字符串处理以及函数传参等。 本篇文章将详细介绍C语言中的指针,涉及指针的定义、指针类型、指针的解引用操作、指针的实际应用等内容,帮助你深入理解指针在C语言中的作用。 2025.2.4-✍115min 阅读详情

地址与指针类型不兼容造成的影响

最近在复习C语言的语法,复习到指针的时候,看到自己的笔记写着“指针类型要与地址兼容”,换句话说就是“指针类型和所指数据的类型要一致”,当时还在旁边配着一小段代码。

int num01 = 18;
double num02 = 3.14;
int* point01 = &num01;		//√
double* point02 = &num02;	//√
double* point03 = &num01;	//×

假设我非要用double类型的指针指向int型的变量,“地址与指针类型不兼容”会造成什么影响呢?

接下来我们来写一个程序。

#include "stdio.h"

int main() {
    /*
     * 32位机,int类型占4个字节
     * 十六进制:0x 00 11 11 11
     * 十进制:1118481
     * 二进制:0b 00000000 00010001 00010001 00010001
     */
    int intNum = 1118481;
    int* intPoint = &intNum;
    //char型指针指向int型变量
    char* charPoint = &intNum;
    printf("===================\n");
    printf("sizeof(intPoint) = %d\n", sizeof(intPoint));
    printf("sizeof(charPoint) = %d\n", sizeof(charPoint));
    printf("===================\n");

    printf("intPoint: %p\n", intPoint);
    printf("charPoint: %p\n", charPoint);
    printf("===================\n");

    intPoint++;
    charPoint++;
    printf("intPoint++: %p\n", intPoint);
    printf("charPoint++: %p\n", charPoint);
    printf("===================\n");

    char charNum = 'a';
    //int型指针指向char型变量
    intPoint = &charNum;
    charPoint = &charNum;
    printf("intPoint: %p\n", intPoint);
    printf("charPoint: %p\n", charPoint);
    printf("===================\n");

    intPoint++;
    charPoint++;
    printf("intPoint++: %p\n", intPoint);
    printf("charPoint++: %p\n", charPoint);
    printf("===================\n");
    return 0;
}
/*
结果:
1、32位机,用4字节存储地址,所有sizeof都为4
sizeof(intPoint) = 4
sizeof(charPoint) = 4

2、两个指针都指向同一个地址,即0x 00 B3 F9 E0
intPoint: 00B3F9E0
charPoint: 00B3F9E0

3、因为int类型占4个字节,char类型占1个字节。
所以int型指针的增量为4字节,char型指针为1字节
intPoint++: 00B3F9E4
charPoint++: 00B3F9E1

4、两个指针都指向同一个地址,即0x 00 B3 F9 E0
intPoint: 00B3F9BF
charPoint: 00B3F9BF

5、因为int类型占4个字节,char类型占1个字节。
所以int型指针的增量为4字节,char型指针为1字节
intPoint++: 00B3F9C3
charPoint++: 00B3F9C0
*/

在这里插入图片描述

由上可得,程序可以编译并且运行成功。重点是int型的指针和char型指针同时指向同一个变量时,最初指针变量的值(即指向的地址)都是一样的,但是执行完自增操作后值就不同了。

为何呢?

指针的两个语义:一是内存的基地址,即变量存放的地址;二是指向数据的类型,即变量所占的内存空间。

如我刚刚演示的程序,在32位的环境下,int型占4个字节,所以int型的指针自增就是以4个字节为增量。


接下来,我们再举一个列子来说明,类型不兼容的影响。

32位机,int类型占4个字节
我们用8个字节,即2个int型或者8个char型来实验
    
int型数字1:
十六进制:0x 41 42 43 44
十进制:0d 1094861636
二进制:0b 01000001 01000010 01000011 01000100
    
int型数字2:
十六进制:0x 45 46 47 48
十进制:0d 1162233672
二进制:0b 01000101 01000110 01000111 01001000
    
8 个char型变量与其对应的二进制、十进制
'A'  --> 0b 01000001  -->  0d 65
'B'  --> 0b 01000010  -->  0d 66
'C'  --> 0b 01000011  -->  0d 67
'D'  --> 0b 01000100  -->  0d 68
'E'  --> 0b 01000101  -->  0d 69
'F'  --> 0b 01000110  -->  0d 70
'G'  --> 0b 01000111  -->  0d 71
'H'  --> 0b 01001000  -->  0d 72
#include "stdio.h"

void printChar(char* start, char* end);

void printInt(int* start, int* end);


int main() {
    printf("=================================\n");
    char charArr[8] = { 'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A' };
    printf("sizeof(charArr)/sizeof(char) = %d\n", sizeof(charArr) / sizeof(char));
    printf("sizeof(charArr)/sizeof(int) = %d\n", sizeof(charArr) / sizeof(int));
    printf("=================================\n");
    //char型指针指向char型变量
    char* charPoint01 = charArr;
    //int型指针指向char型变量
    int* intPoint01 = charArr;

    printChar(charPoint01, charPoint01 + sizeof(charArr) / sizeof(char));
    printInt(intPoint01, intPoint01 + sizeof(charArr) / sizeof(int));
    printf("=================================\n");

    int intArr[2] = { 1162233672, 1094861636 };
    printf("sizeof(intArr)/sizeof(char) = %d\n", (sizeof(intArr)) / sizeof(char));
    printf("sizeof(intArr)/sizeof(int) = %d\n", sizeof(intArr) / sizeof(int));
    printf("=================================\n");
    int* intPoint02 = intArr;
    char* charPoint02 = intArr;
    printChar(charPoint02, charPoint02 + 8);
    printInt(intPoint02, intPoint02 + sizeof(charArr) / sizeof(int));
    printf("=================================\n");
    return 0;
}

void printChar(char* start, char* end) {
    while (start < end) {
        printf("%c   ", *start);
        start++;
    }
    printf("\n");
}

void printInt(int* start, int* end) {
    while (start < end) {
        printf("%d   ", *start);
        start++;
    }
    printf("\n");
}

/*
结果:
=================================
sizeof(charArr)/sizeof(char) = 8
sizeof(charArr)/sizeof(int) = 2
=================================
H   G   F   E   D   C   B   A
1162233672   1094861636
=================================
sizeof(intArr)/sizeof(char) = 8
sizeof(intArr)/sizeof(int) = 2
=================================
H   G   F   E   D   C   B   A
1162233672   1094861636
=================================
*/

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nm6ZYIjq-1651587040629)(E:\Blog\C语言\地址与指针类型不兼容造成的影响.assets\image-20220503220039270.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OHt2ZmpH-1651587040629)(E:\Blog\C语言\地址与指针类型不兼容造成的影响.assets\B77D75137C78F5B3187117B349520427.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XxWR3Rv2-1651587040629)(E:\Blog\C语言\地址与指针类型不兼容造成的影响.assets\3BE22090F5F814F2283131A8054E7D8F.png)]

由此得出,我们将2个int型的数据,其在内存中的存储占8个字节,int型指针会一次读取4个字节,可以正常显示2个int型变量。

但是如果我们错误地将char型指针指向int型变量,char型数据在内存中占1个字节,char型指针一个只会读取1个字节的数据,因为就会将2个int型变量输出成8个char型变量,造成数据截断。


综上所述,指针类型和其所指向的数据类型要一致,即“地址和指针类型兼容”,否则在进行“指针操作”时会出现诸多问题。

注:如有错误,敬请指正!!!

【NIFI】实现HANA->ORACLE数据同步 实现 HANA->ORACLE数据同步。 阅读详情

相关推荐

ESP32-CAM入门教程

ArduinoESP32-CAM下载模块(接上USB就能用,很方便,如果没有买就只有资金用USB-TTL了)如下图两个合在一起如下图。

qq_48778364的博客 3万+

C语言入门学习笔记十二——指针及其相关知识(一)

指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节,char 占用 1 个字节。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。

Jiangziyadizi的博客 831

头歌工程实训答案-机器学习篇之手写体识别篇

第2关:激活函数'''x:负无穷到正无穷的实数'''if x<=0:return 0else:return x#***第3关:反向传播算法import os。

m0_71537260的博客 2519

c语言不兼容的指针,GCC发出不兼容指针类型的警告

摆脱typedef,它应该变得更加清晰:void P (const int A [][10]){}int main(void){int A[10][10];P(A);return 0;}问题是函数参数中的数组“衰减”为类型为const int(*)[10]的指针,这是指向项为const的数组的指针.此指针类型与从main传递的内容不兼容,因为该数组衰减为int(*)[10]类型的数组指针.有一个规...

weixin_34732699的博客 1237

避坑指南:ESP32S3驱动INMP441麦克风时的常见硬件冲突与解决方案

本文详细解析了ESP32S3驱动INMP441麦克风时常见的硬件冲突问题,包括GPIO资源冲突、电源噪声、I2S时钟同步等,并提供了实用的解决方案和优化策略。通过实测数据和代码示例,帮助开发者快速排查和解决音频设备开发中的疑难问题,提升系统稳定性和音频质量。

embedding5hiker的博客 943

保姆级教程:用dnSpy调试Unity游戏,从找DLL到打断点全流程(附调试版mono.dll下载)

本文详细介绍了使用dnSpy调试Unity游戏的全流程,包括环境准备、关键程序集定位、mono.dll版本匹配与替换、调试环境配置及实战技巧。通过本教程,开发者可以高效进行Unity游戏逆向分析,适用于学习设计模式或安全审计等场景。

weixin_30236595的博客 577

Android Kotlin 泛型(四)

首先申明下,本文为笔者学习《Kotlin 程序开发入门精要》的笔记,并加入笔者自己的理解和归纳总结。 1. 泛型 所谓泛型,就是指在定义数据结构时,只指定类型的占位符,待到使用该数据结构时再指定具体的数据类型。 定义泛型类型变量,可以完整地写明类型参数,如果编译器可以自动推定类型参数,也可以省略类型参数。 class Data<T>(v: T) { var value = v ...

假装你是大灰狼的专栏 1431

CANoe.Diva实战:基于CDD的UDS诊断自动化测试全流程解析

本文详细解析了使用CANoe.Diva进行基于CDD的UDS诊断自动化测试的全流程,包括环境搭建、CDD文件配置、测试范围设置、用例生成与验证、CANoe集成测试及报告分析。通过实战经验分享,帮助工程师快速掌握诊断自动化测试技巧,提升测试效率与质量。

weixin_29258297的博客 219

JAVA基础(类的命名规则、数据类型、变量的定义、控制台输入与输出、运算符)

JAVA Java是一个平台 //JVM java virtual machine JAVA虚拟机(用软件模拟硬件) //JRE java runtime environment JAVA运行时环境 //JDK java development toolkit JAVA开发工具包 //目录:bin //jar.exe 打jar包 //java.exe 编译java源程序 -> 生成字节码程序 //javac.exe 执行java字节码程序-> 启动虚拟机 //java

weixin_50831726的博客 374

基于深度学习DNN LSTM网络的光伏发电量预测 完整代码数据 可直接运行

基于深度学习DNN LSTM网络的光伏发电量预测 完整代码数据 可直接运行

2079

OpenRubrics:自动化评估工具优化LLM对齐效果

在大型语言模型(LLM)应用中,模型输出与人类价值观的对齐是关键挑战。传统人工反馈强化学习(RLHF)依赖大量标注,成本高且一致性差。OpenRubrics作为开源工具,通过结构化准则实现自动化评估,显著提升效率。其核心原理是将主观评价转化为可量化的多维指标,支持动态权重调整,并兼容主流RLHF框架。该工具在降低标注成本的同时,通过Fleiss' Kappa系数等指标保证评估一致性,适用于多语言和医疗等专业领域,为LLM对齐提供了工程化解决方案。

weixin_28730037的博客 359

Day1 :C与C++的区别

头文件与命名空间 C语言中的: 采用原来方式包含可以,可以用C++包含方式,去掉.h 加个c #include<cstdio> namespace: ①存在的意义:增加标识符的使用率(小郭的age和小杰的age) namespace guo//基本写法 namespace+空间名 { int age=17; } name space jie { int age=18; } ②访问:作用域分辨符::(空间名和类名的限定+标识全局变量) void tes

zjjaibc的博客 695

基于STM32、HAL库的 CH9102X USB转UART收发器 驱动程序设计

/ 或 UART_HWCONTROL_RTS_CTS。// 其他函数实现类似,使用HAL_UART_Transmit_IT, HAL_UART_Receive_IT等。UART_TXD <---> USARTx_RX (STM32接收)UART_RXD <---> USARTx_TX (STM32发送)* @param huart: UART句柄指针。* @param huart: UART句柄指针。* @param huart: UART句柄指针。* @param huart: UART句柄指针。

corlin6688的博客 506

C语言指针值传递和地址传递

C语言传参分为值传传递和地址传递。C语言指针传参时,可以通过指针引用方式改变指针指向的值。改变变量,可以使用指针应用方式,改变地址,使用指针的指针引用方式。 C语言值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参->形参) #include <stdio.h> void swap(int x, int y); main() { int a = 10, b = 20; swap(a,

tecoes的博客 1万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

c语言指针强制类型转换

概要: C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。 例如,定义如下: int a; float b; double c; long double d; (假设它们所占的字节分别是4、8、8、10,而且连续存储于某个

赵凯月的博客 9496

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

初阶C语言——指针

C语言你一定要学会的指针来了

2301_76895050的博客 4008

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C语言——指针(二)

C语言指针第二讲,讲究的就是一个:详细!详细!再详细!

tan_run的博客 1546

C语言——指针

指针是C语言中非常重要的概念,它提供了一种直接访问内存中数据的方式,可以实现参数传递、动态内存分配、数组的操作等。在使用指针时,需要注意指针的声明、取地址、解引用、运算、比较等操作,以及指针和数组、函数、结构体、字符串等的应用。掌握指针的使用,可以提高程序的灵活性和效率。

一个普通人的博客 8025

C语言之初识指针

c语言中指针的初步认识.详细介绍

@初阶牛的博客 1937

C语言指针和指针变量

一、指针 概念:当定义一个变量时,系统会为这个变量分配内存,比如,int a,系统会给变量a分配一块内存,大小为in型的4个字节,而且每个字节都会有一个编号,这个编号就是地址,这个编号是计算机抽象出来用于访问数据的,实际上为一个数字。当计算机需要访问数据时,会先找到它的地址,再来获取改地址里的数据。比如,int a=1;当计算机需要printf("%d",a)时,它会先找到a的地址(比如0x00...

qq_43775170的博客 6069

c语言指针强制类型转换的应用

指针的强制类型转换可以灵活的对单个和多个字节的数据结构进行操作

j5856004的博客 1万+

C语言指针类型和类型转换

C语言指针类型和类型转换 指针类型 指针是强类型,意思是特定类型的指针变量存放特定类型变量的地址,比如int * 需要一个指向整形的指针来存放整形数据的地址,char* 需要一个指向字符型的指针来存放字符型数据的地址,那为什么说指针是个强类型呢?指针不仅用来表示变量的地址,同时也得使用指针来解引用地址的内容,以此方便修改和使用变量的值。说到这里,我们又得来回顾一下数据类型所占空间的大小(32位机器) int - 4byte char - 1byte float - 4byte 我们用一个实例来说明指针是

拓海凌峰的博客 5555

【C语言】“指针类型”与“野指针”

在计算机上我们访问数据需要通过内存地址来访问,在C语言中,指针变量是用来存放内存地址的变量,在不同系统下,指针(内存)地址的长度不同,32位CPU下,由于有32根地址线,所以指针(内存)地址是由32个bit位组成的,也就是4Byte,在64位CPU下,有64根地址线,所以地址由64个bit位组成,也就是8Byte,指针指向的地址都是一个。

qq_65596720的博客 7612

C语言初始指针

简略的介绍了C语言指针,让大家能对指针有个大概的了解

m0_66483195的博客 4950

C语言的指针(上)

指针详解

fdxghb65467的博客 1826

C语言指针(带类型的地址)

指针:带类型的地址 在C语言中,数据是分类型的,对不同类型的数据,在内存中分配的存储单元大小(字节数)和存储方式是不同的(如整数是以补码的形式存放,实数以指数的形式存放.数据存放形式是计算机组成原理的知识,此处不做过多赘述).C语言中的地址包括位置信息(内存编号或称纯地址)和它所指向的数据类型的信息,或者说它是"带类型的地址".例如,定义变量 int a,对于&a,一般称它为"变量a的地址",确切的说,它是"整型变量a的地址". 指针的移动和运算 “使指针移动一个位置"或"使指针的值加1”,这个1代

qq_43331150的博客 729
上一篇: 各个行业的前端静态页面模板
下一篇: C语言_数组、指针和函数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

窝在角落里学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值