c++ 一维数组长度_每天一点C / 一维数组和指针

d13f3feeb683240ea5fa796d56be8072.png

哈喽,我是老吴,继续记录我的学习心得。

每天一点系列是我对微习惯的践行。现在能做到每天一点 C,将来就会有更多的每天一点系列,没人规定嵌入式软件工程师就只能学习 C 语言和折腾 Linux,不要给自己设限。

为什么是每天一点?
养成写作习惯的第一步:放弃追求大段的、固定的、安静的写作时间,培养随时写作的能力。

同样的技巧也能应用到技术学习上,工程师也可以放弃追求大段的、固定的、安静的看书写代码的时间。遇到一个新知识,第一时间找到相关资料,找到切入点并将其记录在自己的技术笔记中,并且定期复查及完善。


一、每天一点C / 数组和指针

正文目录:

1. 数组名是该数组首元素的地址
2. 用指针操作数组
3. 数组和指针的关系密切
4. 编写处理一维数组的函数:传递数组起始地址+数组长度
5. 编写处理一维数组的函数:传递数组起始地址+结束地址

学习环境:

  • Ubuntu 16.04
  • gcc version 5.4.0

1. 数组名是该数组首元素的地址

演示 demo:

#define MONTHS 12
int main(void){
    int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};
    
    if (days == &days[0])
        printf("TRUE\n");
    
    return 0;
}

运行效果:

$ gcc array_name.c -o array_name

$ ./array_name 
TRUE

相关要点:

  • 数组名和该数组首元素的地址都是常量,在程序的运行过程中,不会改变。

2. 用指针操作数组

演示 demo:

