C语言中指针的初始化和赋值

2023-05-16

1、指针的初始化

指针初始化时,“=”的右操作数必须为内存中数据的地址,不可以是变量,也不可以直接用整型地址值(但是int*p=0;除外,该语句表示指针为空)。此时,*p只是表示定义的是个指针变量,并没有间接取值的意思。

例如:

int a = 25;

int *ptr = &a;

int b[10];

int *point = b;   

int *p = &b[0];


如果:int  *p;

    *p = 7;

则编译器(vs2008)会提示The variable 'p' is being used without being initialized.即使用了未初始化的变量p。

因为p是指向7所在的地址,*p = 7给p所指向的内存赋值,p没有赋值,所以p所指向的内存位置是随机的,没有初始化的。

int k;

int *p;

p = &k;  //给p赋值

*p = 7; //给p所指向的内存赋值,即k= 7


2、指针的赋值

int *p;

int a;

int b[1];

p = &a; 

p = b; 

指针的赋值,“=”的左操作数可以是*p,也可以是p。

当“=”的左操作数是*p时,改变的是p所指向的地址存放的数据;

当“=”的左操作数是p时,改变的是p所指向的地址。

数组的变量名b表示该数组的首地址,因此p=b;也是正确的


同类型的指针赋值:


int val1 = 18,val2 = 19;

int *p1,*p2;

p1 = &val1;

p2 = &val2;

p1 = p2;   //注意啦,p1指向了val2,而没有指向val1


备注:字符串与指针的初始化和赋值

初始化:

char *cp = "abcdefg"; //这个初始化过程,是将指针cp指向字符串的首地址,而并不是传递字符串的值。因为,在C语言里面,没有整体处理一个字符串的机制

赋值:

cp = "abcdefg";

*cp=”abcdefg” ;//错误!字符串常量传递的是它的首地址,不可以通过*cp修改该字符串的值,因为该字符串为常量,而它只是简单的将指针指向该字符串常量


3、指针常量

在C语言中没有一种内建(built-in)的方法去表示指针常量,所以当我们使用它的时候通常先写成整型常量的形式,然后再通过强制类型转换把它转换成相应的类型,如:int * , double * , char *等。 所以后面所示的做法是不行的: int *p = 0x12345678 ; 正确的方式应为:int *p = (int *) 0x12345678; 要注意指针中只能存放地址,不能将一个非0值整型常量表达式或者其他非地址类型的数据赋给一个指针,原因就在此。在大多数计算机中,内存地址确实是以无符号整型数来表示的,而且多以16进制表示,但我们在C语言中不能用整型数去表示地址,只能用指针常量来表示,因为它是被用来赋给一个指针的。

对于这个赋值问题还可以换一个角度去理解,在C语言中,使用赋值操作符时,赋值操作符左边和右边的表达式类型应该是相同的,如果不是,赋值操作符将试图把右边表达式的值转换为左边的类型。所以如果写出int *p = 0x12345678 ; 这条语句编译器会报错:'=' : cannot convert from ' const int ' to ' int * ' ,因为赋值操作符左边和右边的表达式的类型应该相同,而0x12345678是int型常量,p是一个指向int型的指针,两者类型不同,所以正确的方式是:int *p = (int *) 0x12345678 ; 


4、指针初始化补充

ANSI C定义了零指针常量的概念:一个具有0值的整形常量表达式,或者此类表达式被强制转换为void *类型,则称为空指针常量,它可以用来初始化或赋给任何类型的指针。也就是说,我们可以将0、0L、'/0'、2–2、0*5以及(void *)0赋给一个任何类型的指针,此后这个指针就成为一个空指针,由系统保证空指针不指向任何对象或函数。

ANSI C还定义了一个宏NULL,用来表示空指针常量。大多数C语言的实现中NULL是采用后面这种方式定义的:#define  NULL  ((void *)0)。

对指针进行初始化时常用的有以下几种方式:

  1.采用NULL或空指针常量,如:int *p = NULL;或 char *p = 2-2; 或float *p = 0;

  2.取一个对象的地址然后赋给一个指针,如:int i = 3;  int *ip = &i;

  3.将一个指针常量赋给一个指针,如:long *p = (long *)0xfffffff0;

  4.将一个T类型数组的名字赋给一个相同类型的指针,如:char ary[100]; char *cp = ary;

  5.将一个指针的地址赋给一个指针,如:int i = 3;  int *ip = &i;int **pp = &ip;

  6.将一个字符串常量赋给一个字符指针,如:char *cp = “abcdefg”;

