sizeof与strlen()、递归优化题解
一、sizeof
sizeof是C/C++中的一个操作符(operator),确切的说是一个编译时运算符,参数可以是数组、指针、类型、对象、函数等。用于统计类型或者变量所占的内存字节数。由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。
二、strlen()
是C标准库中的字符串函数,要在运行时才能计算。参数必须是字符型指针(char*), 且必须是以'\0'结尾的。它的功能是:返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符'\0'。返回的长度大小不包括'\0'。
三、实例
1、char *str = "hello";
strlen(str); //它的值是5,因为hello这个字符串有5个字符
sizeof(str); //它的值是4,因为char *是一个指针类型,它占4个字节。
sizeof("hello"); //它的值是5,是因为hello有5个字符,每一个字符占1个字节。
2、int a[2] = {0};
sizeof(a); //它的值是8,因为a中有2个int型变量,每个int型占4个字节,所以8字节
strlen(a) //a相当于一个指针,但是strlen只能接受char*类型,所以编译时出错
3、char arr[10] = "Hello";
int
len_one = strlen(arr);
int len_two = sizeof(arr);
cout << len_one << " and " << len_two
<< endl;
输出结果为:5 and 10
strlen只关心存储的数据内容,不关心空间的大小和类型。
sizeof返回定义arr数组时,编译器为其分配的数组空间大小,不关心里面存了多少数据(10x1)。
4、char * parr = new char[10];
int len_one = strlen(parr);
int len_two = sizeof(parr);
int len_three = sizeof(*parr);
cout << len_one <<
" and " << len_two << " and " <<
len_three << endl;
输出结果:3 and 4 and 1
第一个输出结果3实际上每次运行可能不一样,这取决于parr里面存了什么(从parr[0]开始直到遇到第一个'\0'结束);
第二个结果实际上本意是想计算parr所指向的动态内存空间的大小,但是事与愿违,sizeof认为parr是个字符指针,因此返回的是该指针所占的空间(指针的存储用的是长整型,所以为4)
第三个结果,由于*parr所代表的是parr所指的地址空间存放的字符,所以长度为1。
面试题:定义一个空的数据类型,里面没有任何成员变量和成员函数,对该类型求sizeof,得到的结果是多少?
答案:是1,为什么不是0?空类型的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明该类型的实例时,它必须在内存中占有一定的空间,否则无法使用这些实例(也就不能求sizeof了),至于占用多少内存,由编译器决定,Visual Studio中每个空类型的实例占用1字节的空间。
扩展1:如果在该类型中添加一个构造函数和析构函数,再求sizeof,得到的结果是多少?
答案:还是1。调用构造函数和析构函数只需要知道函数的地址即可,而这些地址只与类型相关,而与类型的实例无关,编译器也不会因为这两个函数而在实例内添加任何额外的信息。
注:不管添加的是构造函数还是析构函数还是其它任何类型的函数,都是这个结果。
扩展2:那如果把析构函数标记为虚函数呢?
答案:C++的编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针,在32位机器上,一个指针占4字节空间,因此求sizeof得到4;如果是64位则为8。
测试用例:
#include <stdio.h> struct nullType { }; struct type1 { type1() {} ~type1() {} int print() { printf("Alexia"); return ; } }; struct type2 { type2() {} virtual ~type2() {} }; int main() { printf("sizeof(nullType) = %d\n", sizeof(nullType)); printf("sizeof(type1) = %d\n", sizeof(type1)); printf("sizeof(type2) = %d\n", sizeof(type2)); return ; }
代码的优化,给出下一段代码,请做出最好的优化
int f(int n) {
if(n<=)
return n*n;
else {
return f(n-)*f(n-) -f(n-)*f(n-);
}
}
解答
无非是将递归转化为循环,防止重复计算中间值,跟斐波那契数列f(n)=f(n-1)+f(n-2)一样,解决方式也一样,就是利用几个临时变量保存中间值,然后每次循环都更新临时变量即可。过程没啥好说的,直接给出代码即可。
int f2(int n) {
int first = ;
int second = ;
int third = ;
int fourth = ;
if(n<=)
return n*n;
for(int i = ; i <= n; ++i) {
int tmp = fourth * first - third * third;
first = second;
second = third;
third = fourth;
fourth = tmp;
}
return fourth;
}
sizeof与strlen()、递归优化题解的更多相关文章
- sizeof和strlen的区别和联系总结
link:http://blog.csdn.net/ghevinn/article/details/9974967 strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头 ...
- C语言中sizeof与strlen区别
本文转载自:http://www.2cto.com/kf/201109/105100.html 1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc& ...
- sizeof、strlen、字符串、数组,整到一块,你还清楚吗?
写在前面 sizeof.strlen.字符串.数组,提到这些概念,相信学过C语言的人都能耳熟能详,也能谈得头头是道,但是,在实际运用中,当这些内容交织在一起时,大家却不一定能搞地清清楚楚,本文的目的正 ...
- sizeof和strlen的区别
一.sizeof sizeof(...)是运算符,而不是一个函数. sizeof操作符的结果类型是size_t,在头文件中typedef为unsigned int,其值在编译时即计算好了, ...
- Sizeof与Strlen的区别与联系
转自:http://www.cnblogs.com/carekee/articles/1630789.html 一.sizeof sizeof(...)是运算符,在头文件中typedef为uns ...
- Sizeof与Strlen的区别与联系(转)
Sizeof与Strlen的区别与联系 一.sizeof sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型 ...
- sizeof()和strlen()
sizeof计算的是栈中大小 P { margin-bottom: 0.21cm; direction: ltr; color: rgb(0, 0, 0); text-align: justify } ...
- sizeof 和 strlen 的区别
sizeof 和 strlen 都是c/c++ 中常见的符号,他们的功能是判断数组长度.那么他么到底有什么区别 1.sizeof 不是函数,而是一个操作符.字节数的计算在程序编译时进行,而不是在 ...
- C++-sizeof和strlen的区别
一.sizeof sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型.对象.函数等. 它的功能是:获得保 ...
随机推荐
- 属性检测 In,hasOwnPreperty()和propertyIsEnumerable()
IN 左侧是属性名:右侧是对象名, 如果 属性是 自有属性 或者继承属性 则返回 TRUE var o={x:1,y:2} "x" in o 返回 true: hasOw ...
- JDK1.7之Fork/join
Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.Fork/Join框架要完成两件事情: 1.任务分 ...
- ijkplayer实现IMediaDataSource
由于ijkplayer不能识别android.resource类型的资源在播放raw中的文件的时候用IjkMediaPlayer不能正常播放,实现IMediaDataSource为IjkMediaPl ...
- PHP面向对象程序设计之抽象类和抽象方法
抽象类: 抽象类不能被实例化.抽象类中只定义(或部分实现)子类需要的方法.子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化. 我们可以用一个abstract关键字来定义一个抽象类,示例如下: ...
- vue脚手架解决跨域问题-------配置反向代理
1.打开config/index.js 2.在dev配置对象中找到proxyTable:{} 3.添加如下配置 // 配置反向代理,解决跨域请求 proxyTable: { '/api': { tar ...
- spring半自动代理
1.被代理类接口Person.java package com.xiaostudy; /** * @desc 被代理类接口 * * @author xiaostudy * */ public inte ...
- chrome关闭后还在进程中运行
1.网上搜到信息: 设置 “即使关闭浏览器也后台运行” 取消打勾 2.然后我找了一下,应该是这个选项:“关闭 Google Chrome 后继续运行后台应用” 3. 4. 5.
- java 在Excel中插入图片 POI实现
一.POI简介 Jakarta POI 是apache的子项目,目标是处理ole2对象.它提供了一组操纵Windows文档的Java API 目前比较成熟的是HSSF接口,处理MS Excel(97- ...
- Appium 自动化测试(5)-- Appium详细介绍:Appium 手机自动化测试_TesterHome公开版pdf
- srs部署到ubuntu 18.04 server
srs.txt ubuntu 18.04 安装 srs 1. 上传srs_40.7z和h2ws.7z到linux服务器,然后远程ssh连接 (假设登陆用户名是bob,linux服务器ip是192.16 ...