#define SIZE 4
int main(void){
    short dates [SIZE];
    short * pti;
    short index;
    double bills[SIZE];
    double * ptf;
    
    pti = dates;    // assign address of array to pointer
    ptf = bills;
    printf("%23s %15s\n", "short", "double");
    for (index = 0; index         printf("pointers + %d: %10p %10p\n",  index, pti + index, ptf + index);
    
    return 0;
}

运行效果:

$ gcc point_array.c -o point_array

$ ./point_array
                  short          double
pointers + 0: 0x7ffc890b17c0 0x7ffc890b17d0
pointers + 1: 0x7ffc890b17c2 0x7ffc890b17d8
pointers + 2: 0x7ffc890b17c4 0x7ffc890b17e0
pointers + 3: 0x7ffc890b17c6 0x7ffc890b17e8
  • 指针的值是它所指向对象的地址,指针前面使用 * 运算符可以得到该指针所指向对象的值。

  • %p 会以十六进制显示指针的值

  • 必须声明指针所指向对象类型,原因之一:计算机既要知道储存对象的地址,又要知道储存对象需要多少字节。

  • 指针加 1 指的是增加一个数据存储单元。对数组而言,这意味着加 1 后的地址是下一个元素的地址,而不是下一个字节的地址。


3. 数组和指针的关系密切

以下关系表明了数组和指针的关系十分密切:

days + 2 == &days[2]   // TRUE,相同的地址
*(days + 2) == days[2] // TRUE,相同的值

演示 demo:

int main(void){
    int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int index;
    
    for (index = 0; index         printf("Month %2d has %d days.\n", index +1, *(days + index));
    
    return 0;
}

运行效果:

$ gcc point_array2.c -o point_array2

$ ./point_array2 
Month  1 has 31 days.
Month  2 has 28 days.
...
Month 12 has 31 days.
  • C 语言在描述数组表示法时借助了指针:ar[n]的意思是*(ar + n)。

  • 可在编写程序时适时使用 数组表示法或指针表示法,这是两种功能等效的方法。大多数情况下可以用指针表示数组,反过来,也可以用数组表示指针。

  • 编译器编译这两种写法生成的代码相同。


4. 编写处理一维数组的函数:传递数组起始地址+数组长度

假设要编写一个处理数组的函数,该函数返回数组中所有元素之和,待处理的是名为 data 的 int 类型数组,应该如何调用该函数?

演示 demo:

int sum(int ar[], int n);
int main(void){
    int data[SIZE] = {20,10,5,39,4,16,19,26,31,20};
    long answer;
    
    answer = sum(data, SIZE);
    printf("The total number of data is %ld.\n", answer);
    printf("The size of data is %zd bytes.\n",
           sizeof data);
    
    return 0;
}

int sum(int ar[], int n){
    int i;
    int total = 0;
    
    for( i = 0; i         total += ar[i];
    printf("The size of ar is %zd bytes.\n", sizeof ar);
    
    return total;
}

运行效果:

$ gcc func_array.c -o func_array
func_array.c: In function ‘sum’:
func_array.c:26:53: warning: ‘sizeof’ on array function parameter ‘ar’ will return size of ‘int *’ [-Wsizeof-array-argument]
     printf("The size of ar is %zd bytes.\n", sizeof ar);
                                                     ^
func_array.c:19:13: note: declared hereint sum(int ar[], int n)
$ ./func_array
The size of ar is 8 bytes.
The total number of data is 190.
The size of data is 40 bytes.
  • 数组名是该数组首元素的地址,所以实参 data 是一个储存int 类型值的地址,那么函数 sum 的形参数就应该是一个指针。

  • 在函数声明或函数定义中,int ar[] 等效于 int *ar,本质上都应该看作是指针。

  • 只有在函数声明或函数定义中,才可以用int ar[]代替int *ar

  • 函数声明可以省略参数名,所以下面 4 种原型都是等价的:

  • 注意编译器的警告信息:warning: ‘sizeof’ on array function parameter ‘ar’ will return size of ‘int *’,这是在提示程序员你打印的是指针的 size,而不是整个数组的 size。

int sum(int *ar, int n);
int sum(int *, int);
int sum(int ar[], int n);
int sum(int [], int);
  • 一般会把数组的参数作为其中一个参数传递给处理数组的函数。

5. 编写处理一维数组的函数:传递数组起始地址+结束地址

演示 demo:

int sump(int * start, int * end);
int main(void){
    int data[SIZE] = {20,10,5,39,4,16,19,26,31,20};
    long answer;
    
    answer = sump(data, data + SIZE);
    printf("The total number of data is %ld.\n", answer);
    
    return 0;
}

int sump(int * start, int * end){
    int total = 0;
    
    while (start     {
        total += *start;
        start++;next element
    }
    
    return total;
}

运行效果:

$ gcc func_array2.c -o func_array2

$ ./func_array2
The total number of marbles is 190.

相关要点:

  • 注意 answer = sump(data, data + SIZE) 和 while (start < end),这是一种推荐用法,简洁且清晰。因为下标从 0 开始,所以 data + SIZE 指向数组末尾的下一个位置。

  • data + SIZE 是推荐的,但是 data[SIZE] 则是错误的。

  • 处理数组的函数实际上用指针作为参数,但是在编写这样的函数时,可以选择是使用数组表示法还是指针表示法。数组表示法让函数是处理数组的这一意图更加明显,而对于喜欢指针的程序员,使用指针表示法,则觉得使用指针更自然。

二、思考技术,也要思考人生

我喜欢学习技术,但我更爱学习如何生活

你和我各有一个苹果,如果我们交换苹果的话,我们还是只有一个苹果。但当你和我各有一个想法,我们交换想法的话,我们就都有两个想法了。

dd22fff30d7a08fdd72ca06009035368.png

如果你也对 嵌入式系统 (Linux、RTOS、OpenWrt、Android) 和 开源软件 感兴趣,并且想和更多人互相交流学习的话,请关注我的公众号:嵌入式Hacker,一起来学习吧。

无论是关注或转发,还是打赏,都是对作者莫大的支持。对了,记得点 在看和点赞 ,如果你还想看到我的推送的话。

祝各位工作顺利,家庭幸福,财源滚滚~

ps:
欢迎加入我的微信群:加我微信,我拉你进群,暗号(加群)。

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

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

相关文章

mysql事务中怎么更改空值_MySQL事务

1.事务1.事务特性--ACIDAtomicity(原子性):要么全做,要么不做,不能只做一半(银行转账)Consistency(约束性):事务的前后,约束都能满足Isolation(依赖性):事务之间是独立的,互不影响的Durability(持久性):事务执行之后,事物的结果可以持久保存2.事务隔离级别:read uncommitted:可…

线程池实现填充短信_填充一个池需要多少个线程?

线程池实现填充短信在最近几个月中&#xff0c;我们一直看到很小但持续的操作失败&#xff0c;但有一个奇怪的异常– org.springframework.jdbc.CannotGetJdbcConnectionException –“无法获得JDBC连接&#xff1b; 嵌套异常是java.sql.SQLException&#xff1a;客户端尝试检出…

jsf标签_多个动态包含一个JSF标签

jsf标签每个JSF开发人员都知道ui&#xff1a;include和ui&#xff1a;param标签。 您可以包括一个facelet&#xff08;XHTML文件&#xff09;并传递一个对象&#xff0c;该对象将在包含的facelet中可用&#xff0c;如下所示&#xff1a; <ui:include src"/sections/co…

spring 长轮询_Spring集成文件轮询和测试

spring 长轮询我最近实施了一个小项目&#xff0c;在该项目中&#xff0c;我们必须轮询文件夹中的新文件&#xff0c;然后在文件内容上触发服务流。 Spring Integration非常适合此要求&#xff0c;因为它带有一个通道适配器 &#xff0c;该适配器可以扫描文件夹中的新文件&…

您将在下一个项目中使用JSF吗?

上周有一篇很棒的stackoverflow博客文章&#xff0c;主题是“ JavaScript框架的残酷生命周期” 。 这篇文章是关于Javascript UI框架&#xff08;angularjs&#xff0c;angular&#xff0c;jquery和react&#xff09;的流行和流行的速度。 这篇文章的关键指标是每月关于框架的问…

使用java自带的日志管理_java日志管理

1.相关概念日志统一框架(日志门面)&#xff1a;apache commons logging、slf4j日志实现框架(实现层)&#xff1a;JDK自带的logging(java.util.logging)、log4j、Java Util Logging、log4j2、logback.(1)JDK自带的logging(java.util.logging)用法&#xff1a;1 importjava.util.…

安卓4.4玩java_Android4.4运行过程中闪退java.lang.NoClassDefFoundError

上周五项目测试时发现一个奇怪的Bug&#xff0c;项目中依赖了一个第三方框架&#xff0c;但是在android4.0-4.4.4之间的系统中运行会直接闪退&#xff0c;抛出错误异常为java.lang.NoClassDefFoundError。第一次遇到这样的问题&#xff0c;google了好久找到了以下几个原因&…

update se_Java SE 7 Update 25 –发行说明进行了解释。

update se昨天是CPU日。 Oracle通过6月的Java重要补丁更新发布了Java SE更新25 。 在4月的最后一次重大更新之后&#xff0c;这是最后一次与Oracle其他所有Oracle产品都不适合的Oracle重要补丁更新计划。 从2013年10月开始 &#xff0c;Java安全修补程序将遵循四个年度安全发布…

java scavenge_请概述一下Java中都有哪些垃圾收集器

1、Serial(串行GC)收集器Serial收集器是一个新生代收集器&#xff0c;单线程执行&#xff0c;使用复制算法。它在进行垃圾收集时&#xff0c;必须暂停其他所有的工作线程(用户线程)。是Jvmclient模式下默认的新生代收集器。对于限定单个CPU的环境来说&#xff0c;Serial收集器由…

阿帕奇光束

Apache Beam是一个开放源代码统一模型&#xff0c;用于定义批处理和流数据并行处理管道。 使用一种开源的Beam SDK&#xff0c;您可以构建一个定义管道的程序。 然后&#xff0c;该管道由Beam支持的分布式处理后端之一执行&#xff0c;这些后端包括Apache Apex &#xff0c; Ap…

java音乐登陆界面_第四篇——Spring音乐登录界面设计及实现(C#)

Spring音乐播放器&#xff0c;我们小组设计其启动时有一个登录界面&#xff0c;用户初次可以注册&#xff0c;输入用户名和密码&#xff0c;点击注册即将输入信息保存到register文本文件中&#xff1b;如果已有用户名&#xff0c;输入用户名和密码&#xff0c;点击登录&#xf…

java中线性结构的例子_java数据结构--线性结构

一、数据结构数据结构由数据和结构两部分组成&#xff0c;就是将数据按照一定的结构组合起来&#xff0c;这样不同的组合方式有不同的效率&#xff0c;可根据需求选择不同的结构应用在相应在场景。数据结构大致分为两类&#xff1a;线性结构(如数组&#xff0c;链表&#xff0c…

Spring Boot和JSP

本指南展示了如何使用Spring Boot通过JSP创建MVC Web应用程序。 先决条件&#xff1a; Eclipse IDE&#xff08;最新版本&#xff09; Maven的4 Java 1.8 1.创建Maven Web项目 打开eclipse&#xff0c;然后创建一个新的Maven Web项目&#xff0c;并将其命名为SpringBootWe…

判断用户名和密码是否正确java_facebook中如何判断用户名和密码是否正确

Do you hear the angel?Do you think that this really has the angel in the world?We knew from the story in the book, the angel contain the wing of the beauty, beautiful face , the mind of the docile, generous breadth of view, they would like to sacrifice t…

使用Spock测试您的代码

Spock是针对Java和Groovy应用程序的测试和规范框架。 Spock是&#xff1a; 极富表现力 促进测试的给定/何时/然后语法 与大多数IDE和CI服务器兼容。 听起来不错&#xff1f; 通过快速访问Spock Web控制台&#xff0c;您可以非常快速地开始使用Spock。 当您有一个喜欢的小测…

php删除文见,php如何删除文件夹

php删除文件夹的方法&#xff1a;首先创建一个PHP示例文件&#xff1b;然后通过“function deldir($dir) {...}”删除目录下的文件并删除当前文件夹即可。php删除文件夹及其文件夹下所有文件function deldir($dir) {//先删除目录下的文件&#xff1a;$dhopendir($dir);while ($…

阿帕奇齿轮泵

Apache Gearpump是实时大数据流引擎。 它从2014年中期开始就在Intel上作为GitHub上的开源项目构想的&#xff0c;并于2016年3月8日进入Apache孵化。Gearpump的名称是对工程术语“齿轮泵”的指称&#xff0c;它是一个超级简单的泵&#xff0c;由只有两个齿轮&#xff0c;但是在流…

php网站标签加小图标,在htmltitle/title标签添加图标,网页title左边显示网页的logo图标...

如图在黑色所画圆之中显示一个图标&#xff1a;步骤一&#xff1a;在图片中显示图标&#xff0c;这里的图片只支持ico格式&#xff0c;需要转换图片格式.原始图像可以接受: .jpg .jpeg .gif .png等图像格式在这个网址http://www.php.cn/上传你的原始图片然后生成ico格式图标(百…

在Java中解析JSON时如何忽略未知属性– Jackson @JsonIgnoreProperties注释示例

使用Jackson API在Java中解析JSON时的常见问题之一是&#xff0c;当您的JSON包含未知属性&#xff08;即您的Java类没有对应于所有JSON属性的所有字段&#xff09;时&#xff0c;该操作将失败。 例如&#xff0c;如果您正在使用REST Web服务中的JSON&#xff0c;并且明天他们在…

php界面设置编码格式,php设置编码格式的方法

php设置编码格式的方法发布时间&#xff1a;2020-08-15 11:02:56来源&#xff1a;亿速云阅读&#xff1a;78作者&#xff1a;小新这篇文章主要介绍php设置编码格式的方法&#xff0c;文中介绍的非常详细&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们一定要看完&…