开发者社区> 楚兴> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

宝典——C/C++程序设计

简介: 1 计算转化为二进制后包含1的数量 int fun(int n) { int count = 0; while(n) { count++; n &= n-1; } return count; } 2 判断是否为2N2^N !(x&(x-1)) 3 求均值
+关注继续查看

1 计算转化为二进制后包含1的数量

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

    return count;
}

2 判断是否为2N

!(x&(x-1))

3 求均值

int fun(int x, int y)
{
    return (x & y) + ((x ^ y) >> 1);
}

4 求最大值

int fun(int a, int b)
{
    return ((a+b) + abs(a-b))/2;
}

5 求三个数的中间数

inline int max(int a, int b) { return a >= b ? a : b; };
inline int min(int a,int b) { return a <= b ? a : b; };
inline int medium(int a, int b, int c)
{
    int t1 = max(a, b);
    int t2 = max(b, c);
    int t3 = max(a, c);
    return min(t1, min(t2, t3));
}

6 交换数值

void fun(int &a, int &b)
{
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
}

7 C++中调用被C编译器编译后的函数,为什么要加extern “C”?

C++语言支持函数重载,C语言不支持函数重载。
用于解决名字匹配问题。

8 头文件中的#ifndef/#define/#endif作用?

防止头文件被重复引用。

9 #define

需要注意括号的使用,例如

#define MIN(A,B) ((A) <= (B) ? (A) : (B))

10 const

int b = 500;
const int *a = &b; //情况1
int const *a = &b; //情况2
int* const a = &b; //情况3
const int* const a = &b //情况4

对于情况1和2,则const用来修饰指针所指向的变量,这种情况下不允许对内容进行更改:

*a = 600; //错误

但是有其他方法可以改变*a的值:

int b = 500, c = 600;
const int *a = &b;
a = &c; //方式1
a = 800; //方式2

对于情况1和2,可以先不进行初始化。虽然指针指向的内容是常量,但是指针本身不是常量。

const int *a; //正确

对于情况3,定义时必须同时初始化:

int b = 500, c = 600;
int* const a; //错误,没有初始化
int* cosnt a = &b; //正确,必须初始化
*a = 600; //正确,允许改值
cout<<a++<<endl; //错误

对于情况4,指针本身和指向的内容均为常量。

任何不修改成员数据的函数都应该声明为const函数。
const声明必须出现在函数的声明和函数的实现里,否则编译器会把它看成一个不同的函数。

11 const与#define相比有什么不同?

C++可以用const或者#define定义常量,但是前者比后者有更多的优点:

  • const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只能进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误。
  • 有些集成化的工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++常量中只使用常量而不适用宏常量,即const常量完全可以取代宏常量。

12 sizeof

char *ss1 = "0123456789"; //sizeof(ss1)=4,指针大小为定值4
char ss2[] = "0123456789"; //sizeof(ss2)=11
char ss3[100] = "0123456789"; //sizeof(ss3)=100
int ss4[100]; //sizeof(ss4)=400
char q1[]="abc"; //sizeof(q1)=4
char q2[]="a\n"; //sizeof(q2)=3,'\n'为一位
char* q3 = "a\n"; //sizeof(q3)=4
char *str1=(char*)malloc(100); //sizeof(str1)=4
void *str2=(void*)malloc(100); //sizeof(str2)=4

对于结构体,结构体的长度一定是最长的数据元素的整数倍。结构体对齐参数按默认的8字节对齐。

struct{
 short a1;
 short a2;
 short a3;
}A; //sizeof(A)=6

struct{
 long a1;
 short a2;
}B; //sizeof(B)=8

13 类的大小

空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。

  • 类内部的成员变量:

    • 普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。
    • static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。
  • 类内部的成员函数:

    • 普通函数:不占用内存。
    • 虚函数:要占用4个字节,用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的,和虚函数的个数是没有关系的

14 sizeof和strlen之间的区别

  • sizeof操作符的结果类型是size_t,它在头文件中的typedef为unsigned int类型。该类型保证能容纳所建立的最大对象的字节大小。
  • sizeof是运算符,strlen是函数。
  • sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以“\0”结尾的。sizeof还可以用函数做函数。
  • 数组做sizeof的参数不退化,传递给strlen就退化为指针。
  • 大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量的长度。这就是sizeof(x)可以用来定义数组维数的原因。
  • strlen的长度要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型占内存的大小。
  • sizeof后如果是类型必须加括号,如果是变量名可以不加括号,因为sizeof是个操作符而不是个函数。
  • 当使用了一个结构类型或变量时,sizeof返回实际的大小。当使用一静态的空间数组时,sizeof返回全部数据的尺寸。sizeof操作符不能返回被动态分配的数组或外部的数组的尺寸。
  • 数组作为参数传递给函数时传的是指针而不是数组,传递的是数组的首地址。

15 空类默认产生4个成员函数:默认构造函数、析构函数、拷贝构造函数和赋值函数。

