当前位置: 首页 > news >正文

C语言 入门教程||C语言 指针||C语言 字符串

C语言 指针

学习 C 语言的指针既简单又有趣。通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的 C 程序员,学习指针是很有必要的。 

正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。请看下面的实例,它将输出定义的变量地址:

#include <stdio.h>int main ()
{int  var1;char var2[10];printf("var1 变量的地址: %x\n", &var1  );printf("var2 变量的地址: %x\n", &var2  );return 0;
}

尝试一下

当上面的代码被编译和执行时,它会产生下列结果:

var1 变量的地址: bff5a400
var2 变量的地址: bff5a3f6

通过上面的实例,我们了解了什么是内存地址以及如何访问它。接下来让我们看看什么是指针。

什么是指针?

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

type *var-name;

在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch     /* 一个字符型的指针 */

所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

如何使用指针?

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:

#include <stdio.h>int main ()
{int  var = 20;   /* 实际变量的声明 */int  *ip;        /* 指针变量的声明 */ip = &var;  /* 在指针变量中存储 var 的地址 */printf("Address of var variable: %x\n", &var  );/* 在指针变量中存储的地址 */printf("Address stored in ip variable: %x\n", ip );/* 使用指针访问值 */printf("Value of *ip variable: %d\n", *ip );return 0;
}

尝试一下

当上面的代码被编译和执行时,它会产生下列结果:

Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20

C 中的 NULL 指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为指针。

NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:

#include <stdio.h>int main ()
{int  *ptr = NULL;printf("ptr 的值是 %x\n", ptr  );return 0;
}

尝试一下

当上面的代码被编译和执行时,它会产生下列结果:

ptr 的值是 0

在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。

如需检查一个空指针,您可以使用 if 语句,如下所示:

if(ptr)     /* 如果 p 非空,则完成 */
if(!ptr)    /* 如果 p 为空,则完成 */

C 指针详解

在 C 中,有很多指针相关的概念,这些概念都很简单,但是都很重要。下面列出了 C 程序员必须清楚的一些与指针相关的重要概念:

概念描述
指针的算术运算可以对指针进行四种算术运算:++、--、+、-
指针数组可以定义用来存储指针的数组。
指向指针的指针C 允许指向指针的指针。
传递指针给函数通过引用或地址传递参数,使传递的参数在调用函数中被改变。
从函数返回指针C 允许函数返回指针到局部变量、静态变量和动态内存分配。

C语言 字符串 

在 C 语言中,字符串实际上是使用 null 字符 '' 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

下面的声明和初始化创建了一个 "Hello" 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 "Hello" 的字符数多一个。

char greeting[6] = {'H', 'e', 'l', 'l', 'o', ''};

依据数组初始化规则,您可以把上面的语句写成以下语句:

char greeting[] = "Hello";

以下是 C/C++ 中定义的字符串的内存表示:

其实,您不需要把 null 字符放在字符串常量的末尾。C 编译器会在初始化数组时,自动把 '' 放在字符串的末尾。让我们尝试输出上面的字符串:

#include <stdio.h>int main ()
{char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};printf("Greeting message: %s\n", greeting );return 0;
}

尝试一下

当上面的代码被编译和执行时,它会产生下列结果:

Greeting message: Hello

C 中有大量操作字符串的函数:

序号函数 & 目的
1strcpy(s1, s2);
复制字符串 s2 到字符串 s1。
2strcat(s1, s2);
连接字符串 s2 到字符串 s1 的末尾。
3strlen(s1);
返回字符串 s1 的长度。
4strcmp(s1, s2);
如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
5strchr(s1, ch);
返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
6strstr(s1, s2);
返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

下面的实例使用了上述的一些函数:

#include <stdio.h>
#include <string.h>int main ()
{char str1[12] = "Hello";char str2[12] = "World";char str3[12];int  len ;/* 复制 str1 到 str3 */strcpy(str3, str1);printf("strcpy( str3, str1) :  %s\n", str3 );/* 连接 str1 和 str2 */strcat( str1, str2);printf("strcat( str1, str2):   %s\n", str1 );/* 连接后,str1 的总长度 */len = strlen(str1);printf("strlen(str1) :  %d\n", len );return 0;
}

