C语言中数组与指针的区别

一.  简介

本文学习了 C语言中数组与指针的区别。这样的话,可以在编写C代码时规避掉出错的问题。

二.  C语言中数组与指针的区别

 1.  数组

定义字符串数组时,必须让编译器知道需要多少空间。

一种方法是用足够空间的数组存储字符串。例如如下:

char buf[40] = "hello world!";

或者 如下:

char buf[40] = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0'};

注意,最后的空字符。没有 '\0'就不是一个字符串,而是一个字符数组。

通常,让编译器确定数组的大小很方便。回忆一下,省略数组初始化声明中的大小,编译器会自动计算数组的大小,如下所示:

char buf[] = "hello world!";

让编译器计算数组的大小只能用在初始化数组时,如果创建一个稍后再填充的数组,就必须在声明时指定大小。

2. 指针

可以用指针表示法创建字符串。例如如下:

char *ptr = "hello world!";

3.  以上数组与指针有什么区别?

数组

数组形式在计算机的内存中分配为一个内含 13(还包括 '\0')个元素的数组,每个元素被初始化为字符串常量对应的字符。

通常字符串都作为可执行文件的一部分存储在数据段中,当把程序载入内存时,也载入了程序中的字符串。字符串存储在静态存储区中,但是,程序在开始运行过时才会为该数组分配内存。此时,才将字符串拷贝到数组中,注意,此时字符串有两个副本,一个是静态内存中的字符串常量,另一个是存储在 buf数组中的字符串。

这里关键要理解,在数组形式中,数组 buf是地址常量。不能更改 buf,如果改变了  buf,则意味着改变了数组的存储位置(即地址)。

可以进行类似 buf+1 这样的操作,标识数组的下一个元素。但是,不允许进行 ++buf这样的操作,递增运算符只能用于变量名前,不能用于常量。

指针

指针形式 (*ptr) 也使得编译器为字符串在静态存储区预留了 13个元素的空间,另外,一旦开始执行程序,它会为 指针变量 ptr 留下一个存储位置,并把字符串的地址村存在指针变量中,该变量最初指向该字符串的首地址。

但是它的值可以改变。因此,可以使用递增运算符,例如:

++ptr  //指向第2个字符

总之,初始化字符数组把静态存储区的字符串拷贝到数组中,而初始化指针只把字符串的地址拷贝给指针。

数组与指针使用上的区别

初始化字符数组来存储字符串和初始化指针来指向字符串有何区别?

(指向字符串:指向字符串的首字符)

例如,有如下声明:

char buf[] = "come on, TangSan!";
char* ptr = "come on, Xiao Wu!";

两者的主要区别是:数组名 buf是常量,而指针名 ptr是变量。那么实际使用有什么区别?

首先,两者都可以使用数组表示法:

for(i=0; i< 10; i++)
    printf("%c", buf[i]);

for(i=0; i< 10; i++)
    printf("%c", ptr[i]);

其次,两者都能进行指针加法操作:

for(i=0; i< 10; i++)
    printf("%c", *(buf+i));

for(i=0; i< 10; i++)
    printf("%c", *(ptr+i));

但是,只有指针标识法可以进行递增操作:

for(i=0; i< 10; i++)
    printf("%c", *(ptr++));

而对于指针 ptr,是否可以进行如下操作:

ptr[1] = '1';

《C primer Plus》书籍说,编译可能允许这样做,但是对当前的 C标准而言,这样的行为还未定义的。例如,这样的语句可能导致内存访问错误。原因是编译可以使用内存中的一个副本来表示所有完全相同的字符串常量。

但是,我这边在 ubuntu系统上经过测试是不行的,会报段错误。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多表查询练习题