对指针进行初始化或赋值的实质是将地址或同类型(或相兼容的类型)的指针赋给它,而不管这个地址是怎么取得的。要注意的是:对于一个不确定要指向何种类型的指针,在定义它之后最好把它初始化为NULL并在解引用这个指针时对它进行检验防止解引用空指针。另外,为程序中任何新创建的变量提供一个合法的初始值是一个好习惯,它可以帮你避免一些不必要的麻烦。


5、void *型指针

ANSI C定义了一种void *型指针,表示定义一个指针,但不指定它指向何种类型的数据。void *型指针作为一种通用的指针,可以和其它任何类型的指针(函数指针除外)相互转化而不需要类型强制转换,但不能对它进行解引用及下标操作。C语言中的malloc函数的返回值就是一个void *型指针,我们可以把它直接赋给一个其他类型的指针,但从安全的编程风格角度以及兼容性上讲,最好还是将返回的指针强制转换为所需的类型,另外,malloc在无法满足请求时会通过返回一个空指针来作为“内存分配失败”的信号,所以要注意返回值指针的判空


6、指向指针的指针

在指针初始化的第5种方式中提到了用一个指针的地址来初始化一个指针。回忆一下上一讲的内容:指针是一种变量,它也有自己的地址,所以它本身也是可用指针指向的对象。我们可以将指针的地址存放在另一个指针中,如:

int i = 5000;

int *pi = &i;

int **ppi = π

此时的ppi即是一个指向指针的指针,下图表示了这些对象:

                          

i的地址为108,pi的内容就是i的地址,而pi的地址为104,ppi的内容即是pi的地址。对ppi解引用照常会得到ppi所指的对象,所获得的对象是指向int型变量的指针pi。想要真正地访问到i.,必须对ppi进行两次解引用,如下面代码所示:

printf("%d", i );

printf("%d", *pi );

printf("%d", **ppi );

