C语言面试题(第二部分)(2024年收集更新)
2024年收集更新的C语言面试题(第二部分),C语言面试题(第二部分),最新最常见的 C语言编程面试问题和答案。
在C语言中声明变量:变量声明仅在编译时向编译器提供以给定类型和名称存在的变量的确定性,以便编译器继续进行进一步编译,而不需要该变量的所有细节。 在 C 语言中,当我们声明一个变量时,我们只将信息提供给编译器,但没有为它保留内存。 它只是一个引用,通过它我们只向编译器保证这个变量可以定义在函数内部或函数外部。
注意:我们可以多次声明一个变量,但只定义一次。
例如:
extern int data;
extern int foo(int, int);
int fun(int, char); //...
完整答案
全局变量和静态全局变量有不同的联系。 这就是全局变量可以在文件外部访问但静态全局变量只能在声明它的文件内访问的原因。
静态全局变量 ===>>> 内部链接。
非静态全局变量 ===>>> 外部链接。
...
完整答案
存储类决定程序中变量或函数的范围(生命周期)和范围(可见性)。 每个变量都在内存中的某个位置以位的形式存储变量的值。 存储类决定这些变量值将存储在 CPU 寄存器、堆栈内存、BSS 或 DS 中的位置。
C语言编程中有四种可用的存储类,它们如下:
autostaticexternregister
...
完整答案
在C语言中,外部静态变量有内部链接,内部静态变量没有链接。 这就是它们具有不同范围但两者都将在整个程序中存活的原因。
外部静态变量 ===>>> 内部链接。
内部静态变量 ===>>> 无。
...
完整答案
让我们先来看一下 typedef 和宏的简短描述,以了解它们之间的区别。
typedefC语言提供了一个非常重要的关键字 typedef,用于为现有类型定义新名称。 typedef 是编译器指令,主要与用户定义的数据类型(结构、联合或枚举)一起使用,以降低它们的复杂性并增加代码的可读性和可移植性。
语法:
typedef type NewTypeName;
示例:
typedef unsigned int UnsignedInt;
现在 UnsignedInt 是一个新类型,就可以使用它来创...
完整答案
编译器错误。
解释:typedef 已被视为部分存储类,因此不能一次混合两个存储类。
完整答案
C语言中的变量定义了一个位置名称,可以在其中放置值,并且可以在程序中需要时使用这些值。 换句话说,可以说变量是一个名称(或标识符),它指示内存中的某个物理地址,其中数据以字符串位的形式存储。
在C语言中,每个变量都有特定的数据类型(预定义的或用户定义的),这些数据类型决定了变量的大小和内存布局。
注意:每个变量都绑定了两个重要的属性,范围和范围。
...
完整答案
变量 p 对应的声明如下:
1. int p; // An integer
2. int p[5]; // An array of 5 integers
3. int *p; // A pointer to an integer
4. int *p[10]; // An array of 10 pointers to integers
5. int **p; // A pointer to a pointer to an integer
6. int (*p)[3]; // A pointer ...
完整答案
数据类型是数据的分类,它告诉编译器或解释器程序员打算如何使用数据。 换句话说,您可以说它定义了变量的大小(BYTE)和范围。C语言中数据类型的分类:1、预定义数据类型(int、char、float等)2、用户定义的数据类型(struct、union、enum)
在 C 语言中,不同的数据类型有不同的范围。 范围因编译器而异。 在下表中,根据 32 位 GCC 编译器列出了一些具有范围和格式说明符的数据类型。
数据类型 Memory (bytes) 范围 ...
完整答案
在 C 语言中,static 关键字非常重要。 如果在变量或函数中使用了 static 关键字,那么只有内部链接或无链接有效。1、静态变量只初始化一次,因此在函数体内声明为静态的变量在函数调用之间保持其先前值。2、带有static关键字的全局变量具有内部链接,因此只能在翻译单元(.c)内访问。 其他翻译单元无法访问它。 static 关键字保护变量从另一个编译单元访问。3、默认情况下,在 C 语言中,函数的链接是外部的,它可以被同一个或另一个翻译单元访问。 在 static 关键字的帮助下,可以...
完整答案
C语言有3种链接,外部链接、内部链接和无链接。
完整答案
可以,我们可以在头文件中声明静态变量。
完整答案
C标准解释了整数的最小大小应该是 16 位。 一些编程语言解释说整数的大小取决于实现,但可移植程序不应该依赖它。整数的大小主要取决于编译器编写者为底层处理器编写的编译器类型。可以看到编译器根据便利性和底层架构愉快地改变整数的大小。 因此,建议使用 C99 整数数据类型(uin8_t、uin16_t、uin32_t ..)代替标准 int。
...
完整答案
在标准 C 语言中,整数数据类型默认是有符号的。 所以如果创建一个整数变量,它可以存储正值和负值。
完整答案
有符号和无符号整数类型具有相同的存储(根据标准至少 16 位)和对齐方式,但它们仍然存在很多差异,在下面的行中,描述有符号和无符号整数之间的一些差异。
有符号整数可以同时存储正值和负值,但在它旁边无符号整数只能存储正值。有符号整数类型的非负值范围是相应无符号整数类型的子范围。例如:
假设整数的大小为 2 个字节。有符号整数 -32768 到 +32767无符号整数 0 到 65535
在计算无符号整数时,它永远不会溢出,因为如果计算结果大于无符号整数类型的最大值,则它会以比结果类型可以表示的...
完整答案
宏和函数的区别如下所示:
完整答案
输出:编译器错误。说明: 扩展宏时,var 将被替换为 0(Rvalue)。 因为正在尝试增加 Rvalue,所以将收到编译器错误。
完整答案
C语言中的枚举是用户定义的数据类型。 它由一组命名的常量整数组成。 使用 enum 关键字,我们可以通过使用枚举标签(可选)和命名整数列表来声明枚举类型。基本上,我们使用枚举来增加代码的可读性,并且与符号常量(宏)相比,使用枚举更容易调试代码。 enum 最重要的属性是它遵循范围规则,编译器会自动将值分配给它的成员常量。
注意:枚举类型的变量存储由该类型定义的枚举列表的值之一。
enum 的语法如下:
enum Enumeration_Tag { Enumeration_List };
E...
完整答案
const 限定符仅向编译器指示无法更改限定对象的值。 简单来说, const 表示不可修改(不能在运行时给对象赋值)。
语法:
const DataType Identifier = Value;
e.g.
const int iData = 0;
完整答案
在程序中有以下地方需要使用 const 关键字:
在引用函数参数调用中,如果不想更改已传入函数的实际值。
int PrintData ( const char *pcMessage);
在某些地方, const 比宏更好,因为 const 由编译器处理并且具有类型检查。
const int ciData = 100;
对于 I/O 和内存映射寄存器,const 与 volatile 限定符一起使用以实现高效访问。
const volatile uint32_t *DEVICE_STATUS...
完整答案
a是一个常数整数。与第一个类似,a是一个常数整数。这里的a是一个指向常量整数的指针,整数的值是不可修改的,但指针是可修改的。这里的a是一个指向整数的常量指针,指向的整数的值是可修改的,但指针是不可修改的。这里的a是一个指向 const 整数的 const 指针,这意味着指向的整数和指针的值都是不可修改的。
...
完整答案
上述代码的输出将是 1.200000,有 6 个空格。
解释:这里 1.200000 是用 6 个空格打印的,因为通过在 printf 中给出 * 可以指定一个额外的宽度参数,这里pos是宽度,data是值。 如果数字小于宽度,则其余部分用空格填充。
...
完整答案
常量指针:常量指针是其值(指向的地址)不可修改的指针。 如果尝试修改指针值,将得到编译器错误。常量指针声明如下:
Data_Type * const Pointer_Name;
int *const ptr; //constant pointer to integer
当编译以下代码会得到编译器错误时,让我们看看下面的示例代码。
#include<stdio.h>
int main(void)
{
int var1 = 10, var2 = 20;
//Initia...
完整答案
当在操作数上使用后自增 (++) 运算符时,结果是操作数的值,得到结果后,操作数的值加 1。后自减 (–-) 的工作 运算符类似于后自增运算符,但不同之处在于操作数的值减 1。
注意:递增和递减 1 是指定的类型。
...
完整答案
现在的编译器已经足够聪明了,它们根据需求优化代码。 post 和 pre-increment 都有自己的重要性,我们需要根据要求使用它们。如果您通过字符指针逐字节读取闪存,那么在这里您必须使用后增量,否则将跳过数据的第一个字节。在预递增的情况下,指向地址将先递增,然后再读取该值。在下面的示例代码中,创建一个字符数组并使用想要读取数组值的字符指针。但是如果使用预增量运算符会发生什么? 这个问题的答案是“A”将被跳过而 B 将被打印出来。
#include <stdio.h>
int m...
完整答案
*ptr++ 和 ++*ptr两种表达方式不同。下面通过一个示例代码来了解这两个表达式之间的区别。
#include <stdio.h>
int main(void)
{
int aiData[5] = {100,200,30,40,50};
int *ptr = aiData;
*ptr++;
printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], ...
完整答案
这两种表达方式不同。 下面来看一个示例代码来了解这两个表达式之间的区别。
示例1:
#include <stdio.h>
int main(void)
{
int aiData[5] = {100,200,30,40,50};
int *piData = aiData;
++*piData;
printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiDat...
完整答案
常量和宏的主要区别如下:
const 关键字由编译器处理,另一方面,宏由预处理器指令处理。const 是修饰标识符行为的限定符,但宏是预处理器指令。使用 const 关键字会进行类型检查,但不会对 #define 进行类型检查。const 由 C 块限定,#define 适用于文件。const 可以作为参数(作为指针)传递给函数。 在通过引用调用的情况下,它可以防止修改传递的对象值。
...
完整答案
volatile 关键字是一种类型限定符,可防止编译器优化对象。 根据 C 标准,具有 volatile 限定类型的对象可能会以实现未知的方式进行修改或具有其他未知的副作用。也可以说,可以随时更改 volatile 限定对象的值,而无需代码执行任何操作。如果对象由 volatile 限定符限定,则编译器每次程序访问它时都会从内存中重新加载该值,这意味着它会阻止将变量缓存到寄存器中。 从内存中读取值是检查值的不可预测变化的唯一方法。
...
完整答案
可以,可以在 C 语言中创建一个 volatile 指针。示例代码如下:
int * volatile piData; // piData is a volatile pointer to an integer.
完整答案
在这里,指出了一些需要使用 volatile 关键字的重要地方。
1、访问内存映射的外设寄存器或硬件状态寄存器。示例代码:
#define COM_STATUS_BIT 0x00000006
uint32_t const volatile * const pStatusReg = (uint32_t*)0x00020000;
unit32_t GetRecvData()
{
//Code to recv data
while (((*pStatusReg) & COM...
完整答案
const 关键字是编译器强制执行的,它表示程序无法更改对象的值,这意味着它使对象成为不可修改的类型。例如:
const int a = 0;
如果尝试修改a的值,将收到编译器错误,因为a使用 const 关键字限定,阻止更改整数变量的值。另一方面, volatile 阻止任何编译器优化,并表示对象的值可以通过超出程序控制范围的东西进行更改,因此编译器不会对对象做出任何假设。例如:
volatile int a;
当编译器看到上述声明时,它会避免对a做出任何假设,并在每次迭代中从分配给变量的...
完整答案
是的,可以同时使用常量和易失性。 volatile 和 const 关键字的最大用途之一是在访问 GPIO 寄存器时。 在 GPIO 的情况下,如果它被配置为输入,它的值可以通过“外部因素”(如果开关或任何输出设备连接到 GPIO)来更改。 在这种情况下, volatile 起着重要作用,并确保编译器始终从 GPIO 地址读取值并避免做出任何假设。使用 volatile 关键字后,无论何时访问端口,都将获得正确的值,但这里还有一个问题,因为指针不是 const 类型,因此可能是程序更改了指针的指...
完整答案
设置第 N 位设置第 N 位意味着如果第 N 位为 0,则将其设置为 1,如果为 1,则保持不变。 在 C 中,按位或运算符 (|) 用于设置整数数据类型的位。 据我们所知| (按位或运算符)计算一个新的整数值,其中每个位的位置只有当操作数(整数类型)在该位置为 1 时才为 1。简而言之,如果其中任何一位为 1,则可以说两位的“按位或”始终为 1。
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
设置位的算法:
Number | = (1UL <<...
完整答案
让给定的整数是a和b。 如果a的符号位与b的符号位不同,则a和b的符号位 (MSB) 的 EX-OR 将为 1。 换句话说,如果a和b的符号相反,a和b的异或将是负数。
示例代码:
bool CheckOppositeSign(int a, int b)
{
bool bRetValue = 0;
bRetValue = ((a ^ b) < 0); // true if a and b have opposite signs
return bRetValue;
}...
完整答案
有很多方法可以反转数字的位,这里描述了三种通用的方法来反转位。
方法一在此方法中,将检查 num 的设置位并循环遍历整数的所有位。 如果发现 num 的第 i 位被设置,那么只需将 1 放在 tmp 的 ((INT_BITS – 1) – ith ) 位置,其中 INT_BITS 是整数的位数。
#define CHAR_BITS 8 // size of character
#define INT_BITS ( sizeof(int) * CHAR_BITS)
//bit reversa...
完整答案
参考以下代码实现:
#define CHAR_BITS 8 // size of character
#define INT_BITS ( sizeof(int) * CHAR_BITS) //bits in integer
void PrintInBinary(unsigned n)
{
char Pos = (INT_BITS -1);
for (; Pos >= 0 ; --Pos)
{
(n & (1 << Pos)...
完整答案
上面程序的输出是:8
完整答案
上面程序的输出是:15
完整答案
上面程序的输出:2
完整答案
假设 a、b 两个数字,有很多方法不使用第三个变量交换两个数字的值。
方法1(使用算术运算符):
#include <stdio.h>
int main()
{
int a = 10, b = 5;
// algo to swap 'a' and 'b'
a = a + b; // a becomes 15
b = a - b; // b becomes 10
a = a - b; // fonally a...
完整答案
下面来看看如何编写一个小算法来检查 2 的幂。如果一个数字是 2 的幂,则函数返回 1。示例代码1:
int CheckPowerOftwo (unsigned int x)
{
return ((x != 0) && (!(x & (x - 1))));
}
示例代码2:
int CheckPowerOftwo (unsigned int x)
{
return (x && (!(x & (x - 1))));
}
...
完整答案
输出结果:未定义的行为。
完整答案
实现定义(implementation-defined)
完整答案
请参考下面代码实现:
unsigned int NumberSetBits(unsigned int n)
{
unsigned int CountSetBits= 0;
while (n)
{
CountSetBits += n & 1;
n >>= 1;
}
return CountSetBits;
}
完整答案
在C程序中有下面情节应该使用指针:
传递大型结构喜欢的服务器请求或响应数据包。实现链表和二叉树。GPIO 或硬件寄存器。从函数中获取地址或更新值(通过引用调用)创建动态数组。使用函数指针创建回调函数。
注意:除此之外,还有很多地方需要用到指针。
...
完整答案
void 指针是通用指针。它没有关联的数据类型,这就是为什么它可以存储任何类型对象的地址并类型转换为任何类型的原因。根据 C 标准,指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。 void 指针声明类似于普通指针,但不同之处在于使用 void 关键字代替数据类型。
语法:
void * Pointer_Name;
...
完整答案
C语言中的 void 指针有以下优点:
使用 void 指针,可以创建一个可以接受任何数据类型参数的通用函数。 memcpy 和 memmove 库函数是泛型函数的最佳示例,使用这些函数可以将数据从源复制到目标。例如:
void * memcpy ( void * dst, const void * src, size_t num );
void 指针可以转换为另一种数据类型,这就是 malloc、calloc 或 realloc 库函数返回 void * 的原因。 由于 void *这些函...
完整答案
通常,当引用对象被删除或释放时,会出现延迟指针,而不会更改指针的值。 它会产生问题,因为指针仍然指向不可用的内存。 当用户尝试取消引用悬空指针时,它会显示未定义的行为,并且可能是分段错误的原因。
示例代码:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *piData = NULL;
//creating integer of size 10.
piData = malloc(sizeo...
完整答案
在首次使用之前未正确初始化的指针称为野指针。 未初始化的指针行为是完全未定义的,因为它可能指向某个可能导致程序崩溃的任意位置,这就是它被称为野指针的原因。换句话说,编程语言中没有被编译器或程序员初始化的每个指针都以野指针开始。
注意:通常,编译器会警告通配指针。
语法:
int *piData; //piData is wild pointer
...
完整答案
根据 C 标准,值为 0 的整数常量表达式,或转换为 void * 类型的此类表达式称为空指针常量。 如果将空指针常量转换为指针类型,则生成的指针称为空指针。语法:
int *piData = NULL; // piData is a null pointer
...
完整答案
函数指针类似于其他指针,但唯一的区别是它指向函数而不是变量。换句话说,函数指针是一种存储函数地址的指针,这些指向的函数可以在程序中随时被函数指针调用。
完整答案
声明函数指针的语法非常简单。 一开始似乎很难,但是一旦熟悉了函数指针,它就会变得容易。函数指针的声明类似于函数的声明。 这意味着函数指针还需要返回类型、声明名称和参数列表。 需要记住的一件事是,每当在程序中声明函数指针时,声明名称前面都有 *(星号)符号并用括号括起来。
例如:
void ( *fpData )( int );
为了更好的理解,我们举个例子来描述一下 C语言中函数指针的声明。
示例:
void ( *pfDisplayMessage) (const char *);
在上面的...
完整答案
有很多地方可以使用函数指针。 通常,函数指针用于实现回调函数、有限状态机以及提供C语言中的多态特性等。
完整答案
数组和指针之间的一个重要区别是数组中元素的地址始终是固定的,不能在执行时修改地址,但对于指针,可以根据需要更改指针的地址。考虑下面的例子:
在下面的示例中,当尝试增加数组的地址时,将得到编译器错误。
...
完整答案
输出结果为:*arr size 80解释:
int (*arr)[5][4] 是指向数组的指针。 4*5 的元素总数,如果整数大小为 4 字节,则 *arr 的大小将为 80。
完整答案
根据 C 标准,有四种存储持续时间,静态、线程 (C11)、自动和分配。存储期限决定了对象的生命周期。
静态内存分配:静态分配意味着,一个对象具有外部或内部链接或使用静态存储类声明。它仅在程序启动之前初始化一次,其生命周期贯穿程序的整个执行过程。全局和静态变量是静态内存分配的一个示例。
动态内存分配:在 C 语言中,有很多用于动态分配内存的库函数(malloc、calloc 或 realloc,..)。动态分配内存的问题之一是它不会被编译器本身破坏,这意味着用户有责任解除分配的内存。当使用内存管...
完整答案
内存泄漏是一个常见且危险的问题。 这是一种资源泄漏。 在 C 语言中,当使用内存管理功能分配一块内存而忘记释放它时,就会发生内存泄漏。示例:
int main ()
{
char * pBuffer = malloc(sizeof(char) * 20);
/* Do some work */
return 0; /*Not freeing the allocated memory*/
}
注意:一旦分配了内存,分配的内存在空闲之前不会分配给另一个程序或进程。
.....
完整答案
malloc 和 calloc 是内存管理函数。 它们用于动态分配内存。 基本上,calloc 和 malloc 之间没有实际区别,只是 calloc 分配的内存用 0 初始化。在 C 语言中,calloc 函数将所有分配的空间位初始化为零,但 malloc 不初始化分配的内存。 这两个函数的参数数量也有所不同, malloc 接受一个参数,而 calloc 接受两个。
...
完整答案
realloc()函数用于调整分配的内存块的大小。 它有两个参数,第一个是指向先前分配的内存的指针,第二个是新请求的大小。realloc()函数首先释放旧对象,然后重新分配新指定的大小。 如果新大小小于旧大小,则新分配内存的内容将与先前相同,但如果新创建的对象中的任何字节超出旧大小,则超出大小的值将是不确定的。
语法:
void *realloc(void *ptr, size_t size);
示例代码:
#include <stdio.h>
#include <stdli...
完整答案
如果请求空间的大小为零,则行为将由实现定义。 malloc 的返回值可能是一个空指针,或者它表明该大小的行为是某个非零值。 标准建议不要使用指针来访问当大小为零时由 malloc 返回的对象。
...
完整答案
内存管理功能保证如果内存被分配,那么它将适当地与任何具有基本对齐的对象对齐。基本对齐小于或等于没有对齐规范的实现所支持的最大对齐。动态内存分配的主要问题之一是碎片,基本上,碎片发生在用户没有有效使用内存时。有两种类型的碎片,外部碎片和内部碎片。外部碎片是由于空闲列表上可用但程序无法使用的小空闲内存块(小内存洞)造成的。有不同类型的空闲列表分配算法可以有效地使用空闲内存块。为了理解外部碎片,考虑一个程序有 3 个连续的内存块并且用户释放中间的内存块的场景。在这种情况下,如果所需的内存块大于单个内存...
完整答案
当我们调用内存管理函数(malloc、calloc 或 realloc)时,这些函数会保留额外的字节用于簿记。每当调用 free() 函数并传递指向已分配内存的指针时,free()函数都会获取簿记信息并释放分配的内存。 无论如何,如果程序更改指向已分配地址的指针的值,则调用 free()函数会给出未定义的结果。
____ The allocated block ____
/
+--------+--------------------....
完整答案
在 C 语言中,可以使用 sizeof 运算符计算静态数组的大小,但没有运算符来计算动态分配的内存大小。主要有两种方法可以在代码的每个部分中获取分配的内存大小。
创建一个全局变量来存储分配的内存大小。携带已分配内存的长度。
示例:
假设需要创建一个大小为 n 的整数数组。 所以要携带数组的数组长度,需要为n+1分配内存。
int *piArray = malloc ( sizeof(int) * (n+1) );
如果内存分配成功,则分配 n(数组的大小)它的 0 个位置。
piArray[...
完整答案
上面示例代码输出结果是:0 1 2 2 3
解释:第一个 printf:*ptr++ 意味着它将增加地址并取消引用该地址,但这里的增量是一个后增量,所以首先和之后取消引用,所以在基地址上你得到 0(ptr 指向下一个位置)。第二个 printf: (*ptr)++ 第一次取消引用,然后增加值,所以位置值是 1 是增量,所以得到 2(这里的指针没有改变)。第三个 printf: *ptr 表示当指针指向该位置时取消引用,所以得到 2。第五个 printf:*++ptr 表示第一个指针在取消引用后递...
完整答案
这两个副本函数都用于将 n 个字符从源对象复制到目标对象,但它们有一些区别,如下所述。
如果源指针和目标指针指向的内存区域重叠,则 memcpy 复制函数会显示未定义的行为。 memmove 函数在重叠的情况下具有定义的行为。 因此,每当有疑问时,使用 memmove 代替 memcpy 会更安全。
#include <string.h>
#include <stdio.h>
char str1[50] = "I am going from Delhi to ...
完整答案
字符串是字符的集合,它总是以空字符结尾,这意味着每个字符串在字符串的末尾都包含一个空字符。例子:
char *pszData = “aticle”;
在上面的示例中,pszData 是指向字符串的指针。 字符串的所有字符都存储在一个连续的内存中,并在字符串的最后一个空字符组成。
见下表:
character ‘a’ ‘t’ ‘i’ ‘c’ ‘l’ ‘e’ ‘ ’
Address 0x00 0x01 0x02 0x03 ....
完整答案
字节序是在内存中存储数据的字节顺序,它还描述了通过数字链路传输字节的顺序。 在内存数据存储中,顺序取决于系统的字节序,如果系统是大字节序,则首先存储 MSB 字节(意味着在低地址),如果系统是小端序,则首先存储 LSB 字节(在较低的地址)。little-endian 和 big-endian 系统的一些示例:
...
完整答案
下面使用 C语言来编写程序检查系统的字节顺序。
方法一:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void)
{
uint32_t u32RawData;
uint8_t *pu8CheckData;
u32RawData = 0x11223344; //Assign data
pu8CheckData = (uint8_t *)...
完整答案
下面下面是编写 C 程序来将 little-endian 转换为 big-endian(反之亦然)。方法一:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
//Function to change the endianess
uint32_t ChangeEndianness(uint32_t u32Value)
{
uint32_t u32Result = 0;
u3...
完整答案
素数是一个正的自然数,它的值大于 1,并且只有两个因数 1 和数本身。使用除法检查素数的算法开始
步骤 1 → 取数 n步骤 2 → 将数字 n 除以 (2, n-1) 或 (2, n/2) 或 (2, sqrt(n))。步骤 3 → 如果数 n 可被 (2, n-1) 或 (2, n/2) 或 (2, sqrt(n)) 之间的任何数整除,则它不是素数步骤 4 → 如果它不能被 (2, n-1) 或 (2, n/2) 或 (2, sqrt(n)) 之间的任何数整除,则它是质数最后停止
示例代码:...
完整答案
方法一:
#include <stdio.h>
int main(int argc, char *argv[])
{
int iTotalElement = 0 ;
int aiData[] = {10, 20, 30, 40, 50, 60};
//Calculate numbers of elements using pointer arithmatic
iTotalElement = *(&aiData + 1) - aiData;
...
完整答案
方法一:
当增加指针时,指针会增加一块内存(内存块取决于指针数据类型),所以这里将使用这种技术来计算sizeof结构。
首先,创建结构。创建一个指向结构的指针并分配 NULL 指针。将指针增加到 1。
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char Name[12];
int Age;
float Weight;
int RollNumber;...
完整答案
在结构或联合的情况下,编译器在结构或联合的成员之间插入一些额外的字节用于对齐,这些额外未使用的字节称为填充字节,这种技术称为填充。填充以内存为代价提高了处理器的性能。 在结构或联合数据成员中,按照最高字节成员的大小对齐,以防止性能损失。
注意:处理器架构要求的数据类型对齐,而不是语言。
...
完整答案
在 C 语言中,有很多方法可以将二维数组作为参数传递。 在下面的部分中,将描述几种将二维数组作为参数传递给函数的方法。
使用指针将二维数组传递给c中的函数多维数组的第一个元素是另一个数组,当传递一个二维数组时,它将被拆分为指向数组的指针。
例如
如果 int aiData[3][3], 是一个 2D 整数数组,它将被拆分为指向 3 个整数数组的指针 (int (*)[3])。
#include <stdio.h>
//Size of the created array
#define...
完整答案
枚举和宏的区别:
与宏相比,枚举增加了代码的可读性并且易于调试。枚举的所有元素组合在一起,宏是不可能的。
示例:
//constant created by macro,
#define MON 0
#define TUE 1
#define WED 2
#define THU 3
#define FRI 4
#define SAT 5
#define SUN 6
//constant created by enum,
typedef enum Days
{
Mon,
Tue,...
完整答案
通过给定的指针直接删除节点没有实际的解决方案,需要做一些技巧。通过给定的要删除的指针将数据从下一个节点复制到当前节点并删除下一个节点。参考示例:
//Get the Address of the next node
NodePointer temp = Node->pNextNode;
//Get the data of next node
Node->iData = temp->iData;
//Get the Address of next to next no...
完整答案
请参阅下面的示例,其中交换两个变量的值。
#include <stdio.h>
#define swap(x,y,T) do {
T temp = (*x);
(*x) = (*y);
(*y) = temp;
} while (0)
int main(void)
{
int a = 5;
int b = 9;
printf("Value of a and b before swaping
");
...
完整答案
递归是函数调用自身的过程,直接或间接调用自身的函数称为递归函数。 递归函数调用自身,所以可以有多个递归调用,所以递归函数应该有终止条件来中断递归。 如果递归函数中存在非终止条件,则会发生堆栈溢出,程序将崩溃。递归函数可用于解决许多数学问题,例如生成斐波那契数列、计算数字的阶乘以及便于递归定义的数据结构(如树)。
让我们看一个例子,
void test( int n)
{
test(n);
// Remaining code
}
在上面的代码中,test()是一个调用自身的递归函数...
完整答案
基本上,C 程序的内存布局包含五个段,它们是堆栈段、堆段、BSS(由符号开始的块)、DS(数据段)和文本段。每个段都有自己的读、写和可执行权限。 如果程序尝试以不允许的方式访问内存,则会发生分段错误。
下面找到C程序的内存布局
栈堆BSS(未初始化数据段)DS(初始化数据段)文字
...
完整答案
为了理解这个问题,让我们举个例子,假设 arris 是一个 5 个元素的整数数组:int arr[5];如果打印 arr 和 &arr ,那么会发现相同的结果,但两者都有不同的类型。
arr => 数组的名称是指向其第一个元素的指针。 所以这里 arr, split 作为指向整数的指针。&arr => 它拆分为指向数组的指针,这意味着 &arr 将类似于 int(*)[5];
#include<stdio.h>
int main()
{
...
完整答案
参考以下代码实现:
#include<stdio.h>
int main()
{
int count = 0;
int numb1 = 0;
int numb2 =0;
int i =0;
printf("Enter count of numbers = ");
scanf("%d",&count);
if(count <= 0)
{
...
完整答案
C语言中有很多双指针的应用,但这里我描述的是双指针的一个重要应用。 如果想创建一个函数来分配内存,并且想从函数参数中取回分配的内存,那么需要在这种情况下使用双指针。 看下面的代码:
#include<stdio.h>
#include<stdlib.h>
void AllocateMemory(int **pGetMemory,int n)
{
int *p = malloc(sizeof(int)*n);
if(p == NULL)
{
...
完整答案
该代码将打印 3 次HI。 printf()函数将返回它正在打印的字符数,并将其与a进行比较。 由于 printf() 的返回值为 2,HI 将被打印 2 次。 最后,当a的值为 3 时,它首先打印 HI 并检查条件,并在条件失败时退出 while 循环。 因此,HI 将被打印 3 次。
...
完整答案
一个负值。
解释说明:
int strcmp(const char *s1, const char *s2);
strcmp() 返回一个表示比较结果的整数,
如下:
0, if the s1 and s2 are equal;
A negative value if s1 is less than s2;
A positive value if s1 is greater than s2;
...
完整答案
输出结果为:Undefined
解释:
到达 main 以外的函数的末尾,就相当于返回; 到达任何其他值返回函数的末尾是未定义的行为,但前提是函数的结果用于表达式中。 在无返回函数中执行 return 语句是未定义的行为。
...
完整答案