常见C语言基础说明五:数组名当函数参数传入

2024-05-09 20:20

本文主要是介绍常见C语言基础说明五:数组名当函数参数传入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.  简介

前面几篇学习了  C语言中基础问题,文章如下:

常见C语言基础题说明一-CSDN博客

常见C语言基础说明二:位运算问题-CSDN博客

常见C语言基础说明三:static修饰的函数或变量-CSDN博客

常见C语言基础说明四:#define宏定义与 a---CSDN博客

本文继续学习 嵌入式C开发中,可能涉及的一些C语言基础问题。

二.  常见C语言基础说明四:数组名当函数参数传入

1.  字符串常量、函数内的定义的指针

(1)示例一有如下代码,计算出运行结果:

#include <stdio.h>void get_string(char* p)
{char* ptr = "welcome";p = ptr;
}int main(void)
{ char buf[] = "how are you!";get_string(buf);printf("%s\n", buf);return 0;
}

打印结果为:

how are you!

分析:

数组名是一个指针常量,其只能指向数组的首个元素所在地址。当数组作为函数参数时,会转化(有的也称退化)为一个指针,可以进行一些指针的操作,比如,a++ 来读取下一个元素,但是其转化为的指针也还是指向这个数组的。

这里将 数组名 buf(也就是数组的首个元素的地址)作为函参传入函数中。

buf = ptr 这一句就是将 函数中一个局部变量指针 ptr的地址,而没有改变 数组buf中的内容。 ptr其实是函数的局部变量(局部变量存储在栈区),也就是说当函数执行结束后 ptr会被销毁。

ptr 指向的是一个字符串常量,字符串常量存储在静态存储区。静态存储区的数据,一直存在,只有当程序执行结束退出才会被销毁。

get_string函数执行结束后,由于 ptr这个指针已经销毁,所以,当最后返回到 main函数后,数组buf仍然是 "how are you!"

(2) 示例2 有如下代码,计算结果:

#include <stdio.h>
char* get_string(void)
{char* ptr = "welcome!";  //"welcome"是字符串常量,存储在静态存储区return ptr;
}int main(void)
{ char* ptr2 = "Hello world!";ptr2 = get_string();printf("%s\n", ptr2);return 0;
}

输出结果为:

welcome!

分析如下:

ptr指针是函数 get_string中定义的一个局部变量,函数中局部变量存放在栈区,函数执行完后存放在栈区的变量就释放了,为什么指针还可以返回正常的字符串呢?

这里 ptr 指向的是一个字符常量的字符串,字符串常量存储在静态存储区,所以,"welcome!"这个字符串会一直存在,直到程序运行结束才会销毁。

main主函数中,定义了一个指针 ptr2 指向了 该字符常量的存放地址,所以,main函数最终可以打印出  "welcome!" 该字符串常量。

示例3:而如果是 如下代码,那么就存在问题了:

char* get_string(void)
{char buf[] = "welcome!";  //"welcome"是字符串常量,存储在静态存储区return buf;
}int main(void)
{char* ptr2 = get_string();printf("%s\n", ptr2);return 0;
}

运行会提示段错误。

get_string 函数中定义的是一个局部变量数组,所以存放在栈区,是不能返回。

因为在 get_string函数被调用结束后,数组 buf就已经释放,也就是不存在了。

这篇关于常见C语言基础说明五:数组名当函数参数传入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974399

相关文章

C语言的那些事儿之七

每日一结 深刻理解c中函数参数的传递   一:值传递 main()  {  int a = 4,b = 6;  Exchg1(a, b) /* 这里调用了 Exchg1 函数 */  printf("a = %d, b = %d.\n", a, b);  }    Exchg1(a, b)时所完成的操作代码如下所示。  int x = a; /* ← *

C语言的那些事儿之六

每日一结 ​ 注:不管是什么变量,归根结底,对内存的访问形式分为两类: 1.内存标识符: 通过对内存标识符的访问,实际上是访问内存标识符对应的内容 2.内存空间的地址: 在使用地址访问时,记得在地址前加上*,这表示通过地址去访问地址中相应的内容 3.在你不明白数据和地址在内存中的关系时,不妨画一张内存图

C语言的那些事儿之五

每日一结 1.指针:一个变量的地址   指针变量:专门用来存放变量地址的变量 ​   2.什么是空指针(NULL)         语言定义中说明, 每一种指针类型都有一个特殊值—— “空指针” ——它与同类型的其它所有指针值都不相同, 它“与任何对象或函数的指针值都不相等”。也就是说, 取地址操作符&永远也不能得到空指针,

C语言的那些事儿之四

每日一结 1.在switch-case语句中,若case和break中有多个语句,其之外可以不用花括号,语句之间分号即可。且switch()括号内不能是float类型的,再者,case和 : 之间必须要用空格,且case和 :之间的数必须是整型 ​   2.在do-while()循环中,while(

C语言的那些事儿之三

每日一结 1.对于异或,用于值交换的理解 今天在看C语言的位运算时,看到了如下交换a,b两值的方法:                     a = a^b;                     b = a^b;                     a = a^b; 后来想想,真是太神奇了!其实,我们首先知道,对于任意的

C语言的那些事儿之二

每日一结 1.查找一个数据类型占几个字节,可用sizeof(),具体用法见截图: ​ (注意:sizeof 可以测数据类型在内存空间所占的长度 ,若里面放的是变量,则是测这变量所占的内存空间的长度) 2.在bool类型中,非零为true,零为false,可参照截图: 4.正数的反码,补

C语言的那些事儿之一

每天一结 1.怎么快速切换电脑的界面? 按一下Alt+Tab键是最近用到的两个程序间的切换。如果要在一个程序下实现两个窗口间切换的话,可以按Ctrl+Tab键 2.在linux中,如果你想要实现某种操作,但不知道该用什么命令,除了谷歌百度,就没有其他办法了 3.主目录是指在你打开linux操作系统终端时,最先出现的那个目录就是主目录,这个主目录是可以设置的 4.查找当前目录的

C语言试卷习题

C语言试卷题     ​         二.程序题 1.冒泡排序 答案:略...     2.编写strcpy函数 已知strcpy函数的原型是char *strcpy(char *strDest ,const *strSrc); strD

C语言的那些事儿之八

每日一结 递归函数: 找出fac.c这个函数的问题 递归函数的例题:     结构体: 注: I.在定义结构体时,花括号后面的分号一定不能省! II.因为 -> 运算符的优先级高于 & ,所以&(p -> id)可以写成 &p -> id III.结构体记得在其外部定义,结构体其实说白

读《C语言陷阱与缺陷》一书后的一些注意事项

1.一般而言,赋值运算相对于比较运算出现得更频繁,因此字符数较少的符号=就被赋予了更常用的含义——赋值操作 2.' '不等于零(' '的ASCII码值为32) 3.需要注意的是,除了字符串与字符常量,符号的中间不能嵌有空白(空格符,制表符和换行符)。例如,如果/是为了判断下一个符号而读入的第一个字符,而/之后紧接着* , 那么无论上下文如何,这两个字符都将被当做一个符号 而实