C++ 知识点积累

本文探讨了C++编程中的常见误区与技巧,包括函数指针占用空间的问题、宏定义的使用、数组初始化、指针操作等核心概念,并解析了一些典型的代码行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-----------------------------------2018.9.3更新------------------------------------------------------------
第50条  函数指针不占类的空间             错误       跟其他指针一样占空间
 

class Father
{
public:
	int a;
//	int (*fun)(int);
};

int  main(int argc, char const *argv[])
{
	Father f;
	printf("%d\n", sizeof(f));
	int *a=NULL;
	printf("%d\n", sizeof(a));
	return 0;
}


-----------------------------------------------------------------------------------------------------------------

1 、宏可以来初始化数组的大小,#define size 10char str1[size],str2[size+2];

2、a=a+b=b++ ;错误:能赋值必须要求是一个可修改的左值;

3、if(-1){} 除0是false外,其余都是true。

4、

#include <stdio.h>
#include <stdlib.h>

void fun ( int *pl,int *p2,int *s )
{
    s = (int*) malloc(sizeof(int));
    *s = *pl + *(p2++ );
}

main( )

{
    int a [2] = {l,2},b [2] = {10,20},*s = a;
    fun (a,b,s); 
    printf ( "%d \n", *s);
}

谈谈我个人的理解:函数fun传递了两个参数,p1,p2,传指针:形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作,也就是说p1和p2是指针实参地址的指针,再看函数fun中的s,形参s本来是指向实参的地址,在函数体内形参s有指向新开辟的内存,因此没有没有用到实参的地址,所以打印出来是1,

5、. , .*,::,?:, sizeof 不能重载

6、整个数组只能初始化, 不能赋值

7、float(i),在cpp中可行,但是在C中不可行

8、#define宏定义中换行需添加续行符'\'

*9、因为seta函数参数为类A的指针,所以每当指针+1,指向的是下一个long类型数据,不是data[1].a,而是data[0].b的地址,所以前面4个数据被赋值为2,打印:22221111

class A{
    public:
        long a;

};

class B : public A {
    public:
        long b;
};

void seta(A* data, int idx) {
    data[idx].a = 2;
}

int main(int argc, char *argv[]) {
    B data[4];
    for(int i=0; i<4; ++i){
        data[i].a = 1;
        data[i].b = 1;
        seta(data, i);
    }
    for(int i=0; i<4; ++i){
         std::cout << data[i].a << data[i].b;
    }
    return 0;
}

 

10、实型常量又称实数或浮点数。在C语言中可以用两种形式表示一个实型常量:小数形式、整数形式

11、静态数据类型可以在类的外部进行初始化:静态成员变量必须在类外初始化,静态成员常量在类中初始化

12、c++关键字是int,char之类的,标识符使用户自定义的变量名,类名之类的

13、①.fork()函数会把它所在语句以后的语句复制到一个子进程里,单独执行。

       ②.如果printf函数最后没有"\n",则输出缓冲区不会被立即清空,而fork函数会把输出缓冲区里的内容也都复制到子进程里。

所以,父进程和子进程各输出2个Hello,共4个。

如果第一个printf("Hello");写成printf("Hello\n");,则只会输出3个Hello,父进程2个,子进程1个。

14、链接阶段可以发现被调用的函数未定义

编译:将预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后,产生相应的汇编代码文件。

int main() {
 printf("Hello");
 fork();
 rintf("Hello");
}

15、   y=   -   9  转换为16位的2进制数的方法:

          1.首先写出9的 16位的2进制数 :0000000000001001

          2.取反:1111111111110110

          3.加1:1111111111110111

16、int a[][4]={0,0},只有数组元素 a[0][0] 和 a[0][1] 可以得到初值 0

17、!2,得到0值.

18、  全局变量声明为static后,作用域非但没有扩大,反而缩小,只能在所在的文件内使用

          静态变量默认初始化为0.

          局部变量可以使用static, 形参不能