以上三条语句的输出均为5000。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言中指针的初始化和赋值 的相关文章

  • DLL程序入口DllMain详解

    DLL程序入口点函数 xff1a DllMain xff0c 注意 xff1a 大小写是区别的 仅导出资源的DLL可以没有DllMain函数 函数原型 cpp view plain copy print BOOL APIENTRY DllM
  • C++编写DLL的方法

    在写C 43 43 程序时 xff0c 时常需要将一个class写成DLL xff0c 供客户端程序调用 这样的DLL可以导出整个class 也可以导出这个class的某个方法 一 导出整个class 方法很简单 xff0c 只需要在类的头
  • dll文件的c++制作

    1 首先用vs2005建立一个 c 43 43 的dll 动态 链接 库 文件 xff0c 这时 xff0c DllTest cpp 定义 DLL 应用程序的入口点 include 34 stdafx h 34 include 34 Dll
  • vs2008 C++创建和调用标准DLL

    为了共享代码 xff0c 需要生成标准的dll xff0c 本文将介绍在vs2008 C 43 43 生成及调用dll 一 生成DLL 生成一个名为FunDll的dll文件 xff0c 对外函数为addl step1 vs2008 环境下
  • VSCode使用SSH免密登录服务器

    VSCode使用SSH免密登录服务器 前言一 SSH连接服务器1 1 安装ssh插件1 2 配置连接 二 免密登录服务器2 1 生成公钥2 2 服务器新建授权文件2 3 本地复制公钥到服务器 总结 前言 vscode使用remote ssh
  • 使用directX 7结合C#进行2D游戏编程

    使用directX 7结合C xff03 进行2D游戏编程 前言 对于C 的开发人员来讲 xff0c GDI 43 是一个拥有丰富的绘图API指令 传统 高效的程序集 但不幸的是 xff0c 你要想用她来开发一个复杂而又平滑的动画的时候 x
  • DirectX学习笔记_关于Sprite.Draw2D的说明

    在DirectX的Sprite中提供一个Draw2D的方法 xff0c 该方法绘制一个 Sprite 对象用于二维空间中显示 xff0c 在DirectX 9 0C中 xff0c 该方法有6个重载 xff0c 分别是 1 public vo
  • 关于Direct2D

    关于Direct2D Direct2D是一个硬件加速的 xff0c 提供立即模式的二维图形API 它提供了二维的几何体 xff0c 位图 xff0c 文本的高性能 xff0c 高质量的渲染 十分方便的是 xff0c Direct2D与GDI
  • C# GDI+ 绘图

    1 坐标系统 1 坐标原点 xff1a 在窗体或控件的左上角 xff0c 坐标为 0 0 2 正方向 xff1a X轴正方向为水平向右 xff0c Y轴正方向为竖直向下 3 单位 xff1a 在设置时 xff0c 一般以像素为单位 xff0
  • lock锁和monitor.enter锁

    210 08 05 14 50 28 转载 Lock object 锁的使用 using System using System Threading namespace program class wangjun public static
  • windows重绘机制原理

    一 Windows程序中的绘制和更新 与DOS环境比较 xff0c Windows中的应用程序在处理文字和图形绘制时有以下区别 xff1a 1 只能在窗口的客户区域绘制文字和图形 2 在窗口上绘制的内容不一定能够保留到程序下一次有意地改写时
  • C# Winform 出现异常:无法将顶级控件添加到控件,解决方案如下:

    Form1Test frm 61 new Form1Test frm TopLevel 61 false 重要的一个步骤 frm Parent 61 splitContainerPanel Panel2 frm Show
  • c#中的Form.Show和Form.ShowDialog的区别

    出处 xff1a http hi baidu com cysteine blog item 01e32224702ff5398744f9bf html 区别1 xff1a ShowDialog是模态的 xff08 独占用户输入 xff09
  • 浅析C#中foreach引用变量

    昨天做老师的网站作业 要对一些对象做添加修改删除处理 别的倒没什么 xff0c 删除时出现了点问题似的 因为是从一个类的集合中删除掉一个元素 这样就要遍历整个集合 xff0c 而foreach正是为遍历准备的新玩意 自然而然用上了 于是代码
  • 用汇编的眼光看C++(之拷贝、赋值函数)

    拷贝构造函数和复制函数是类里面比较重要的两个函数 两者有什么区别呢 xff1f 其实也很简单 xff0c 我们可以举个例子 xff0c 加入有这样一个类的定义 xff1a cpp view plain copy class apple pu
  • IDEA配置一个入门的ssh事例,解决Artifact war exploded:Error during artifact deployment. See server log for detail

    首先 xff0c 我的版本ideaIU 2017 3 4 xff0c 一 新建一个项目project 1 1 create new project 2 file new project 2 这里选择spring xff0c struts2
  • WinForm 之Control.Invoke 和Control.BeginInvoke 方法的使用 Control 不能在创建它的 Thread 之外被调用。但可以通过 invoke 来保证 C

    WinForm 之Control Invoke 和Control BeginInvoke 方法的使用 Control 不能在创建它的 Thread 之外被调用 但可以通过 invoke 来保证 Control 线程安全 在跨线程更新的时候
  • C#中跨线程访问控件问题解决方案

    net 原则上禁止跨线程访问控件 xff0c 因为这样可能造成错误的发生 xff0c 推荐的解决方法是采用代理 用代理方法来间接操作不是同一线程创建的控件 第二种方法是禁止编译器对跨线程访问作检查 xff0c 可以实现访问 xff0c 但是
  • C#中Invoke的用法(转)

    转载 转自 xff1a http blog 3snews net html 30 34530 27563 html 在多线程编程中 xff0c 我们经常要在工作线程中去更新界面显示 xff0c 而在多线程中直接调用界面控件的方法是错误的做法

