[转载]C 指针

一、认识存储单元
指针是C语言最显著的特色。要理解指针的概念,需要先理解计算机读写内存的的方式以及变量的概念。
计算机内存是以字节为单位划分内存单元的,每个内存单元占用一个字节,每个内存单元都有自己的地址编号,操作系统或软件根据这个地址来识别内存单元,在地址所标识的内存单元中存取数据。内存单元的地址是固定的,内存单元中的数据是可以修改的。
C语言中,变量名实质上是内存单元的地址符号,用户使用变量本质上是访问该变量所对应的内存单元。
二、C指针的概念
1、在C中,将内存单元的地址(编号)称为指针,可以通过一个变量来存放指针,这种变量称为指针变量。指针变量中存储的是内存单元的地址。
例如 int a = 10; 假设存放a的内存单元块为 101,102,103,104,占用四个字节。如果再执行一个 int *p=&a;那么p的值就成为101了,*p的值就是10,a的值也是10。
&是取地址运算符,获取变量的首地址。
2、创建指针的方法是:类型说明符 *变量名,这是C定义指针变量的方法。其中*表示这个变量是指针变量。
C要求,指针必须存放在指针变量中。
一个指针只能指向同一类型的变量。
3、指针的初始化
int *p=NULL;
int a=10;
int *p=&a;
注意:
a)未初始化的指针的系统会给一个随机的值,没有意义,操作可能引起系统崩溃。
b)未初始化的指针应该给一个NULL值,以表明它是个空指针,表示0值。
c)不允许把常量赋值给指针变量。
d)必须保持指针变量类型与所指数据的一致性,否则会发生不可预期的效果。(虽然C已允许将任何地址赋值给指针变量)。
4、取地址& 与 取内容*
取地址运算符是& ;
取内容运算符是*,注意:区别定义指针变量类型说明符*。
int a=10;
int *p=&a;    //定义指针变量p,并指向a;
*p=3;   //将3赋给指针p所指的内存单元,则a的值也变为了3
int b = *p;  //将指针p的所指内存单元值赋给变量b;
明白这个道理后,指针和一般变量一样可以操作了。
指针的直接操作内存,在Java中是没有的,Java没有指针。Java中的基本变量名实际上也是内存地址的别名。
三、指针操作数组
1、指向数组的指针
数组是保存在一片连续的内存单元中。数组名是这块连续内存单元的首地址,是不可改变的常量。因此数组名也是一个常量指针。
int a[3]={1,2,3};
int *p=a;  //指向数组的指针
当指针执行数组名或数组首元素地址时,指针就指向了数组。
2、指针运算
a)自增/自减:C规定,指针加1,表示指针后一个指针的类型的内存单元。
b)加减整数运算,只能加减整数,整数表示的基类型数据的宽度倍数。
c)指针相减,指针间的元素个数,不是存储单元数。
d)指针比较,判断指针在内存中的高低位置关系。
3、指针操作数组
下标发和指针法,分五种方式:
#include<stdio.h>
int main()
{
        int i,a[5]={1,2,3,4};
        int *p=a;
        for(i=0;i<4;i++)
                printf("a[%d]=%d\n",i,a[i]);
        printf("\n");
        for(i=0;i<4;i++)
                printf("p[%d]=%d\n",i,p[i]);
        printf("\n");
        for(i=0;i<4;i++)
                printf("*(p+%d)=%d\n",i,*(p+i));
        printf("\n");
        for(i=0;i<4;i++)
                printf("*(a+%d)=%d\n",i,*(a+i));
        printf("\n");
        for(i=0;i<4;i++)
                printf("*p++=%d\n",*p++);
        getch();
        return 0;
}
a[0]=1
a[1]=2
a[2]=3
a[3]=4

p[0]=1
p[1]=2
p[2]=3
p[3]=4

*(p+0)=1
*(p+1)=2
*(p+2)=3
*(p+3)=4

*(a+0)=1
*(a+1)=2
*(a+2)=3
*(a+3)=4

*p++=1
*p++=2
*p++=3
*p++=4
注意,数组名虽然是指针,但是数组名是常量,不可改变,因此不可以a++;
4、指针操作二维数组
二维数组是多个一维数组组成的数组,或者说是一维数组的数组,或者说是一维数组,但是各个元素还是一维数组。
这个概念和java中是一致的。
假设有二维数组
int a[x][y];
那么
a)a表示数组首地址的指针。
b)a[i]表示第i+1个一维数组,其地址为a[i],指向的是一个一维数组。
c)a[i][j] 与*(a[i]+j)、*(*(a+i)+j)是相同的,表示同一个元素。
#include<stdio.h>
int main()
{
        int a[4][5], i,j;
        for(i=0;i<4;i++)
                for(j=0;j<5;j++)
                        a[i][j]=i*5+j;
        printf("二维数组的值为:\n");
        for(i=0;i<4;i++)
        {
                for(j=0;j<5;j++)
                        printf("%4d ",a[i][j]);
                printf("\n");
        }                

        getch();
        return 0;
}
二维数组的值为:
     0        1        2        3        4
     5        6        7        8        9
    10     11     12     13     14
    15     16     17     18     19
