C语言面经

25.类型相同的两个指针之间不能进行的运算

指针主要用于存储变量的内存地址。对于同类型的指针变量之间,有一些规则:

        a. 小于运算(<):指针间的小于比较是基于它们指向的内存地址。地址较小的指针在小于比较中被认为是较小的。

        b. 赋值运算(=):指针可以赋值给另一个相同类型的指针。这样做会使得两个指针指向同一个地址。

        c. 减法运算(-):两个指向同一数组的指针进行减法运算会得到一个整数,表示它们之间的元素差距。这里的减法结果不是一个地址,而是一个表示距离的整数值。

        d. 加法运算(+):两个指针之间不能进行加法运算。指针加法没有定义,因为这不会产生有意义的结果,也可能导致程序崩溃或安全问题。

26、如何在C语言中设置、清除、切换和单位检查单个位?
  • 设置特定位:将一个数的特定位设置为1,可以使用“按位或”(|)运算符。具体语法:
number |= (1UL << nthPosition);

        这里,其中UL代表Unsigned Long1UL表示一个无符号数据1。将这个数向左移动nthPosition位,将1放置在我们想要设置的位上,然后使用“按位或”(|)运算符将其与原始数进行组合。任何数与1进行“按位或”运算的结果都是1。

  • 清除特定位:要清除一个数的特定位,即设置为0,使用“按位与”(&)运算符与一个特殊的位掩码进行运算:
number &= ~(1UL << nthPosition);

1左移nthPosition位,然后使用按位非(~)操作创建一个在该位为0的掩码,其他位为1。与原数进行“与”运算后,该位被清零

  • 检查特定位:要检查一个数的特定位是否设置为1,使用“按位与”(&)运算符:
bit = number & (1UL << nthPosition);

        将1左移至目标位产生掩码,然后与原数进行“与”运算。如果目标位为1,则结果非零;如果为0,则结果为零。

  • 切换特定位:若要切换整数的特定位的值,使用“按位异或”(^)运算符:
number ^= (1UL << nthPosition);

        将1左移nthPosition位产生掩码,然后与原数进行“异或”运算。这将切换目标位的值,因为“异或”运算符会将相同的位转为0,不同的位转为1。

28.C语言动态内存分配的函数

        "C语言提供了几个强大的函数来进行动态内存分配,使得程序员可以在程序执行期间根据需要分配或释放内存。这些函数是 malloc(), calloc(), realloc(), 和 free()

  1. malloc() 函数用于分配指定大小的内存块。它不会初始化内存,所以分配的内存中可能包含垃圾值。如果成功,它返回指向分配的内存的指针;如果失败,则返回空指针。其语法是 ptr = (cast-type*)malloc(byte-size),这里 ptr 是指向分配的内存的指针,byte-size 是要分配的字节数。
  2. calloc() 函数malloc() 类似,但有两个主要区别:它同时分配内存并将其初始化为零。其语法是 ptr = (cast-type*)calloc(n, element-size),其中 n 是要分配的元素数量,而 element-size 是每个元素的大小。这对于初始化数组特别有用。
  3. realloc() 函数用于重新调整之前分配的内存块的大小。这是在动态内存管理中非常有用的功能,允许增加或减少已分配内存的大小。如果在原有内存块附近没有足够的空间进行扩展,它会分配一个新的内存块,复制旧数据到新位置,并释放旧内存块。其语法是 ptr = realloc(ptr, newsize)newsize 是新的大小。
  4. free() 函数用于释放之前通过 malloc()calloc()realloc() 分配的内存块。一旦内存被释放,原有指针所指向的内存区域就不再有效。释放未使用的内存是避免内存泄漏的重要步骤。其语法非常简单:free(ptr)
