您现在的位置是:亿华云 > 系统运维
由一道面试题所引出的C语言static变量特性
亿华云2025-10-03 02:40:36【系统运维】8人已围观
简介最近部门在准备春招笔试题时,有这样一道题目:用C/C++语言实现一个函数,给定一个int类型的整数,函数输出逆序的整数对应的字符串,例如输入1234,则输出字符串"4321",,输入-1234,则输出
最近部门在准备春招笔试题时,由道引出语有这样一道题目:用C/C++语言实现一个函数,面试给定一个int类型的题所特性整数,函数输出逆序的变量整数对应的字符串,例如输入1234,由道引出语则输出字符串"4321",面试,输入-1234,题所特性则输出字符串"-4321"。变量题目要求,由道引出语不使用标准库,面试以及不能分配动态内存。题所特性当时觉得蛮简单的变量,这不就是由道引出语类似字符串逆转嘛,纸上得来终觉浅,面试绝知此事要躬行,题所特性自己尝试做了一下,发现还是有一些地方值得注意。今天在此整理一下常见的坑,巩固下基础东西。
版本一
算法思路其实很简单:使用对10取余和除法操作依次获取每一位的数字,然后根据ASSIC码转换为字符,将结果存放在一个char型数组中,***返回字符串数组结果,如下所示:
#include<stdio.h> //版本一 const char * reverseInt(int n) { char str[16] = { 0}; int temp = n; int i = 0; if (n < 0) { temp = -n; str[i++] = -; } //当temp除到是一位数的时候退出 while (0 != temp / 10) { char ch = temp % 10 + 48; temp = temp / 10; str[i++] = ch; } //处理原始数据的高防服务器***位 str[i++] = temp % 10 + 48; return str; } int main(int argc, char **agrv) { int test_data1 = 12345; int test_data2 = 789; printf("[test_data1] %d--->%s\n", test_data1, reverseInt(test_data1)); printf("[test_data2] %d--->%s\n", test_data2, reverseInt(test_data2)); return 0; }发现编译出现了警告,如下:
[root@epc.baidu.com ctest]# gcc -g -o test test.c test.c: In function reverseInt: test.c:24:2: warning: function returns address of local variable [-Wreturn-local-addr] return str; ^从编译器给出的信息很清楚的说明了问题:返回了一个局部变量的地址,但是我们知道,函数的局部变量是存在stack中的,当这个函数调用过程结束时,这个局部变量都是要释放掉的,自然就不可再使用了,所以就会产生这样的warning,这个是和变量的生命周期相关的。
版本二
对于版本一存在的问题,很自然的会想到有两种解决方案,***:使用malloc分配动态内存存放结果,但是题目中明确说明不能不能分配动态内存。因此自然排除掉。第二种方案就是将char result[16]改为static型:static char result[16];对,就是云南idc服务商这么一点改动。
#include<stdio.h> //版本二 const char * reverseInt(int n) { static char str[16] = { 0}; int temp = n; int i = 0; if (n < 0) { temp = -n; str[i++] = -; } //当temp除到是一位数的时候退出 while (0 != temp / 10) { char ch = temp % 10 + 48; temp = temp / 10; str[i++] = ch; } //处理原始数据的***位 str[i++] = temp % 10 + 48; return str; } int main(int argc, char **agrv) { int test_data1 = 12345; int test_data2 = 789; printf("[test_data1] %d--->%s\n", test_data1, reverseInt(test_data1)); printf("[test_data2] %d--->%s\n", test_data2, reverseInt(test_data2)); return 0; }运行结果如下:
[root@epc.baidu.com ctest]# ./test [test_data1] 12345--->54321 [test_data2] 789--->98721从运行结果上看,***个测试数据其结果是正确的,但是第二个输出结果确实错误的。这是什么原因?先来回一下用static修饰所修饰的局部变量(也称静态局部变量)特点,如下:
1:静态局部变量定义时未赋初值,则默认初始化为0;
2:静态局部变量其作用域为函数或代码块,其生命周期为整个程序的运行期间;注意这两个概念不要混淆;
3:在一个进程的运行期间,静态局部变量只会初始化一次,就是***次调用该静态局部变量所在函数的时候初始化,此后再调用不会初始化。
好了,到这里,其实问题的原因已经很明显了:在上面程序中,static char str[16] = { 0}只会初始化一次,既在执行reverseInt(test_data1)时初始化,执行完该语句,将结果存放到str中,此时str中的香港云服务器内容为54321,既str[16] = { 5,4,3,2,1,\0};当再次对第二个测试数进行转换调用reverseInt(test_data2)时,str仍然是上次的结果{ 5,4,3,2,1,\0},因此在转换后为98721。
版本三
那么如何解决版本二的问题了,一个很简单的办法就是在reverseInt函数中对static变量str每次使用for循环进行初始化,如下,鉴于篇幅,就不将main函数也贴出来了:
const char * reverseInt(int n) { static char str[16] = { 0}; int temp = n; int i = 0; int j = 0; for (; j < 16; j++) { str[j] = \0; } if (n < 0) { temp = -n; str[i++] = -; } //当temp除到是一位数的时候退出 while (0 != temp / 10) { char ch = temp % 10 + 48; temp = temp / 10; str[i++] = ch; } //处理原始数据的***位 str[i++] = temp % 10 + 48; return str; }运行,能得到我们期望的结果了:
[root@epc.baidu.com ctest]# ./test [test_data1] 12345--->54321 [test_data2] 789--->987其实,版本三还有很多细节需要考虑的,比如:当输入的整数超过int的范围如何处理等等,虽然是小细节,但却十分重要,大家有兴趣可以思考下练练手。
很赞哦!(83)
相关文章
- 2023年值得关注的五大数据中心趋势
- .net 适用于从事Internet相关的网络服务的机构或公司
- 并非一个好米任何人都会给你一个好的价格。那你该如何用以有的好米卖出最理想的价格呢?
- 公司名字不但要与其经营理念、活动识别相统一,还要能反映公司理念,服务宗旨、商品形象,从而才能使人看到或听到公司的名称就能产生愉快的联想,对商店产生好感。这样有助于公司树立良好的形象。
- 普洛斯常熟东南数据中心获LEED金级认证及IDCC绿色算力基础设施奖
- 注册域名要了解几大点?新手有什么方式注册域名?
- 网站页面结构改版,仅是页面样式发生变化,不会对排名、收录有影响;只有涉及到页面URL改变,才会对网站排名、收录有影响。
- 以上的就是为大家介绍的关于域名的详解
- 构建高性能Web服务器:Nginx的基本用法和配置技巧揭秘
- 打开https://www.aizhan.com/输入自己想要查询的域名然后按回车键,如果做过网站都会有数据显示出来