1、创建好数据库 create database text use text --学生表 (students) CREATE TABLE students ( student_id INT PRIMARY KEY, name VARCHAR(50), age INT, major VARCHAR(50) );--课程表 (courses) CREATE TABLE courses ( course_id INT PRIMARY KEY, course_name V…

Linux基础之进程-进程状态

目录 一、进程状态 1.1 什么是进程状态 1.2 运行状态 1.2 阻塞状态 1.3 挂起状态 二、Linux操作系统上具体的进程状态 2.1 状态 2.2 R 和 S 状态的查看 2.3 后台进程和前台进程 2.4 休眠状态和深度休眠状态 一、进程状态 1.1 什么是进程状态 首先我们知道我们的操作系…

Java学习47-Java 流(Stream)、文件(File)和IO - 其他流的使用

1.标准输入流System.in/标准输出流System.out System.in : 标准的输入流&#xff0c;默认从键盘输入 System.out: 标准的输出流&#xff0c;默认从显示器输出(理解为控制台输出) System.setOut()方法和 System.setIn()方法&#xff08;结合下面介绍的打印流举例&#xff09; …

灵活的静态存储控制器 (FSMC)的介绍(STM32F4)

目录 概述 1 认识FSMC 1.1 应用介绍 1.2 FSMC的主要功能 1.2.1 FSMC用途 1.2.2 FSMC的功能 2 FSMC的框架结构 2.1 AHB 接口 2.1.1 AHB 接口的Fault 2.1.2 支持的存储器和事务 2.2 外部器件地址映射 3 地址映射 3.1 NOR/PSRAM地址映射 3.2 NAND/PC卡地址映射 概述…

ctfshow web入门 php反序列化 web267--web270

web267 查看源代码发现这三个页面 然后发现登录页面直接admin/admin登录成功 然后看到了 ///backdoor/shell unserialize(base64_decode($_GET[code]))EXP <?php namespace yii\rest{class IndexAction{public $checkAccess;public $id;public function __construct(){…

定时器的理论和使用

文章目录 一、定时器理论1.1定时器创建和使用 二、定时器实践2.1周期触发定时器2.2按键消抖 一、定时器理论 定时器是一种允许在特定时间间隔后或在将来的某个时间点调用回调函数的机制。对于需要周期性任务或延迟执行任务的嵌入式应用程序特别有用。 软件定时器&#xff1a; …

MySQL表的基本操作

表 创建表 comment是添加一个注释 语法&#xff1a; 说明&#xff1a; field 表示列名 datatype 表示列的类型 character set 字符集&#xff0c;如果没有指定字符集&#xff0c;则以所在数据库的字符集为准 collate 校验规则&#xff0c;如果没有指定校验规则&#xff0c;则…

知识图谱 | 语义网络写入图形数据库(含jdk和neo4j的安装过程)

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本文主要介绍如何使用 Neo4j 图数据库呈现语义网络&#xff0c;并通过 Python 将语义网络的数据写入数据库。具体步骤包括识别知识中的节点和关系&#xff0c;将其转化为图数据库的节点和边&#xff0c;最后通过代码实现数据的写…

两数相加 - (LeetCode)

前言 今天无意间看到LeetCode的一道“两数相加”的算法题&#xff0c;第一次接触链表ListNode&#xff0c;ListNode结构如下&#xff1a; public class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) {this.val val;}ListNode(int val, ListNode next) {…

使用TimeSum教你打造一套最牛的知识笔记管理系统!

从用户使用场景进行介绍软件的使用&#xff1a; 一、用户需求&#xff1a; 我需要一款软件记录我每天&#xff1a; 干了啥事有啥输出&#xff08;文档&#xff09;需要时间统计&#xff0c;后续会复盘记录的内容有好的逻辑关系需要有日历进行展示。 二、软件使用介绍&#xf…

【UE5.1 角色练习】01-使用小白人蓝图控制商城角色移动

目录 效果 步骤 一、导入资源 二、控制角色移动 三、更换角色移动动作 效果 步骤 一、导入资源 新建一个工程&#xff0c;然后在虚幻商城中将角色动画的相关资源加入工程&#xff0c;这里使用的是“动画初学者内容包”和“MCO Mocap Basics” 将我们要控制的角色添加进…

在idea中使用vue

一、安装node.js 1、在node.js官网&#xff08;下载 | Node.js 中文网&#xff09;上下载适合自己电脑版本的node.js压缩包 2、下载完成后进行解压并安装&#xff0c;一定要记住自己的安装路径 一直点击next即可&#xff0c;这部选第一个 3、安装成功后&#xff0c;按住winR输入…

【Shell脚本】Shell编程之数组

目录 一.数组 1.基本概念 2.定义数组的方法 2.1.方法一 2.2.方法二 2.3.方法三 2.4.方法四 2.5.查看数组长度 2.6.查看数组元素下标 3.数组分片 4.数组字符替换 4.1.临时替换 4.2.永久替换 5.数组删除 5.1.删除某个下标 5.2.删除整组 6.数组遍历和重新定义 7…

2024洗地机爆款榜单,哪个牌子洗地机值得买?助你轻松选对洗地机

随着现代生活节奏的加快&#xff0c;人们对于家庭清洁的需求也越来越高。家用洗地机作为一种高效清洁工具&#xff0c;能够帮助您轻松应对家庭地板的清洁问题&#xff0c;节省时间和精力。然而&#xff0c;在选择洗地机时&#xff0c;究竟哪个牌子的洗地机值得买呢&#xff1f;…

【 第一性原理计算方法及应用】

第一性原理计算方法及应用述

Android Iptables 客制化方法及基本使用

Android Iptables 客制化方法及基本使用 Android netd 的自定义链NetdConstants.cpp 的 execIptablesRestore 方法IptablesRestoreController 的 execute 方法使用 oem-iptables-init.sh 添加自定义的防火墙规则oem-iptables-init.sh 示例文件 基本概念Iptables 链Iptables 表 …

关于nvm管理node版本的一些问题

背景&#xff1a; 基于开发项目的迭代不能做到全部更新&#xff0c;有的项目是vue2.0 有的项目是vue3.0&#xff0c; 那么我们开发的时候就需要对node 进行更新&#xff0c;进而产生因为版本不同导致的错误&#xff1a;由此我们需要一款管理 切换node版本的东西&#xff0c;那就…

其它高阶数据结构①_并查集(概念+代码+两道OJ)

目录 1. 并查集的概念 2. 并查集的实现 3. 并查集的应用 3.1 力扣LCR 116. 省份数量 解析代码1 解析代码2 3.2 力扣990. 等式方程的可满足性 解析代码 本篇完。 写在前面&#xff1a; 此高阶数据结构系列&#xff0c;虽然放在⑤数据结构与算法专栏&#xff0c;但还是作…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷5(私有云)

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包…

idea2023.3.2版本全局设置maven地址

idea每次新建项目都默认使用了一个user目录下的地址&#xff0c;而不是自己安装的maven地址&#xff0c;每次创建项目后&#xff0c;都要重新从settings中设置一下maven地址。 可以全局修改&#xff1a;首先在File-->Close Project回到idea最开始的界面 然后在Customize里点…