尝试一下

当上面的代码被编译和执行时,它会产生下列结果:

strcpy( str3, str1) :  Hello
strcat( str1, str2):   HelloWorld
strlen(str1) :  10

您可以在 C 标准库中找到更多字符串相关的函数。

相关文章:

C语言 入门教程||C语言 指针||C语言 字符串

C语言 指针 学习 C 语言的指针既简单又有趣。通过指针&#xff0c;可以简化一些 C 编程任务的执行&#xff0c;还有一些任务&#xff0c;如动态内存分配&#xff0c;没有指针是无法执行的。所以&#xff0c;想要成为一名优秀的 C 程序员&#xff0c;学习指针是很有必要的。 …...

Nacos2.x+Nginx集群配置

一、配置 nacos 集群 注意&#xff1a;需要先配置好 nacos 连接本地数据库 1、拷贝三份 nacos 2、修改配置文件&#xff08;cluster.conf&#xff09; 修改启动端口&#xff1a; nacos1&#xff1a;8818 nacos2&#xff1a;8828 nacos3&#xff1a;8838 当nacos客户端升级为…...

Android源码分析 - InputManagerService与触摸事件

0. 前言 有人问到&#xff1a;“通过TouchEvent&#xff0c;你可以获得到当前的触点&#xff0c;它更新的频率和屏幕刷新的频率一样吗&#xff1f;”。听到这个问题的时候我感到很诧异&#xff0c;我们知道Android是事件驱动机制的设计&#xff0c;可以从多种服务中通过IPC通信…...

python库--urllib

目录 一.urllib导入 二.urllib爬取网页 三.Headers属性 1.使用build_opener()修改报头 2.使用add_header()添加报头 四.超时设置 五.get和post请求 1.get请求 2.post请求 urllib库和request库作用差不多&#xff0c;但比较起来request库更加容易上手&#xff0c;但该了…...

美团前端二面常考react面试题及答案

什么原因会促使你脱离 create-react-app 的依赖 当你想去配置 webpack 或 babel presets。 React 16中新生命周期有哪些 关于 React16 开始应用的新生命周期&#xff1a; 可以看出&#xff0c;React16 自上而下地对生命周期做了另一种维度的解读&#xff1a; Render 阶段&a…...

环境搭建04-Ubuntu16.04更改conda,pip的镜像源

我常用的pipy国内镜像源&#xff1a; https://pypi.tuna.tsinghua.edu.cn/simple # 清华 http://mirrors.aliyun.com/pypi/simple/ # 阿里云 https://pypi.mirrors.ustc.edu.cn/simple/ #中国科技大学1、将conda的镜像源修改为国内的镜像源 先查看conda安装的信息…...

【C++进阶】四、STL---set和map的介绍和使用

目录 一、关联式容器 二、键值对 三、树形结构的关联式容器 四、set的介绍及使用 4.1 set的介绍 4.2 set的使用 五、multiset的介绍及使用 六、map的介绍和使用 6.1 map的介绍 6.2 map的使用 七、multimap的介绍和使用 一、关联式容器 前面已经接触过 STL 中的部分…...

JavaSE学习进阶 day1_01 static关键字和静态代码块的使用

好的现在我们进入进阶部分的学习&#xff0c;看一张版图&#xff1a; 前面我们已经学习完基础班的内容了&#xff0c;现在我们已经来到了第二板块——基础进阶&#xff0c;这部分内容就不是那么容易了。学完第二板块&#xff0c;慢慢就在向java程序员靠拢了。 面向对象进阶部分…...

苹果笔可以不买原装吗?开学必备性价比电容笔

在当今的时代&#xff0c;电容笔日益普及&#xff0c;而且相关的功能也逐渐完善。因此&#xff0c;在使用过程中&#xff0c;怎样挑选一款性价比比较高的电容笔成为大家关心的焦点。随着电容笔的普及&#xff0c;更好更便宜的电容笔成为了一种趋势。那么&#xff0c;哪个品牌的…...