随机推荐

  • 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)

    今天无意中看到有关Invoke和BeginInvoke的一些资料 xff0c 不太清楚它们之间的区别 所以花了点时间研究了下 据msdn中介绍 xff0c 它们最大的区别就是BeginInvoke属于异步执行的 Control Invoke
  • C#中Invoke 和 BeginInvoke的涵义和区别

    BeginInvoke 方法真的是新开一个线程进行异步调用吗 xff1f 参考以下代码 xff1a public delegate void treeinvoke private void UpdateTreeView MessageBox
  • C# 理解lock

    一 为什么要lock xff0c lock了什么 xff1f 当我们使用 线程 的时候 xff0c 效率最高的方式当然是 异步 xff0c 即各个线程同时运行 xff0c 其间不相互依赖和等待 但当不同的线程都需要访问某个资源的时候 xff
  • excel操作的几种方法

    using System using System Collections Generic using System Text using System Data using System Windows Forms using Syste
  • c#中如何实现拷贝对象

    大家都知道 xff0c 在C 中变量的存储分为值类型和引用类型两种 xff0c 而值类型和引用类型在数值变化是产生的后果是不一样的 xff0c 值类型我们可以轻松实现数值的拷贝 xff0c 那么引用类型呢 xff0c 在对象拷贝上存在着一定
  • 深入了解Windows句柄到底是什么

    总是有新入门的Windows程序员问我Windows的句柄到底是什么 xff0c 我说你把它看做一种类似指针的标识就行了 xff0c 但是显然这一答案不能让他们满意 xff0c 然后我说去问问度娘吧 xff0c 他们说不行网上的说法太多还难
  • 句柄概念

    句柄 xff08 handle xff09 xff0c 有多种意义 xff0c 其中第一种是指程序设计 xff0c 第二种是指Windows编程 现在大部分都是指程序设计 程序开发这类 第一种解释 xff1a 句柄是一种特殊的 智能指针 当
  • 腾讯云大数据发布最新产品矩阵,助力企业整合打通海量数据

    9月11日 xff0c 主题为 释放数字经济发展的新动能 的腾讯全球数字生态大会大数据专场在线上拉开帷幕 腾讯大数据领域的多位顶级专家 xff0c 与包括 Hadoop 创始人 Doug Cutting 在内的业内顶级大咖 xff0c 以及
  • C/C++中函数参数传递

    看了内存管理的有关内容 xff0c 有一点了解 xff0c 但不是很深入 xff0c 发现之前写代码时有很多细节问题没有注意到 xff0c 只知道这样做可以实现功能 xff0c 却不知道为什么可以这样 xff0c 对于采用自己的方法造成的隐
  • Windows窗口刷新机制详解

    1 Windows的窗口刷新管理 窗口句柄 xff08 HWND xff09 都是由操作系统内核管理的 xff0c 系统内部有一个z order序列 xff0c 记录着当前窗口从屏幕底部 xff08 假象的从屏幕到眼睛的方向 xff09 x
  • C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

    BSS段 xff08 bss segment xff09 通常是指用来存放程序中 未初始化 的 全局变量 的一块内存区域 BSS是英文Block Started by Symbol的简称 BSS段属于静态内存分配 数据段 xff1a 数据段
  • C# 窗体Show和ShowDialog 方法的区别详解

    CenterParent 窗体在其父窗体中居中 CenterScreen 窗体在当前显示窗口中居中 xff0c 其尺寸在窗体大小中指定 Manual 窗体的位置由 Location 属性确定 WindowsDefaultBounds 窗体定
  • c# 窗口句柄问题 。

    1 如何获得一个窗口的句柄 xff1f 例如获取窗口PictureBox控件 xff08 其他控件也可以 xff09 的句柄 xff0c csharp view plain copy IntPtr handle 61 pictureBox
  • c#中已知一个外部窗口的句柄,怎么关闭

    已知一个外部窗口的句柄 xff0c 怎么关闭它 怎么给这个窗口的一个文本框设置内容 public void Test Handle windowhandle string TextBoxName System windws froms fr
  • 数组内存分配概念

    在这里解答一下 xff1a int arr 4 amp arr 1 61 arr 0 43 sizeof int 静态分配 xff0c 即普通数组 xff0c 由于在栈中分配 xff0c 而栈的生成方向是自高地址向低地址生成 所以有 xff
  • 静态数组和动态数组 内存分布

    数组是程序设计中是一个非常重要的概念 数组是一个用于收集大量类似数据的容器 xff0c 以及其每一个元素能被相同处理过程迭代来处理的一个抽象体 创建数组一般有三种方式 xff1a 全局 静态范围的数组 xff0c 局部变量数组 xff0c
  • C语言 内存分配 地址 指针 数组 参数 解析

    指针简介 指针式保存变量地址 的变量 增加阅读难度 指针 和 goto 语句会增加程序的理解难度 容易出现错误 ANSI C American National Standards Institute 美国国家标准学会 即标准C 通用指针类
  • C++数组与指针概念

    指向数组元素的指针 一个变量有地址 xff0c 一个数组包含若干元素 xff0c 每个数组元素都在内存中占用存储单元 xff0c 它们都有相应的地址 指针变量既然可以指向变量 xff0c 当然也可以指向数组元素 xff08 把某一元素的地址
  • [代码实例][C]Linux实现线程池

    ThreadPool h span class token macro property span class token directive keyword ifndef span THREADPOOL H span span class
  • C语言中指针的初始化和赋值

    1 指针的初始化 指针初始化时 xff0c 61 的右操作数必须为内存中数据的地址 xff0c 不可以是变量 xff0c 也不可以直接用整型地址值 但是int p 61 0 除外 xff0c 该语句表示指针为空 此时 xff0c p只是表示