16 类和结构

struct也可以有构造函数、析构函数,之间也可以继承。唯一的不同是struct里面默认的访问控制是public,class中默认的访问控制是private。

17 3种继承方式:(默认为私有继承)

继承方式 对派生类可见性 对派生类对象可见性 作为派生类对象时状态
public 公有和保护 公有的可见 保持原状态
protected 公有和保护 都不可见 保护
private 公有和保护 都不可见 私有

18 虚拟继承是多重继承中特有的概念,是为解决多重继承而出现的。(防止多次出现某个共同基类)

19 虚指针或虚函数指针是一个虚函数的实现细节。带有虚函数的类中的每一个对象都有一个虚指针指向该类的虚函数表。

20 防止被实例化:使用抽象类或者构造函数被声明为private。

21 运算符重载:全局函数(一元为一个参数,二元为两个参数),成员函数(一元没有参数,二元为两个参数)。

22 位置转换

printf("%f", 5);   // 0.000000
printf("%d", 5.01);  //一个大数

22 类型转换操作符

  • static_cast 在编译时使用类型信息执行转换,在转换执行时进行必要的检测,操作数相对是安全的。
  • const_cast 最普通的用途就是转换掉对象的const属性
  • reinterpret_cast 复制要转换对象的比特位到目标(是为了映射到完全不同的类型,双刃剑,谨慎使用)
  • dynamic_cast 运行时检查,用于在继承体系中进行安全的向下转换(基类指针/引用到派生类指针/引用的转换),如果源和目标类型没有继承关系,编译器会报错。必须在代码里判断返回值是否为NULL来确认转换是否成功。是四个转化中唯一的RTTI操作符,提供运行时类型检查。(当基类指针指向或引用派生类对象时,转换成功;否则得到NULL)

23 求值

unsigned int i = 0; i -= 1; // i=65535=pow(2,8) - 1;

24 设置和清楚某个位

#define BIT3 (0x1 << 3)
static int a;
void set_bit3()
{
    a |= BIT3;
}
void clear_bit3()
{
    a ^= BIT3;
}

25 输出结果为3c,即15*4=60。

int *pa = NULL;
int *pb = pa + 15;
printf("%x", pb);
return 0;

26 volatile

语法与const一样,但是volatile的意思是在编译器认识的范围外,这个数据可以被改变。(该变量可能会被意想不到地改变)

27 设置绝对地址为0x67a9的整型变量的值为0xaa66。

int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa66;

28 补码

  • 10的二进制补码为-(2^8 - |-10|) = - 246 = 11110110;
  • 10的三进制4位数补码为3^4 - |-10|=71=2111;

29 关键字static的作用

  • 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存植被分配一次,因此其值在下次调用时扔维持上次的值。
  • 在模块内的static全局变量可以被模块内所有函数访问,但不能被模块外其他函数访问。
  • 在模块内的static函数只可被模块内的其他函数使用,这个函数的使用范围被限制在声明它的模块内。
  • 在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。
  • 在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【C语言程序设计】第一章:程序设计与C语言
《C语言程序设计》第一章:程序设计与C语言精炼
10 0
C/C++【程序环境和预处理】
C/C++【程序环境和预处理】
9 0
程序员的bug修复宝典
程序员的bug修复宝典
74 0
程序设计中的设计
通常我们所谓的程序设计,其实包含编码与设计两个部分,编码行为一般为人们所熟知,被称为coding,然而设计过程却容易为大家所忽视。
762 0
未来WEB程序员
作为一名程序员,如果你想在这个领域内继续向前进步或者在当前的经济形势下保持不被炒鱿鱼,那么你就决不应当自满自足,你需要继续学习。近日,著名IT评论员Justin James在他的博客中列出了未来五年程序员应当具备的十项技能,如果照此实践,你未来的工作前景一定一片光明。
945 0
C/C++/Java 程序计时功能函数
编写程序肯定要使用计时功能,来判断程序的执行时间。今天Google了一下,自己就梳理总结一下: (1)C/C++程序计时   C/C++中使用的计时函数是clock()。   C语言中的头文件对应是#include,C++中对应的头文件为#include。
764 0
C++程序设计-第13周 继承与派生(二)
课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565 【目的】 1. 进一步掌握类的派生与继承的概念、应用方法2. 掌握继承方式对成员访问权限的影响3. 掌握虚基类的用法 第三部分 实践项目【项目1】理解基类中成员的访问限定符和派生类的继承方式由下面派生类StudentB对基类StudentA的继承…… #includ
908 0
Java中C/S通讯程序设计一例
  一、 客户端图形界面   本例中客户端的图形界面用Swing实现,服务器端不使用图形界面 public class javaClient extends JFrame implements ActionListener//以JFrame为基类,实现ActionListener接口 { JButton sendButton; //"发送"按钮 JTextField inputField; /
746 0
+关注
楚兴
达则兼济天下,穷则独善其身。
344
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载