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,一经查实,立即删除!

相关文章

设计模式 工厂方法_工厂设计模式–一种有效的方法

设计模式 工厂方法如您所知&#xff0c;“工厂方法模式”或俗称“工厂设计模式”是“创意设计模式”类别下的一种设计模式。 模式背后的基本原理是&#xff0c;在运行时&#xff0c;我们根据传递的参数获得类似类型的对象。 关于这种模式的文章很多&#xff0c;开发人员可以通过…

SMPP Java示例(客户端)

这篇文章通过创建一个简单的SMPP客户端向移动用户发送短信来提供SMPP Java示例&#xff0c;使用该客户端我们可以简单地提交以向单个移动用户发送消息&#xff0c;也可以一次将消息广播给多个移动用户。另外&#xff0c;我们将验证交货收据。 出于客户端的目的&#xff0c;我们…

mysql插入另一个表中数据_MySql中把一个表的数据插入到另一个表中的实现

1.如果2张表的字段一致&#xff0c;并且希望插入全部数据&#xff0c;可以用这种方法&#xff1a;INSERT INTO 目标表 SELECT * FROM 来源表;insert into insertTest select * from insertTest2;2.如果只希望导入指定字段&#xff0c;可以用这种方法&#xff1a;INSERT INTO 目…

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

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

mysql自定义函数多参数_自定义mysql函数 - 无法传递参数

作为标题状态。这里的功能DELIMITER //CREATE FUNCTION GetCreateValue( table_name CHAR(64), id_field CHAR(64), name_field CHAR(64), name_value CHAR(64) )RETURNS INTEGERBEGINDECLARE ret INTEGER;SELECT count(*) INTO ret FROM table_name WHERE name_field name_va…

与Zapier集成

整合很无聊。 也是不可避免的。 但是我不会写有关企业集成模式的文章 。 相反&#xff0c;我将解释如何创建与Zapier集成的应用程序。 什么是Zapier &#xff1f; 它是一项服务&#xff0c;使您可以通过其API&#xff08;或协议&#xff09;连接两个&#xff08;或多个&#x…

python用psf函数_python学习之-类的内置函数

内置方法&#xff1a;__str__(该方法必须返回字符串类型),在对像被打印时自动触发,然后将该方法的返回值当做打印结果输出)class People:def __init__(self,name,age):self.namenameself.ageagedef __str__(self): #绑定给对象的方法return ‘‘ %(self.name,self.age) #这个方…

多用户远程连接mysql_Mysql权限控制 - 允许用户远程连接

Mysql为了安全性&#xff0c;在默认情况下用户只允许在本地登录&#xff0c;可是在有此情况下&#xff0c;还是需要使用用户进行远程连接&#xff0c;因此为了使其可以远程需要进行如下操作&#xff1a;一、允许root用户在任何地方进行远程登录&#xff0c;并具有所有库任何操作…

cxf 服务端soap报文_使用Apache CXF开发SOAP Web服务

cxf 服务端soap报文在上一篇文章中&#xff0c;我逐步介绍了使用apache CXF开发简单的RESTFull服务的步骤。 在本文中&#xff0c;我将讨论使用CXF开发SOAP Web服务。 在继续前进之前&#xff0c;让我们先了解一下构成SOAP Web服务的概念/元素 SOAP或简单对象访问协议 SOAP是一…

Java 8日期和时间

如今&#xff0c;一些应用程序仍在使用java.util.Date和java.util.Calendar API&#xff0c;包括使我们的生活更轻松地使用这些类型的库&#xff0c;例如JodaTime。 但是&#xff0c;Java 8引入了新的API来处理日期和时间&#xff0c;这使我们可以对日期和时间表示进行更精细的…

php mysql 随机字符串_MySQL_Mysql 自定义随机字符串的实现方法,前几天在开发一个系统,需要 - phpStudy...

Mysql 自定义随机字符串的实现方法前几天在开发一个系统&#xff0c;需要用到随机字符串&#xff0c;但是mysql的库函数有没有直接提供&#xff0c;就简单的利用现有的函数东拼西凑出随机字符串来.下面简单的说下实现当时.1.简单粗暴.select ..., substring(MD5(RAND()),floor(…

python哪些类型可以作为迭代器_python0.8-----set类型与迭代器

set:类似dict&#xff0c;是一组dict的集合&#xff0c;不存储value。本质&#xff1a;无序(没有下标)无重复的元素的集合。创建&#xff1a;创建set需要一个list或者tuple或者dict作为输入集合。重复元素在色中会被自动过滤。s1[1,2,3,4,5,6,1,2]set(s1){1,2,3,4,5,6} --表示》…

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

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

python线性回归x可以数量不一样吗_R和Python中的线性回归 - 在同一问题上的结果不同...

只是指出这一点&#xff1a; statsmodel s least squares fit does by default not include a constant. If we remove the constant from R适合&#xff0c;我们得到与Python实现非常相似的结果&#xff0c;或者相反&#xff0c;如果我们向 statsmodel -fit添加一个常量&#…

PostgreSQL开放自由

Open Liberty是源自WebSphere Liberty的有趣的新型OSS Java EE应用服务器。 您可以将Open Liberty配置为使用PostgreSQL作为其默认数据源&#xff0c;如下所示&#xff1a; 将<datasource> &#xff0c; <jdbcDriver>和<library>指令添加到server.xml配置中…

实现mysql百度式查询_mysql查询优化建议(百度)

1.对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引。2.应尽量避免在 where 子句中使用!或<>操作符&#xff0c;否则将引擎放弃使用索引而进行全表扫描。3.应尽量避免在 where 子句中对字段进行 null 值判断…

海思芯片怎么使用tde给qt加速_3519移植Qt适配附件

【实例简介】修改Qt5.5.1linuxfb插件代码&#xff0c;适配海思3519平台【实例截图】【核心代码】3519Qt移植.tar├── 3519Qt绉绘│ ├── linuxfb│ │ ├── include│ │ │ ├── acodec.h│ │ │ ├── fisheye_calibrate.h│ │ │ ├─…

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

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

用Java比较文件

我正在为PACKT创建一系列有关Java网络编程的视频教程。 有整节关于Java NIO。 一个示例程序是通过原始套接字连接将文件从客户端复制到服务器。 客户端从磁盘读取文件&#xff0c;服务器将到达的字节保存到磁盘。 因为这是一个演示&#xff0c;所以服务器和客户端在同一台计算机…

java哈希_Java如何采用哈希码实现分类(以员工分配为例)

5.总程序&#xff1a;下面代码是我们获取的所有的程序代码&#xff0c;如下&#xff1a;public static void main(String[] args) {Scanner scannew Scanner(System.in);System.out.println("请输入员工姓名&#xff1a;");String namescan.nextLine();System.out.pr…