19、当派生类中含有对象成员时:

          构造函数的执行顺序:基类的构造函数 → 对象成员的构造函数 → 派生类的构造函数;

20、0xf (16进制)=  00001111

21、C++类的数据成员的存储类型不能是auto、register和extern

22、将char转换为int时关键看char是unsigned还是signed,如果是unsigned就执行0扩展,如果是signed就执行符号位扩展。跟int本身是signed还是unsiged无关。

23、联合在这样的情况下,还要注意是小端存储还是大端存储

union Test
 {
    char a[4];
    short b;
 };

24、undef 会重新define a, 但define 执行的时候,就一直替换到文件末尾,main中a都被替换了,进foo定义,遇到undef之后重新define成50. 如果foo放在前面,开始define替换,先遇到undef a替换成50,再从main到结尾全替换成50,

#define a 10
void foo(); 
main(){
   printf("%d..",a);
   foo();
   printf("%d",a);
}

void foo(){
   #undef a
   #define a 50
}

25、ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间; 从内存取出就是out,从磁盘进入内存就是in

对输入流操作:seekg()与tellg();对输出流操作:seekp()与tellp()

记忆方法:

26、   ! :代表逻辑取反,即:把非0的数值变为0,0变为1; 

          ~ :表示按位取反,即在数值的二进制表示方式上,将0变为1,将1变为0; 

27、strcpy会将结束符拷贝进去

28、%o与%x都是针对unsigned int

29、next_permutation(arr, arr+size);stl中的数组取值的下一个组合,当前序列没有下一个排列时返回false

30、不能声明为虚函数:

        1.普通函数(不能被覆盖) 

        2.友元函数(C++不支持友元函数继承)

        3.内联函数(编译期间展开,虚函数是在运行期间绑定)

        4.构造函数(没有对象不能使用构造函数,先有构造函数后有虚函数,虚函数是对对象的动作) 

        5.静态成员函数(只有一份大家共享) 

31、异或运算有点像线性代数 里面求秩的,相同的可以减掉,不同的不能减掉

32、 NEW是一个结构体类型

typedef  struct  ST
{
long a;
int  b;
char  c[2];
} NEW;

33、函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数

34、if ('a'<c<='z') printf ("Low”); 可以这么写,但是极有可能不是我们想要的答案

35、后置++优先级高于解引用(*)

36、    1,对于x86,栈的增长方向是从大地址到小地址

            2,对于函数调用,参数的入栈顺序是从右向左

            3,函数调用入栈顺序是  右边参数-->左边参数-->函数返回地址

37、使用virtual之后,是覆盖,没用virtual,就是隐藏,隐藏可以通过::访问的到

38、stl::sort() 是升序排列.

40、char *str=NULL;  printf("%s\n",str);  错误的操作,要是str

41、short占两个字节,65537的二进制表示为:1 00000000 00000001,short i = 65537时,发生了溢出,i取16bit,为1

42、通过函数来申请内存 

int* CreateArr(int n)
{
  int *a=new int[n];
  memset(a,0,n*sizeof(int));
  return a;
}

43、sizeof(1)等于4,sizeof() 是求字节数。

44、派生类继承基类中的公有成员和保护成员,同时也继承私有成员,但是不能访问私有成员,这些私有成员是占空间的

45、%n是统计之前输入字符长度

46、数组名是右值,int a[10],不能a++;

47、结构体内存对其原则:

       原则A:struct或者union的成员,第一个成员在偏移0的位置,之后的每个成员的起始位置必须是当前成员大小的整数倍;

      原则B:如果结构体A含有结构体成员B,那么B的起始位置必须是B中最大元素大小整数倍地址;

      原则C:结构体的总大小,必须是内部最大成员的整数倍;

48、virtual 函数是动态绑定,而缺省参数值却是静态绑定

49、

struct{ 
   char a[10];
   int b;
   short c[3];
}

                                                               

50、函数指针不占类的空间         ×

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值