29.const

        在C语言中,const关键字用于声明一个常量,即在程序执行过程中其值不能被修改的变量。const修饰的变量通常存储在只读存储段,比如只读数据段(.rodata)或文本段(.text),这些内存区域在程序运行时是不允许写入的。

  1. const修饰的变量是只读的。如果尝试修改一个const变量的值,编译器将报错,因为这会违反变量的只读属性。
  2. const修饰数组时,数组中的所有元素都是不可修改的。如果尝试修改数组中的一个const元素,将会引起编译错误。
  3. const修饰指针有不同的含义,这取决于const关键字放置的位置。例如:
  • const int *p意味着指针指向的int值不可以修改,但指针本身可以修改指向其他的int变量。
  • int *const p意味着指针p是一个常量,即p不能指向别的地址,但是p指向的值可以修改。
  • const int *const p意味着指针p不能修改指向,同时p指向的int值也不能被修改。                  当一个const变量被初始化后,它的值就固定了,不能再被修改。这意味着const变量通常需要在声明的同时初始化。
34.原码反码补码的计算

        首先说原码,最前面是符号位,0表示正数,1表示负数,其他的就是普通的二进制数。然后是反码是数值存储的一种,它的正数与原码相同。但负数呢,除了最高位还是1以外,其他位上的1变成0,0变成1。多用于系统环境设置,如在Linux这类系统里目录和文件的默认权限的设置umask,就是使用反码原理。最后来说补码,计算机一律用它来存数和算数。因为用补码,正数负数加减法就能用一套规则来解决,简化了很多。计算补码,正数不用变,负数就把反码加个1就是了。所以,如果要我来计算一个负数的补码,我会先写出它的原码,然后变成反码,最后再给反码加1”

36.逗号表达式

        运算过程是从右向左逐个计算,逗号表达式的值为最后一个表达式的值,逗号运算符的优先级在所有运算符中最低。

40. 如何解决头文件中的重复包含问题?

        为了解决头文件重复包含的问题,通常有两种方法来避免同一个头文件被包含(include)多次导致的编译错误和性能问题:

  1. Include Guards: 这是一种传统的预处理器技巧,通过定义特定的宏来防止头文件的内容被多次包含。典型的做法是使用#ifndef#define,和#endif指令来定义一个只有当特定宏未定义时才允许包含头文件内容的条件。
cCopy code
// A.h文件的示例
#ifndef A_H_
#define A_H_
// 头文件内容
#endif // A_H_
  1. #pragma once: 这是一种现代和非标准的预处理器指令,告诉编译器只包含头文件一次。它简洁且通常可以跨多个编译器工作,但不是所有的编译器都支持它。
cCopy code
// A.h文件的示例
#pragma once
// 头文件内容

        在多数情况下,#pragma once提供了一种简单而清晰的方法来防止头文件的重复包含。但在跨平台的项目中或为了确保最佳的兼容性,传统的Include Guards方法是更可靠的选择。

41. 为什么程序的指令和程序数据分开

        程序被加载到内存中之后,可以将数据和代码分别映射到两个内存区域。由于数据区域对进程来说是可读可写的,而指令区域对程序来讲是只读的,所以分区之后呢,可以将程序指令区域和数据区域分别设置成只读或可读可写。这样可以防止程序的指令有意或者无意被修改当系统中运行着多个同样的程序的时候,这些程序执行的指令都是一样的,所以只需要内存中保存一份程序的指令就可以了,只是每一个程序运行中数据不一样而已,这样可以节省大量的内存。

44.C 从代码到可执行二进制文件的过程

一个C程序从源码到执行文件,有四个过程,预编译、编译、汇编、链接。

预编译:这个过程主要的处理操作如下:

  • 1)将所有的 #define 删除,并且展开所有的宏定义
  • 2)处理所有的条件预编译指令,如 #if、#ifdef
  • 3)处理 #include 预编译指令,将被包含的文件插入到该预编译指令的位置。
  • 4)过滤所有的注释(注释被编译器理解成空格)
  • 5)添加行号和文件名标识。

