c语言刷题笔记

多少位编译器,表示一个指针占据多少位

16位 int 2个字节

2^10 =1024

转义字符

c语言

0、符号优先级

结合方向,+=、=结合方向是从右到左
a+=1,等价于a=a+1,先计算出右边a+1的值,然后赋给左边,这就叫做从右向左结合

1、print函数

printf("s[]=%6.9s\n", s);  表示输出的时候不少于6位,但不超过9位字符

2、逗号表达式

2、(a = 5, b = 2, a > b ? a++ : b++, a + b)     逗号表达式计算的是最后一个逗号的结果

sizeof 与strlen

sizeof 是计算字节包括字符串的\0,strlen不包括

3、printf(输出)与scanf(输入)的区别

 printf("%3.2f\n", i);//3是输出宽度,2是保留的小数点数(这就是精度)

 scanf  只能控制宽度不能控制精度
 scanf("%d%d", &i, &j);
 scanf("%d", &i);
 输入两个要区分两个输入,1上面限制条件 2、输入到时候两个数字之间加上ent 或者空格,输完使用end结束

4、数组

数组的长度可以是变量

5、c++相关字节大小

空类的字节是1个字节、

函数的字节是一个

虚函数存在的话是4(32位,64位是8字节)
 sizeof(void*)4字节 

sizeof(void)错误或者1字节

static 不属于类成员,是类对象共享  0 字节

virtual  4字节(32位)

6、二维数组

对于二维数组啊a[3][4],a[0]和a都表示首元素地址,

a[0]是a[0][0]的地址,

a[1]表示第二行首元素的地址、a[2]表示第三行手元素地址,a[1] +1,表示第二行开始跳过一个元素的地址

a:第0行的地址;a+i:第i行的地址       *(a+i):第i行0列地址  *(a+i)+j   表示&a[i][j]

&a表示数组的地址,&a +1 表示跳过整个二维数组,此处跳过12个int的大小

7、指针+变量的地址计算

设有指针变量为 double *p,则在32位机器上p+1是将指针p的指向向后移动8个字节(增加的是double大小)

8、参数传递的时候改变值

改变非指针的值,需要一重指针,改变一重指针的值,需要传入二级指针

9、异或

 ans ^= i % 3这是异或 1 参与运算的两个值,如果两个相应位相同,则结果为0,否则为1。即:0^0=0, 1^0=1, 0^1=1, 1^1=0

10、字符常量与字符串改变,常量指针

8、字符常量可以改变,可以参加数值运算,参加整数运算时根据ASCll码转换成int值运算

  字符串常量不能修改,要改变字符串,需要使用字符串形式而不是使用字符串常量

const  char *str_const = "Hello, World!";字符串常量,指针是一个指针常量不能改变指针指向

后面str_const [0] =1  错误,不能使用常量指针赋值

const char *str = "Hello";
str[0] = 'h'; // 非法:尝试修改字符串常量的内容

// 字符串 char str[] = "Hello, World!";   

指针常量:指向地址不能改变,数组名: char *s =string   s指向字符串首地址不能改变

字符串指针与字符数组

char* s = "string"
const char* p="abcdef"
字符串存放在静态区,字符串指针是一个常量指针,不能修改其指向内容


char chr[]="abc";
char chr1[]={"abc"};
char chr2[]={'a','b','c','\0'};


,数组名本身是常量指针(数组名是一个常量不能改变),arr[0] = 'S';  // 将第一个字符改为大写 'S'
合法

11、ASCll码

9、ascll码值

a:97 b:98

A:65

12、

10、输出字符地址或是字符值

13、执行与编译

内存分配是在程序执行的过程这个实现,编译只是对代码进行翻译

14、NULL 地址

空地址指的是地址为0的空间

15、%x格式

13、printf ("x = %x", i); 输出的是16进制

16、print函数

14、//用printf输出的话,
//如果是用 %d 的话,符号这个["",]后面要写 值 ;=>一个整数=>一个就是值
//如果是用 %c 的话,符号这个["",]后面要写值;=>一个字符整数=>一个就是值
//如果是用 %s 的话,符号这个["",]后面要写地址=>一串字符串=>一串就是地址((地址,地址的值)

printf ("x = %x", i); 输出的是16进制
count 输入地址的话,也会打印出值

17、strcpy函数与strcat、memcpy

字符拼接

char *strcat(char *dest, const char *src);
 

.strcat(p,r)表示p字符串后面拼接r字符串。
 

strcat    将两个值拷贝


字符覆盖

