首页 > 其他分享 >C语言:指针

C语言:指针

时间:2024-08-12 11:25:27浏览次数:12  
标签:const 变量 int C语言 assert 地址 指针

 

目录

指针变量和地址

取地址操作符

指针变量的大小

指针变量类型意义

指针解引⽤

指针的 + - 整数

const修饰指针

const修饰变量

const修饰指针变量

指针的运算

指针+ -整数

 指针的关系运算

野指针

指针未初始化

 指针越界访问

指针指向的空间被释放了

避免野指针

assert断言

传值调⽤和传址调⽤

传值调用

传址调用


下面这一张图,我们可以看到a初始化为20 ,int* p指向a的地址

指针变量和地址

取地址操作符

&取地址操作符可以取出一个变量的地址

下面在32位环境下打印地址,我们可以看到取出a的地址打印

下面这张图,我们在编译过程中,我们也可以查看内存

指针变量的大小

在32位环境下有32根地址总线4X8=32

32位平台下地址是32个bit位,指针变量⼤⼩是4个字节?

在64位环境下有64根地址总线8X8=64

64位平台下地址是64个bit位,指针变量⼤⼩是8个字节

指针变量类型意义

指针解引⽤
int a=20;
int *p = &a;//p指向a的地址
*p = 99;//通过解引⽤把地址变成20,然后进行修改

上面这*p指向的是a的地址,然后再通过解引⽤把地址变成20,然后进行修改成99


下面这代码p如果不解引⽤那么p就是修改int *p指向的地址

int a = 10;
int b = 20;
int *p = &a;//p指向a的地址
p = &b;//这个是修改p指向的地址
//上面修改了p指向的地址,那下面这个修改的就是 b 的数值了
*p = 0;


下面我们可以看到地址是倒着存放的,int是4个字节,11,22,33,44刚刚好4个

每次编译或执行编译器都会重新分配内存空间

当我们执行*p = 0的时候,我们可以发现全部变成0了,因为int *是4个字节。

下面是char *我们可以发现只改了一个地址,因为char *是一个字节

指针的 + - 整数

下面这代码,我们可以看到int *p是int类型的也就是4个字节

p+1我们可以看到往后跳了4个

char * cp是char类型的也就是1个字节

cp+1我们可以看到往后跳了1个

往后跳多少取决于类型是多少,如果类型是8个字节那么就往后跳8个

const修饰指针

const修饰变量

我们可以发现被const修饰变量不能被修改,拥有了常属性

a拥有了常属性,但是不能当常量使用,会报错


我们可以发现被const修饰的变量,用指针的方式通过地址解引⽤后进行修改

举个例子一个房间里大门被const修饰进不去了,可以通过指针也就是翻窗户进去

我们可以发现const也把指针修饰了,也就是说把窗户也关起来了,谁都进不去了

const修饰指针变量

const修饰指针,const在 * 号前面那么数值就不能修改了

const在*号后面的话,地址不能被修改了

指针的运算

指针+ -整数

下面,我们可以发现int *p指向数组首元素地址,for循环通过数组首元素地址加1一直访问到最后一个元素

指针-指针

我们可以看到char* x指向p的首元素地址

然后while循环,每次循环加1,加1跳过类型大小,访问到下一个地址

加到‘\0’停止,每个字符串后面都会有'\0','\0'也是字符串的结束标志

p加到\0停止到了最后一个元素,然后通过最后一个元素的地址减去首元素地址,就可以拿到总共有多少个元素了

 指针的关系运算

野指针

野指针就像一只疯狗,不把狗栓在树上很危险

指针未初始化

指针未初始化那么指针默认就是随机值

 指针越界访问

数组只有10个元素,用指针越界访问到第12个元素,就会成野指针了

指针指向的空间被释放了

下面这个可以运行,但是也是个野指针,很危险

这个函数,返回了n的地址后,这个函数的空间就被释放了,p指向了一个被释放的空间,就是野指针了

避免野指针

当指针没有地址初始化,我们只需要给个NULL就可以避免野指针了

assert断言

使用assert函数我们需要下面这个头文件

#include <assert.h >

assert.h 头⽂件定义了宏 assert() ,⽤于在运⾏时确保程序符合指定条件,如果不符合,就报
错终⽌运⾏。这个宏常常被称为“断⾔”

用assert可以判断p是不是NULL是NULL就报错并且显示在第几行

p不为空就往下执行

assert() 的使⽤对程序员是⾮常友好的,使⽤ assert() 有⼏个好处:它不仅能⾃动标识⽂件和
出问题的⾏号,还有⼀种⽆需更改代码就能开启或关闭 assert() 的机制。如果已经确认程序没有问
题,不需要再做断⾔,就在 #include <assert.h> 语句的前⾯,定义⼀个宏 NDEBUG 。