数据库连接与properties文件

管理properties数据库&#xff1a; 现在pom文件中加入Druid的坐标&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency>配置文件中添加相应的数据&…...

Linux上的校验和验证

校验和&#xff08;checksum&#xff09;程序用来从文件中生成相对较小的唯一密钥。我们可以重新计算该密钥&#xff0c;用以检查文件是否发生改变。修改文件可能是有意为之&#xff08;添加新用户会改变密码文件&#xff09;&#xff0c;也可能是无意而为&#xff08;从CD-ROM…...

杂记——14.git在idea上的使用及其实际开发介绍

这篇文章我们来讲一下git在idea上的使用&#xff0c;以及在实际开发过程中各个分支的使用及其具体的流程 目录 1.git在idea上的使用 1.1 idea上的git提交 1.2 idea上的分支切换 2.git在实际运用时的分支及其流程 2.1分支介绍 2.2具体流程 3.小结 1.git在idea上的使用 …...

记一次Nodejs减低npm版本的踩坑日记

使用了npm install -g npm6.4.1指令之后&#xff0c;把npm版本减低了&#xff0c;让后悲催的就来了。 由于npm 6.4.1 已经过时&#xff0c;导致运行npm时出现 npm does not support Node.js v18.14.2 版本不兼容问题 升级npm版本&#xff0c;npm install -g npmlatest 没用还是…...

【iOS】—— 初识RAC响应式编程

RAC&#xff08;ReactiveCocoa&#xff09; 文章目录RAC&#xff08;ReactiveCocoa&#xff09;响应式编程和函数式编程的区别函数式编程响应式编程响应式编程的优点RAC操作1.利用button点击实现点击事件和传值2.RACSignal用法RACSignal总结&#xff1a;3.对于label的TapGestur…...

Java——面向对象

目录 前言 一、什么是面向对象&#xff1f; 面向过程 & 面向对象 面向对象 二、回顾方法的定义和调用 方法的定义 方法的调用 三、类与对象的创建 类和对象的关系 创建与初始化对象 四、构造器详解 五、创建对象内存分析 六、封装详解 七、什么是继承&#x…...

电影《毒舌律师》观后感

上周看了《毒蛇律师》这部电影&#xff0c;讲述一位’大律师’在法庭为己方辩护&#xff0c;最终赢得辩护的故事。 &#xff08;1&#xff09;人之常情 说起法律相关&#xff0c;不禁会让人联想到讲法律相关知识的罗翔老师&#xff0c;平时也会看他相关视频&#xff0c;无论是亲…...

【活学活用掌握trap命令】

trap 命令用于指定在接收到信号后将要采取的动作&#xff0c;常见的用途是在脚本程序被中断时完成清理工作。当 shell 接收到 sigspec 指定的信号时&#xff0c; arg 参数(通常是执行命令)会被读取&#xff0c;并被执行。 1. 命令介绍 开始掌握基本的使用方式和方法 [1] 语法…...

计算机组成原理4小时速成6:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线

计算机组成原理4小时速成6&#xff1a;输入输出系统&#xff0c;io设备与cpu的链接方式&#xff0c;控制方式&#xff0c;io设备&#xff0c;io接口&#xff0c;并行串行总线 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c…...

MyBatis源码分析(三)SqlSession的执行主流程

文章目录一、熟悉主要接口二、SqlSession的获取1、通过数据源获取SqlSession三、Mapper的获取与代理1、从SqlSession获取Mapper2、执行Mapper方法前准备逻辑3、SqlCommand的创建4、构造MethodSignature四、执行Mapper的核心方法1、执行Mapper的方法逻辑五、简单SELECT处理过程1…...

环境搭建01-Ubuntu16.04如何查看显卡信息及安装NVDIA显卡驱动

1. 查看显卡型号、驱动 ubuntu-drivers devices2. 安装NVIDIA显卡驱动 &#xff08;1&#xff09;验证是否禁用nouveau lsmod | grep nouveau若有输出&#xff0c;没有禁用&#xff0c;进行以下操作禁用。 sudo gedit /etc/modprobe.d/blacklist.conf在文件末尾中添加两条&…...