char * strcpy ( char * destination, const char * source );
 strcpy(q,b) 将b内容拷贝给q,地址拷贝,只能复制字符串

    strcpy在使用中赋值是将所有的字符串均复制过去,strcpy(p+2,q),p+2表示p中字符保留2个数。

void *memcpy(void *dest, const void *src, size_t n);
 

memcpy 可以复制任何的内容,字符数组、整型、结构体等
      memcpy(a+2,b,sizeof(b))  表示b中的字符从a数组第三个开始覆盖

      memcpy(a,b,sizeof(b))  表示b中的字符从a数组第一个开始覆盖

18、含有结构体的成员变量的结构体对齐

 

 注意A中的最大结构体是内部的int变量,而不是整个16字节结构体,我们看的是内置类型

题目说的几字节对齐说的是

19、关于fopen

fopen()文件顺利打开后,返回指向该流的文件指针,如果文件打开失败,则返回NULL,并将错误代码存储在errno中。 fclose()成功关闭可返回0,错误返回EOF并把错误存储在errno中

20、static

全局变量在所有源文件升效

静态全局变量只能在当前源文件生效

静态函数变量只能在当前源文件生效

static  int  定义只执行一次

21、a[]与a的写法

19、关于数组的形参与实参

形参一般写a[],相当于指针,数组里面的参数没有意义,可以不写

实参一般是a,相当于指针

20、数组名是一个地址常量

22、自动推导类型

decltype和auto都可以用来推断类型,但是二者有几处明显的差异:

23、函数指针数组

int (*s[10])(int) 

右边的int是代表了返回值类型

(*s[i])表示这是一个指针数组

24、c++的一些知识

C++中没有限定private、public、protected的书写次序数据成员类型不可以是register,

25、对于一个表达式来说,只对决定整个表达式值所需的最少数组的子表达式进行运算

