每日一题(六)

9.21数组、字符串的存取效率

在程序中,对数组和字符串的存取,哪个更有效率?

先看一段程序:

#include "stdio.h"
int main() {
    char a = 1;
    char c[] = "123456789";
    char *p  = "123456789";
    a = c[1];
    a = p[1];
    return 0;
}

声明了一个数组c和一个字符串p,然后同样读取其中的一个值,对应的汇编代码如下:

10:a=c[1];
004010678A4DF1 movcl,byteptr[ebp-0Fh]
0040106A884DFC movbyteptr[ebp-4],cl
11:a=p[1];
0040106D8B55EC movedx,dwordptr[ebp-14h]
004010708A4201 moval,byteptr[edx+1]
004010738845FC movbyteptr[ebp-4],al

可以看出对于a = c[1]的操作,是直接将数组中字符串的元素读取到c1寄存器中(也就是a)

对于a = p[1]的操作,显示将指针的值edx中,再根据地址读取字符元素

所以数组的读取比字符串的读取要有效率,即在栈上的数组比指针指向的字符串要读取快。

9.22 求一个int数据 二进制中1的个数

#include <iostream>
using namespace std;

int fun (int x) {
    int count = 0;
    while (x) {
        x &= (x-1);
        ++count;
    }
    return count;
}


int main() {
    int x = 0;
    cin>>x;
    cout<<"ans is :"<<fun(x)<<endl;
    return 0;
}

分析:把一个整数减去1,再和原整数做 & 运算,就会把整数最右边一个1变成0,通过while(x)来计数有多少个1.

9.23 指针与引用的区别

  • 引用只是变量的一个别名,内部是依靠只读指针实现的,引用本身不占用内存空间,不能建立数组的引用
  • 引用在初始化的时候就要指明赋值;而且指针可以在允许的情况下任意时刻赋值
  • 引用不能为NULL;指针可以为NULL
  • 引用保存的是被引用变量的地址
  • sizeof 引用的大小是被引用变量的大小sizeof 指针的大小是指针本身的大小
  • 引用在源代码级相当于一个普通的变量,但是作为函数参数时,传递的是变量地址
  • 指针可以有多级,引用只能一层
  • 引用作为函数返回值传递的时候,不能返回局部变量的引用、函数内new的内存的引用

9.24 编写strcpy

**已知strcpy的函数原型:char *strcpy(char strDest, const char strSrc)其中strDest 是目的字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数,请编写函数 strcpy。

#include <stdio.h>
#include <assert.h>

cahr* strcpy (char *strDest, const char *strSrc)
{
    assert ((strDest != NULL) && (strSrc != NULL));
    char *addr = strDset;
    while ((*strDest++ = *strSrc++) != '\0')return addr;
}
  • assert是宏,不是函数,其的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行
  • strcpy函数会连‘\0’一起拷贝
  • 要用一个临时的变量保存目标字符串的首地址,最后返回这个临时变量
  • 返回值为char* 是为了支持链式表达式

9.25引用作为函数参数的的注意

  • 不能返回局部变量的引用
  • 不能返回函数内部new产生的引用
  • 传递引用给函数与传递指针给函数的效果一样,但是指针传递参数在函数中要分配空间的,而且在函数内使用指针变量名进行运算,程序的可读性会比较差
  • 使用引用传递进来的参数,在函数运行过程中是没有产生实参的副本,是直接对地址进行操作的,所以当形参传递的数据比较大的时候,引用传递参数效果比较好
posted @ 2020-09-26 09:49  Aspirant-GQ  阅读(33)  评论(0编辑  收藏  举报