R3nzSkin英雄联盟皮肤修改器:终极免费皮肤体验完整指南

R3nzSkin英雄联盟皮肤修改器&#xff1a;终极免费皮肤体验完整指南 【免费下载链接】R3nzSkin Skin changer for League of Legends (LOL) 项目地址: https://gitcode.com/gh_mirrors/r3n/R3nzSkin R3nzSkin是一款专为《英雄联盟》玩家设计的开源内存修改工具&#xff0…...

Perplexity如何秒级定位IEEE顶会论文?:2024最新实测验证的7步精准检索法

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Perplexity如何秒级定位IEEE顶会论文&#xff1f; Perplexity 是一款基于大语言模型的实时搜索增强工具&#xff0c;其核心优势在于将语义理解与权威学术数据库&#xff08;如 IEEE Xplore、ACM DL、ar…...

ArcGIS标注进阶:手把手教你搞定分式标注和河流左斜体(附完整表达式)

ArcGIS标注进阶&#xff1a;分式标注与河流左斜体实战指南 在地图制图领域&#xff0c;专业标注是提升可视化效果的关键环节。许多GIS工程师在进行水文地质制图时&#xff0c;常遇到分式标注格式混乱、河流名称无法实现标准左斜体等痛点问题。本文将彻底解决这些标注难题&#…...

Nodeunit源码探秘:核心模块与异步测试实现原理

Nodeunit源码探秘&#xff1a;核心模块与异步测试实现原理 【免费下载链接】nodeunit Easy unit testing in node.js and the browser, based on the assert module. 项目地址: https://gitcode.com/gh_mirrors/no/nodeunit Nodeunit 是一个基于 Node.js 断言模块的轻量…...

Applite:用图形化界面轻松管理Mac软件的终极解决方案

Applite&#xff1a;用图形化界面轻松管理Mac软件的终极解决方案 【免费下载链接】Applite User-friendly GUI macOS application for Homebrew Casks 项目地址: https://gitcode.com/gh_mirrors/ap/Applite 还在为Mac上繁琐的软件管理而烦恼吗&#xff1f;Applite作为一…...

3步搞定微信聊天记录导出:Mac用户必备的数据备份指南

3步搞定微信聊天记录导出&#xff1a;Mac用户必备的数据备份指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否担心珍贵的微信聊天记录因为手机丢失或系统升级而…...

我受够了手动SEO,所以我让AI替我打工了

我受够了手动SEO&#xff0c;所以我让AI替我打工了 这事得从三个月前说起。我坐在电脑前&#xff0c;面前开了十四个标签页。一个Google Search Console在转圈圈&#xff0c;一个Ahrefs在加载报告&#xff0c;一个空白Google Doc等着我写东西&#xff0c;还有一个WordPress后台…...

SoC设计中虚拟原型技术与TLM建模实践

1. 虚拟原型技术概述在SoC设计领域&#xff0c;虚拟原型技术(Virtual Prototyping)已经成为现代芯片开发流程中不可或缺的关键环节。这项技术的核心价值在于&#xff0c;它能够在RTL级硬件设计完成之前&#xff0c;就为软件团队提供一个可执行的硬件抽象模型。作为一名经历过多…...

第八部分-企业级实践——37. 容器编排选型

37. 容器编排选型 1. 容器编排概述 容器编排平台负责管理容器的整个生命周期&#xff0c;包括部署、扩缩容、负载均衡、服务发现、滚动更新等。Docker Swarm 和 Kubernetes 是目前主流的容器编排方案。 ┌──────────────────────────────────…...

ARM PMU性能监控单元架构与PMEVTYPER寄存器详解

1. ARM PMU性能监控单元架构解析性能监控单元(Performance Monitoring Unit, PMU)是现代ARM处理器中用于硬件级性能分析的关键组件。作为芯片上的专用硬件计数器&#xff0c;PMU能够在不显著影响程序执行效率的前提下&#xff0c;实时捕获各类微架构事件。与软件层面的性能分析…...