如果是我们想让assert全部失效我们可以添加下面这个头文件

#define NDEBUG

然后,重新编译程序,编译器就会禁⽤⽂件中所有的 assert() 语句。如果程序⼜出现问题,可以移
除这条 #define NDBUG 指令(或者把它注释掉),再次编译,这样就重新启⽤了 assert() 语
句。


我们可以看到p是NULL,加上这个头文件,assert失效了,如果有多个assert那么全部失效

当然我们在Release环境下执行会自动过滤assert

传值调⽤和传址调⽤

传值调用

传值调用就是传数值到函数里

下面这代码,在函数里交换后就释放了,

传址调用

传值调用就是传地址解引⽤进行交换,通过地址进行的交换,空间释放了,不会影响地址

标签:const,变量,int,C语言,assert,地址,指针
From: https://blog.csdn.net/2401_86723175/article/details/141126972

相关文章

  • C语言 ——猜数字
    目录1.前言2.游戏描述2.1游戏内容2.2游戏方法3.代码实现3.1生成游戏菜单3.2构建主函数3.3构建游戏函数4.代码附上1.前言猜数字小游戏是我们大多数人学习C语言时都会了解到的一个有趣的C语言小游戏,下面我将详细介绍该游戏的实现和编程逻辑。并用二分法......
  • C语言之旅0---(看了就有收获的优质系列博客)
    本章概览1.关键字介绍2.字符和ASCII编码3.字符串和\04.转义字符5.看图放松一下呗!!!1.关键字介绍关键字就是一些具有特殊意思的一些单词,比如:if,int,while等。这个int,各位应该都熟悉吧!(对喽,前面咱们写过–intmain()),在C语言中,有些单词被赋予特殊含义和用法,以供程序员......
  • C语言
    sizeofonarrayfunctionparameterwillreturnsizeof'char*'insteadof'char[]'注意,在C语言中,当把一个数组指针作为参数传给函数后,他会降级成为一个单纯的指针,所以charmyChars[20]Sizeof(myChars)==20但是作为参数传递之后Sizeof(myChars)==sizeof(char*)=......
  • 指针(一)
    1.内存和地址1.1内存我们在学校里住宿的话,学校会给我们分配宿舍,每个人都会有自己的位置。那么当我们需要在学校里面找的时候,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给每个房间编上号,1楼,101,102,103,104....2楼,201,202,203,204....3楼,301,..................
  • day13(C语言)共用体
    共用体 union不同类型的成员变量共用同一块地址空间使用union格式:union共用体名{成员变量1;成员变量2;};unionhello{inta;charb;};intmain(){unionhelloh1;h1.a=20;h1.b='a';printf("a=%d\n",h1.a);//97}可用验......
  • C语言入门教程——手把手教零基础/新手入门(完整C语言学习笔记整理)
    前言    作为一名拥有多年开发经验的技术人员,我的职业生涯涵盖了多种编程语言,包括C语言、C++、C#和JavaScript等。出于对编程的热爱以及希望帮助更多初学者的目的,我决定利用业余时间整理一套全面的C语言学习指南。这套指南旨在为C语言初学者和编程爱好者提供......
  • c语言实现俄罗斯方块
    #include<stdio.h>#include<stdlib.h>#include<time.h>#include<windows.h>#include<conio.h>#defineSPACE32#defineLEFT 75#defineRIGHT77#defineDOWN80#defineESC27#defineWall2#defineBox1#defineKong0#define......
  • 【C++算法】双指针
    移动零题目链接:移动零https://leetcode.cn/problems/move-zeroes/description/算法原理这类题是属于数组划分、数组分开题型代码步骤:使用cur遍历数组当cur所指的元素等于0时,cur向后面移动当cur所指的元素不等于0时,dest向后面移动,cur所指元素与dest移动后所指的元素交换当......
  • C语言——最强版操作符详解
    1.操作符的分类•算术操作符:+、-、*、/、%•移位操作符:<<>>•位操作符:&|^•赋值操作符:=、+=、-=、*=、/=、%=、<<=、>>=、&=、|=、^=•单⽬操作符:!、++、–、&、*、+、-、~、sizeof、(类型)•关系操作符:>、>=、<、<=、==......
  • 嵌入式初学-C语言-二十
    通过指针引用数组数组元素的指针数组指针:        数组中第一个元素的地址,也就是数组的首地址指针数组:        用来存放数组元素地址的数组,称之为指针数组//定义一个一般数组inta[]={1,4,9};//使用指针变量存储数组的第一个元素的首地址,也就是......