z=(x||(y-=x)”   因为x已经决定了最终的结果,所以右边的不会执行

26、函数定义的参数格式

double fun(int, int),只要写数据类型就可以,后面的变量可有可无

27、strlen

strlen() 查找到“\0”就结束

strlen("\n\0") = 1

\a  、\\ 、\0这种算一个字符

28、c++中可以使用函数嵌套调用但是不能再定义的时候嵌套

29、静态成员函数

静态成员函数没有this指针,需要通过类参数访问成员对象

30、字符的赋值

需要加上'q',,直接加上q会转成ASCLL值进行计算

31、地址指向NULL

指针本身本来就不是存储单元,只是指向存储单元的地址,地址为空,只是没有指向有意义的内存,指向了0x00000000~0x0000ffff这段无意义的内存
这个时候不能直直接对这个区域赋值,要先将指针指向有意义的地方,才能通过指针给空间赋值

32、switch语句

defalut是没有任何case匹配·的是时候才能去执行的,

要是没遇到break,就会向下执行到break

switch()括号中的是整形也就是int,字符型

switch (expression) {  
    case constant1:  
        // 当 expression 等于 constant1 时执行的代码  
        break;  
    case constant2:  
        // 当 expression 等于 constant2 时执行的代码  
        break;  
    // ...  
    case constantN:  
        // 当 expression 等于 constantN 时执行的代码  
        break;  
    default:  
        // 当 expression 不等于任何 constant 时执行的代码  
}

33、字符常量

1、‘a’ 单个字符

2、转义字符  ‘\032’

34、数组名与指针的长度(64位操作系统)

str[] = "Hello"   sizeof(str)  6

指针长度 8

void func(char str_arg[100]){

     cout << sizeof(str_arg) << endl;

这里的长度是形参长度是形参的长度是指针,长度是8

35、数组名是常量不可以修改

36、空定义

#define S345:

37、

将字符串赋值给指针的意思是指针指向这个字符串

w < x ? w : y < z ? y : z    ==   w<x?w:(y<z?y:z)

*++c = *(++c)

38、链表

节点想要与下一个节点相连接,需要将自己的地址存放到下一个节点的空间中

指针是一个地址,指针指向地址代表的空间

39、联合体unio

在任意时刻,union中只能有一个数据成员可以有值。当给联合中某个成员赋值之后,该联合中的其它成员就变成未定义状态了;

联合体是共有一块物理内存,不是共有一个值

40、指针移动的使用友\n

41、内联函数

1、内联函数不能太复杂,不然编译器就会视为普通函数

2、内联函数不能声明可能抛出的异常

42、优先级问题

== 优先级大于 =

三目运算符是从后面开始

43、宏定义函数

#define MOVE(a,b) \

{ \

   int  a_target = (a) & 0xFFF;\

   int  b_target = (b) & ~(0xFFF << 3);\

   (b) = (b_target) | (a_target << 3);\

}

44、位运算的应用

清零与保存我们想要的位

保留我们想要的位     a & 1    = a

清零我们想要的位    a & 0   =  0

45、优先级

++的优先级比*高

46、getchar 函数

getchar():从键盘中获取一个字符
不管你输入字符串有多长,每次只能获取一个字符型变量;\n 也会被获得

47 /n  与\r

\r   回车 本行开头

\n   换行

48、c语言文件打开

rr(read):读
w(write):写
a(append):追加
b(banary):二进制文件
+:读和写

49、strcpy与strcat

strcpy 将/0一起赋给

strcat  插在后面

50、c语言优先级

51、不能重载的运算符

类属关系运算符"."

成员指针运算符".*"作用域运算符"::"sizeof运算符三目运算符"?:

52、scanf键盘输入问题

空格 ENT不会读取

53、文件读取

54、memcpy与strcpy拷贝函数,strcat

strncpy(str1,str2,2);作用是将str2中最前面2个字符复制到str1中,取代str1中原有的最前面2个字符。

// 字符串拼接


int src[] = {1, 2, 3, 4, 5};

int dest[5]; memcpy(dest, src, sizeof(src))

dest[]  =  {1,2,3,4,5}

strcat(dest, src); // 将src追加到dest后面

55、*p++与*++p

一般来说单目运算符都是从右往左的,但是当++在变量左边的时候,++变成最低优先级

56、合法的标识符、字符常量、字符串常量

1、合法标识符

  • 标识符只能由字母,数字和下划线组成。
  • 标识符不能以数字开头。

2、合发常量:
十进制 :10
八进制 :017(以0开头,不能出现8,9)
十六进制:0xA1(以0x开头

3、合法字符、字符串常量

57、语言中的指针和p, p+1, *(p+1), *P+1,  &p[0] 的含义

p 指针

p +1  这将导致 p 指向下一个相邻的内存位置

*(p+1)   这是一个解引用操作,它将指针 p 增加一个单位后的地址处的值取出
*p +1     首先解引用指针 p,然后将结果加一

&p[0]  这是取地址操作,它返回指针 p 指向的内存位置的地址。

58、type 重新命名符号类型,define

后面加上_t 表示都是重新定义的

typedef signed char             int8_t;
typedef short int               int16_t;
typedef int                     int32_t;

typedef unsigned char           uint8_t;
typedef unsigned short int      uint16_t;
typedef unsigned int            uint32_t;

typedef struct NUM
{
     int a;
     int b;
}DATA,*PTRDATA;

 DATA等同于struct NUM

*PTRDATA 等同于指向struct  Num的指针

59、#if...#endif的用法总结参考

#ifdef   标识符
     
程序段1
#else
  
程序段2


#endif

 如果标识符被定义了,执行程序1,否则执行程序段2

  1. `#if`格式:
    • 当`#if`后面的表达式为真时,编译`#if`与`#elif`之间的代码段;
    • 如果表达式不成立,则编译`#elif`与`#else`之间的代码段;
    • 如果所有条件都不成立,则编译`#else`与`#endif`之间的代码段。
    • `#else`和`#endif`部分是可选的。3
  1. `#ifdef`格式:

    • 如果宏标识符已经被定义,则编译`#ifdef`与`#else`之间的代码段;
    • 如果宏未被定义,则编译`#else`与`#endif`之间的代码段。
  2. `#ifndef`格式:

    • 如果宏标识符未被定义,则编译`#ifndef`与`#else`之间的代码段;
    • 如果宏已经被定义,则编译`#else`与`#endif`之间的代码段。

例如,如果宏`MAX`被定义,则代码会在`#elif`条件成立时被编译。条件编译结束后,通常需要在最后添加`#endif`以确保语法正确

#if 表达式

    程序段1
#else

    程序段2

#endif

    

如果表达式为真,执行程序段1,否则程序段2

define

  1. #定义 标识符 内容

  2. #define name stuff

  3. #define MAX 100

MAX就表示100

由于预先对标识符进行了定义,在程序的预处理阶段, 编译器会将所有定义的标识符替换成相应的内容并生成 .i 文件

60、c语言中的浮点型

1.2e2  表示 1.2×10的2次方   注意e后面不能为小数,e前面只能是10进制

61、

(m=a>b)&&(n=c>d)  从左边开始,只要左边一旦为0,则直接结束,右边不需要进行

a<b?a:c<d?c:d  三目运算符,从后面开始a<b?a:(c<d?c:d)  ,赋值运算符、也是一样的运算顺序

62 指针与数组名

数组名表示的是数组的首地址

sizeof(数组名) 表示数组的字节大小

si则of(指针) 表示指针的大小

63、想要通过改变形参的值达到改变实参

改变变量的值,要用指针。
改变指针的值,要用指针的指针

64、scanf输入格式

%d%d     输入的时候使用空格、tab ent区分

%d,%d    摄入的时候使用,分开

65、++ 与*运算顺序

记住从后往前运行就可以  ++*a、*a++

66、指针常量与常量指针

指针常量——指针类型的常量  指针指向不能变 .数组名是一个指针常量,指针里面存放的是首元素地址

常量指针——指向“常量的指针     指针指向1内容不能变

int const * p; //常量指针
const int * p; //常量指针
int * const p; //指针常量

常量指针=常量(const)+指针(int *a)
    //注意:可改变对象,不可改变大小

    //指针常量=指针(int *)+常量(const a2)
    //注意:不可改变对象,可改变大小

67、数组指针、指针数组

int *p1[5]; 指针数组
int (*p2)[5]; 数组指针

int *p2[5]  

首先,对于语句“int*p1[5]”,因为“[]”的优先级要比“*”要高,所以 p1 先与“[]”结合,构成一个数组的定义,数组名为 p1,而“int*”修饰的是数组的内容,即数组的每个元素。也就是说,该数组包含 5 个指向 int 类型数据的指针,如图 1 所示,因此,它是一个指针数组

于语句“int(*p2)[5]”,“()”的优先级比“[]”高,“*”号和 p2 构成一个指针的定义,指针变量名为 p2,而 int 修饰的是数组的内容,即数组的每个元素。也就是说,p2 是一个指针,它指向一个包含 5 个 int 类型数据的数组,如图 2 所示。很显然,它是一个数组指针,数组在这里并没有名字,是个匿名数组

68、new 与malloc

int *p=new int(6);   创建一个空间存放6

int* ptr=new int[100];//分配100个int的内存空间


char *point = (char *) malloc(100);   创建一个空间,大小为100


/p = (int *) malloc(10 * sizeof(int))分配100个int的内存空间

用free之前需要检查需要释放的指针是否为空

delete[]    mew[]匹配

69、if  elseif   ,if   

这个后面可以选择接一个else,表示上面都没有满足执行这个,也可以不接,表示什么都不执行

70、不同数据类型进行运行

其实基本原则就是尽可能保存数据,int  > float >double

C语言经典知识

指针、引用、值传递

彻底搞定c和指针-优快云博客

数组指针、指针数组、字符指针

需要明确一个优先级顺序:()>[]>*

 数组指针   是一个指针,指向一个数组的指针 

 (*p)[n]:根据优先级,先看括号内,则p是一个指针,这个指针指向一个一维数组,数组长度为n

  指针数组  是一个数组,一个存放指针的数组

 *p[n]:根据优先级,先看[],则p是一个数组,再结合*,这个数组的元素是指针类型,共n个元素,这是“指针的数组”,即指针数组

字符指针,存放字符串首元素地址,不能通过指针改变常量字符串

数组指针

c语言简单代码

位运算·

1、计算出一个数中二进制中1的个数

1、与 1想与 判断最后一位是不是1

2、将这个数左移

2、使用联合体判断大小端

typedef union {
	int a;
	char b;
}UN;

int main(){
	
	UN u;
	u.a = 1;
	if(u.b == 1) printf("小端存储\n");
	else printf("大端存储\n");
	return 0;
	
}

c++

1、子类继承 属性变化

private   在子类任何继承下都是private

2、友元函数

一个类的私有数据成员通常只能由类的函数成员来访问,而友元函数可以访问类的私有数据成员,也能访问其保护成员

3、if  else的配对

与它上面最近的未与else配对 的if

4、构造函数

构造函数可以重载但是不能是虚函数

构造函数执行顺序是先父类后子类

5、lambda 表达式

auto f  =  [] (int a,int b) -> int {return  a+b}  //定义一个匿名函数


[]   捕获列表为空


调用匿名函数 cout << f(1,2) << endl;    


6、成员变量初始化

在构造函数中需要初始化列表初始化的有如下三种情况

1.带有const修饰的类成员 ,如const int a ;

2.引用成员数据,如 int& p;

3.带有引用的类变量,如: class A { private: int &a; }; class B{ private: A c; }

这里的c需要用初始化列表进行初始化


作者:风走了,雨停了
链接:牛客网公司真题_免费模拟题库_企业面试|笔试真题
来源:牛客网

7、fork复制问题

虚拟地址一样,但是对应的物理地址不同,c语言都是虚拟地址

8、不能重载的运算符

类属关系运算符"."

成员指针运算符".*"作用域运算符"::"sizeof运算符三目运算符"?:

9、static成员变量

静态成员是类共享,静态只能访问静态,普通可以访问静态

静态成员函数没有this指针,需要通过类参数访问成员对象

静态成员必须在类外初始化

静态成员

10、构造函数

1、无参构造函数

2、有参构造

3、有默认参数的构造函数

11、初始化列表

12、空指针

p=NULL;和p=0;或p='\0';是等价的

13、运算符重载

operator+

++

牛客面经

1

linux设备树解析是什么时候

构建内核的时候,将设备树源文件dtbs编程成二进制dtb文件

2

linux多线程:在一个多线程访问某个外设驱动时,怎么防止其他线程访问

原子、加锁、信号量

内联函数的缺点是什么

优点:函数调用的开销减少了

缺点:

增加了代码的体积,加多了编译时间*(这个也不一定,函数调用变少编译时间变少,但是内联函数增加了很多代码编译时间也会变长),代码重复

多线程下怎么喂狗

这个涉及到多个线程对共享资源的访问,涉及到了线程的同步需要加锁

3

gdp运行在什么态, 调试的使用,step、next,finsh的区别

step 单步调试进入函数,next 不进入函数

finish 跳出函数

linux 内核启动流程

第一阶段:执行initrd文件系统中的某个文件,完成加载驱动模块等任务

第二阶段:执行根文件系统中的/sbin/init进程

uboot启动流程

内核如何传递启动参数

在uboot引导阶段,对参数bootargs参数进行设置

设备树DTS、DTB

驱动开发字符设备驱动开发流程

module_init 函数底层原理

module_init()是一个宏定义,这个函数在模块加载的时候被调用。这个宏通过将初始化函数的地址注册到内核数据结构中,在模块加载时候由内核调用这些初始化函数、这使得内核可以在模块加载时执行所需的初始化任务,为模块提供正确的环境的资源

C语言的inline 和define函数区别

#define只是简单的替换,没有函数调用的开销,但可能导致代码膨胀,没有检查类型,

inline 函数是真正的函数,有函数调用的优点,需要编译器支持和遵循,

c++类和c语言函数调用有什么区别

c++和c语言函数代码存储有什么区别

static 关键字、voliate关键字

函数调用的时候参数如何传递,如果参数很多怎么传递

参数很多的时候,将参数打包成结构体,进行传递

linux中断中的下半部软中断与tasklet的区别

软中断与tasklet都是下半部中断

软中断使用全局软中断向量,软中断中可以同时执行多个软中断函数同时运行,但是他们在同一个上下文中按顺序执行,可能会导致其他软中断延时处理

tasklet :每个cpu都有自己的tasklet队列,可以并行处理

大小端

小端模式:低位数据放在低地址,高位数据存放在高位数据

怎么判断是小端还是大端

使用一个共有体 

结构体对齐

1、起始地址是数据大小的整数倍

2、整个结构体大小要是最大成员类型的整数倍

讲下GIc中断的状态

中断控制器GIC:控制器对中断源进行管理,当对应的中断源有效的时候,gic根据该中断源的管理,决定是否将该中断信号发送给cpu,如果多个中断源有效,那么gic还会选择中断优先级高的发送给cpu,待cpu中断处理之后,就会访问gic表示已经处理了,gic会取消中断源

gic控制器的四种状态

inactivate:中断处于无效状态

pending:中断处于有效状态,但是cpu没有响应该中断

activate:cpu在响应中断

activate and pending:cpu在响应中断,但是该中断源又有发送中断过来

MMU,多级页表,页表存储位置

进程切换过程

1、上下文保存:当操作系统决定切换到另一个进程时,首先要保存当前运行进程的上下文信息,包括程序计数器(pc)、寄存器内容、进程状态以及其他数据

2、切换到内核模型:

3、选择新进程:操作系统从就绪列表中选择一个新的进程

4、执行结束之后,回到之前的进程恢复上下文,继续执行

进程间通信

互斥锁与自旋转区别与应用场景

互斥锁:阻塞的会睡眠,自旋锁不会睡眠

中断中使用自旋锁,临界保护时间长的使用互斥锁

socket套接字

6

spi协议有几根线,如果缺少了一根会怎么样

GPIO模式

 shell 脚本中#bin/bash 什么意思

并告诉系统要使用哪个解释器来执行这个脚本,bin/bash是解释器的路径

7

tcp建立连接之后,如果没有收到服务端的消息,客户端会做什么

超时重传,要是时间过长35就会使用超时重传断开连接

建立tcp连接的几种状态

11种状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值