5、数组指针
数组指针:变量是指针,指向了一个数组。
例如:
int *p[3];定义了一个指针p指向了一个长度为3的int数组。
#include<stdio.h>
int main()
{
        int a[4][5],i,j;
        int (*p)[5];
        p=a;
        for(i=0;i<4;i++)
        {
                for(j=0;j<5;j++)
                        *(*p+j)=i*5+j;
                p++;
        }
        printf("二维数组的值为:\n");
        p=a;
        for(i=0;i<4;i++)
        {
                for(j=0;j<5;j++)
                        printf("%4d    ",*(*p+j));
                printf("\n");
                p++;
        }                

        getch();
        return 0;
}
二维数组的值为:
     0        1        2        3        4
     5        6        7        8        9
    10     11     12     13     14
    15     16     17     18     19
6、数组名参数
指针变量 p 是空指针的判断:
if ( p == 0 )
if ( p == '\0' )
if ( p == 3 - 3 )
if ( p == NULL )  /* 使用 NULL 必须包含相应的标准库的头文件 */
if ( NULL == p )
if ( !p )
if ( p == q )
...

指针变量 p 不是空指针的判断:
if ( p != 0 )
if ( p != '\0' )
if ( p != 3 - 3 )
if ( p != NULL )  /* 使用 NULL 必须包含相应的标准库的头文件 */
if ( NULL != p )
if ( p )
if ( p != q )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

公司年会

没有抽奖的年会肯定是不完美的。有抽奖没有饭局的年会也是很香的。因为疫情&#xff0c;我们没有年终饭局&#xff0c;我也不知道过去那些年腾讯是怎么开年会的&#xff0c;不过今年&#xff0c;我觉得挺不错。上周我们搞了年终活动&#xff0c;我那时候还在开会&#xff0c;CG…

MySQL函数笔记_MySQL笔记之数学函数详解

绝对值函数ABS(x)和圆周率函数PI()复制代码 代码如下:mysql> SELECT ABS(0.5), ABS(-0.5), PI();-------------------------------| ABS(0.5) | ABS(-0.5) | PI() |-------------------------------| 0.5 | 0.5 | 3.141593 |-------------------------------…

给年薪不到48w的程序员提个醒!!

近日&#xff0c;一程序员在脉脉自曝“年薪37W带12人团队&#xff0c;因学历内推腾讯被拒”&#xff0c;引发争议。末流院校&#xff0c;带12人前端团队&#xff0c;到手37w股票20w&#xff0c;过硬的编程技术让他觉得可以出去“闯闯”&#xff1b;内推到腾讯&#xff0c;电话里…

POLYCOM RMX2000 激活与初始化 信令板卡初始化

POLYCOM RMX2000 激活与初始化 信令板卡初始化 上个星期跟组长去建行升级RMX2000的时候遇到的问题就是系统起来后&#xff0c;在“硬件监视器”下可以找到MPMx板卡&#xff0c;但是系统的“IP 网络服务”里面找不到信令板卡。 刚开始以为是板卡激活出现问题&#xff0c;重复了几…

实验二 网络嗅探与欺骗

实验二 中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告 实验二 网络嗅探与欺骗 学生姓名 张昊 年级 2015 区队 三 指导教师 高见 信息技术与网络安全学院 2018年9月25日 实验任务总纲 2018—20179学年 第 一 学期 一、实验目…

年终奖

我一个人走在路上&#xff0c;想说点什么&#xff0c;我觉得很难受&#xff0c;去年这个时候我一个高中同学跟我聊天&#xff0c;他跟我说「我听说你们在深圳做程序员的工资很高&#xff0c;我认识的一个朋友在深圳一个月2万多&#xff0c;年终奖发了十几万」。我想&#xff0c…

python barrier_Python线程障碍对象Barrier原理详解

python线程Barrier俗称障碍对象&#xff0c;也称栅栏&#xff0c;也叫屏障。一.线程障碍对象Barrier简介# 导入线程模块import threading# 障碍对象barrierbarrier threading.Barrier(parties, actionNone, timeoutNone)parties — 线程计数器&#xff0c;记录线程数量&#x…

Spring AOP 五大通知类型

1.前置通知 在目标方法执行之前执行执行的通知。 前置通知方法&#xff0c;可以没有参数&#xff0c;也可以额外接收一个JoinPoint&#xff0c;Spring会自动将该对象传入&#xff0c;代表当前的连接点&#xff0c;通过该对象可以获取目标对象 和 目标方法相关的信息。 注意&…