编译:这个过程主要的处理操作如下:

  • 1)词法分析:将源代码的字符序列分割成一系列的记号
  • 2)语法分析:对记号进行语法分析,产生语法树。
  • 3)语义分析:判断表达式是否有意义,
  • 4)代码优化:源代码级别的一个优化过程。
  • 5)目标代码生成:由代码生成器将中间代码转换成目标机器代码,生成一系列的代码序列汇编语言表示。
  • 6)目标代码优化:目标代码优化器对上述的目标机器代码进行优化:寻找合适的寻址方式、使用位移来替代乘法运算、删除多余的指令等。

汇编:这个过程主要是将汇编代码转变成机器可以执行的指令,

链接:将不同的源文件产生的目标文件进行链接,从而形成一个可以执行的程序。

45.为什么要生成汇编,而不是直接从源文件编译成机器指令?
  • 1)汇编语言作为机器指令的助记符,调试以及优化起来都会比较方便;
  • 2)汇编到机器指令的过程是由硬件完成的,是一个自动过程,让硬件来完成效率较高;
  • 3)如果要将源文件直接转换成机器指令,那么编译器编写者就必须要非常数量机器码,这是一个比较困难且低效的过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/3247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Unity】shader中参数传递

1、前言 unity shader这个对于我来说是真的有点难&#xff0c;今天这篇文章主要还是总结下最近学习到的一些东西&#xff0c;避免过段时间忘记了&#xff0c;可能有不对&#xff0c;欢迎留言纠正。 2、参数传递的两种方式 2.1 语义传递 语义传递这个相对来说是简单的 shad…

Csharp_pta2_2

7-7 C# 1.12 区间找数 编写控制台应用程序&#xff0c;根据用户输入的a、b、c、d值&#xff08;均为正整数且a不大于b&#xff09;&#xff0c;输出在[a, b]区间中能被c整除&#xff0c;但是不能被d整除的数。 输入格式: 用户在一行中输入四个正整数&#xff0c;分别对应a、…

数组模拟几种基本的数据结构

文章目录 数组模拟单链表数组模拟双链表数组实现栈数组模拟队列总结 数组模拟单链表 首先类比结构体存储单链表&#xff0c;我们需要一个存放下一个节点下标的数组&#xff0c;还需要一个存储当前节点的值的数组&#xff0c;其次就是一个int类型的索引&#xff0c;这个索引指向…

Python 实现视频去抖动技术

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 视频去抖动是视频处理中的一项重要技术&#xff0c;它可以有效地减少视频中由于相机震动或手…

springSecurity简单直接说明

引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombo…

MyBatis处理SQL中的特殊字符

方式一&#xff1a;转义字符 如下案例&#xff1a; < 表示小于的转义字符 <!-- 在Mapper XML文件中定义SQL语句 --> <select id"selectById" resultMap"BaseResultMap">select *from userwhere id < #{id}; </select>方式二&am…

设计模式:依赖倒转原则(Dependency Inversion Principle,DIP)介绍

依赖倒转原则&#xff08;Dependency Inversion Principle&#xff0c;DIP&#xff09;是面向对象设计原则之一&#xff0c;它强调高层模块不应该依赖于底层模块&#xff0c;二者都应该依赖于抽象。同时&#xff0c;抽象不应该依赖于具体实现细节&#xff0c;具体实现细节应该依…

嵌入式开发学习--进程、线程

什么是进程 进程和程序的区别 概念 程序&#xff1a;编译好的可执行文件&#xff0c;存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09;&#xff0c;程序是静态的&#xff0c;没有任何执行的概念。 进程&#xff1a;一个独立的可调度的任务&#xff0c;执行一…

高可靠性部署系列(3)--- ASG双机热备(HA)

高可靠性部署系列(3)--- ASG双机热备(HA) 前言网络拓扑设备选型网络规划组网需求配置思路操作步骤步骤 1 HA接口管理地址配置步骤 2 HA全局配置步骤 3 配置同步步骤 4 接口状态同步组创建结果验证前言 近期有读者留言:“因华为数通模拟器仅能支持USG6000V的防火墙,无法支…

东方博宜1009 - 数组逆序