转载CSDN博文精选:Android系列开发博客资源汇总

CSDN博客本期热文推荐&#xff0c;为您介绍有关Android应用开发的10个博客&#xff0c;分享他们的日积月累的宝贵经验&#xff0c;希望这些文章对Android开发者们能有所启发和帮助。 [1] 张国威&#xff1a;Android从入门到提高系列 前面写了十四篇关于界面的入门文章&#xff…

简单工厂模式+工厂方法模式

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; …

Windows下搭建ESP-IDF开发环境,适合ESP32/S2/C3/S3系列模组二次开发

前言本教程适用于以下两种用户&#xff1a;①无Linux环境搭建经验或搭建Linux开发环境不成功&#xff1b;②使用安信可windows一体化环境IDE V1.5开发环境搭建不成功&#xff1b;本教程提供了windows下搭建 ESP-IDF 开发环境的方法。适用系统&#xff1a;Windows 10 64 位版本、…

python中 1.34e3_Python快速编程入门——第2章 Python基础语法

第2章 python基础语法一、基本语法二、变量和数据类型三、标识符和关键字四、简单数值类型一、基本语法注释&#xff1a;Python的注释是用# 不像C/C使用的是//或者/*/。多行注释好像挺麻烦。行与缩进&#xff1a;Python中的特色是缩进而C/C语言一般都是使用的括号来表示范围。如…

Lync Server 2010的部署系列_第六章 安装配置拓扑生成器、前端Server、前端池

一、安装 Lync Server 2010 管理工具&#xff08;包括拓扑生成器&#xff09; 1) 登录Front.Gianthard.com&#xff08;192.168.1.21&#xff09;。在“Microsoft Lync Server 2010 - 部署向导”页上&#xff0c;单击“安装拓扑生成器”。 2) 进行SQL方面的客户端。 3) 安装成功…

CF1042F Leaf Sets (贪心+树上构造)

题目大意&#xff1a;给你一棵树&#xff0c;让你对叶节点分组&#xff0c;保证每组中&#xff0c;任意两个叶节点之间的距离不大于K&#xff0c;求最小的组数 手动yy的贪心竟然对的 对于每个节点&#xff0c;维护一个$ma[i]$&#xff0c;表示在$i$节点的子树内 未被分组的叶节…

被 HR 直接怼:估计你一辈子就是个程序员

今天看到一个非常扯蛋的事情。事情来自网络&#xff0c;不是作者本人。我一直认为程序员是可以做一辈子的事情&#xff0c;程序员是一种做得越久技术越熟练的工作。但是有的人并不这样认为。---有程序员因为能力很强&#xff0c;公司非常满意&#xff0c;结果派了一位 HR 与其谈…

一起谈.NET技术,在MVC2.0使用Lodop为WEB打印提出完美解决方案

通过好友CallHot介绍Lodopweb打印控件。由于是国人开发的&#xff0c;故这两天认真了研究下&#xff0c;打算在未来的项目中使用。现将学习成果与园友分享。如果存在不足的地方&#xff0c;希望您指出。 具体的实现步骤如下&#xff1a; 一、准备工作 1.MVC2.0 jQuery1.4.1 开…

树莓派4b搭建个人云_树莓派4B NAS系统搭建

一、硬盘挂载由于之前硬盘(NTFS格式)里有数据不想格式化想直接挂载&#xff0c;就没有格式化成ext4文件格式的。安装ntfs-3gsudo apt-get install ntfs-3g加载内核模块modprobe fuse查看硬盘情况fdis -l将硬盘挂载到/mnt下ntfs-3g /dev/sda1 /mnt实现开机自动挂载vim /etc/fsta…

(转)python调取C/C++的dll生成方法

本文针对Windows平台下&#xff0c;python调取C/C的dll文件。 1.如果使用C语言&#xff0c;代码如下&#xff0c;文件名为test.c。 __declspec(dllexport) int sum(int a,int b) {return (a b); } 如果使用C语言&#xff0c;代码如下&#xff0c;文件名为test_cpp.cpp。在Wind…

生产者-消费者模式

生产者/消费者问题的多种Java实现方式 实质上&#xff0c;很多后台服务程序并发控制的基本原理都可以归纳为生产者/消费者模式&#xff0c;而这是恰恰是在本科操作系统课堂上老师反复讲解&#xff0c;而我们却视而不见不以为然的。在博文《一种面向作业流(工作流)的轻量级可复用…

周末,说下我喜欢的篮球

我应该有很久没有看NBA比赛了&#xff0c;没有其他原因&#xff0c;确实是因为工作太忙了&#xff0c;即使是在带薪上厕所&#xff0c;也没有足够的时间看下NBA比赛。如果说忙是一个比较好的托词&#xff0c;那还有一个原因&#xff0c;我现在更多的喜欢野球圈的新闻。刚毕业那…