题目描述 给你 nn 个整数&#xff0c;将其逆序输出。 输入 第一行一个整数 nn &#xff08;3 \le n \le 1003≤n≤100)代表数的个数。 第二行 nn 个整数&#xff08;空格隔开&#xff09;&#xff08;这些数在 0 \sim 10^60∼106 之间)。 输出 nn 个整数&#xff08;空格…

恶补《操作系统》3_1——王道学习笔记

3内存管理 3.1_1 内存的基础知识 1、什么是内存&#xff0c;作用 &#xff08;1&#xff09;内存&#xff1a;内存用来存放数据。程序执行前需要先放到内存中才能被CPU处理――缓和CPU与硬盘之间的速度矛盾。 &#xff08;2&#xff09;内存存储单元&#xff1a;每个地址对应…

AIGC技术的发展现状和未来趋势

AIGC&#xff08;人工智能生成内容&#xff09;技术是指利用人工智能算法自动生成文本、图像、音频、视频等各类内容的技术。随着深度学习等技术的快速发展&#xff0c;AIGC技术在最近几年取得了显著进步&#xff0c;并在多个领域展现出巨大的潜力。 ​ 编辑 发展现状&#x…

前端数字计算精度问题

计算精度问题通常发生在浮点数运算中&#xff0c;由于浮点数的表示所限&#xff0c;可能导致精度损失。 举例 // 比如 0.1 0.2 // 结果为 0.30000000000000004 0.3 - 0.1 // 结果为 0.19999999999999996vue vue 使用decimal.js 解决小数相加合计精确度丢失问题 微信小程序 …

【2024系统架构设计】回顾历史,查缺补漏篇 ①

前言 hello,大家好: 💡💡💡 我们一起来备考软考高级系统架构设计师吧,本专栏提供综合知识、案例科目、论文(论点和部分示例范文)等内容,包括知识点总结和记忆小妙招哦。 🚀🚀🚀 可以减少资料查找和收集的时间,提高效率,我们一起

ARM功耗管理背景及挑战

安全之安全(security)博客目录导读

服务器网站漏洞怎么修复

服务器网站漏洞的修复是一个关键且复杂的过程&#xff0c;涉及到多个层面的安全加固。以下是一个关于如何修复服务器网站漏洞的详细指南。安全狗专业做服务器安全&#xff0c;有任何服务器安全问题都可以找安全狗哦. ​一、识别和分析漏洞 首先&#xff0c;要确定服务器网站存在…

基于NodeJS + Swagger UI搭建Web API界面

基于NodeJS Swagger UI搭建Web API界面 前言一、创建基于NodeJS的Swagger运行目录二、添加Swagger官方的示例1.创建public工作目录2.添加Swagger官方示例3.启动SwaggerUI实例 三、基于OpenAPI规范提供api文档 前言 Swagger是一个REST APIs文档在线自动生成和测试的框架 一、…

Linux下的基本指令(1)

嗨喽大家好呀&#xff01;今天阿鑫给大家带来Linux下的基本指令&#xff08;1&#xff09;&#xff0c;下面让我们一起进入Linux的学习吧&#xff01; Linux下的基本指令 ls 指令pwd命令cd 指令touch指令mkdir指令(重要)rmdir指令 && rm 指令(重要)man指令(重要)cp指…

基于 NXP iMX8MM 测试 Secure Boot 功能

By Toradex秦海 1). 简介 嵌入式设备对于网络安全的要求越来越高&#xff0c;而 Secure boot就是其中重要的一部分。 NXP i.MX8MM/i.MX8MP 处理器基于 HABv4 特性来提供 Secure boot 启动过程中的 Chain of Trust&#xff1b; HABv4 是基于公共密钥加密 (Public Key Cryptogr…

C语言进阶:指针的进阶(上)

首先 在学习新知识之前 我们先来回顾下之前的学习的内容 1 指针是个变量 用来存放地址 地址唯一标识的一块内存空间 2 指针的大小是固定的4/8字节&#xff08;32位平台/64位平台&#xff09; 3 指针有类型的 指针的类型决定了两点 一个是指针操作的权限以及整数的步长 4 指针的…