1.简述const的作用,const与#define相比,有何优点。
表示定义一个常量,其值在程序的允许期间不可改变。
优点:
1.类型更加安全,const是有类型的常量,编译器会进行类型检查 define 是简单的文本替换 可能会导致未定义的行为
2.作用域,const可以作用在特定的代码块中 define宏定义是全局的 可能会导致命名冲突
3.调试友好,const调试可以识别常量的名称 define不可见
4.使用表达式,const用于初始化时表达的计算 define只能使用简单的常量或表达式
5.const占空间 define在预处理期间替换 不占用空间
2. 头文件中的 #ifndef #define #endif 干什么用?
1.防止头文件的重复包含,如果一个头文件被多个源文件包含,或同一个源文件多次包含同一个头文件,可能导致重复定义的错误。该指令确保包含的内容只被编译一次
2.提高编译效率,确保每次只编译一次 更快处理源文件 提高编译效率
3.what's the difference among the data types "char *p",
"const char *p", "char * const p"and"const char *const p" ?
1.char *p
指向char类型的指针
既可以修改p指向的地址 又可以修改p指向的内容
2.const char *p
指向常量char 的指针p 常量指针 指向的内容不可改变 指向的地址可以改变
3.char * const p
指向char的常量指针p 指针常量 指向的方向不可改变 指向的内容可以改变
4.const char * const p
指向常量的常量指针 指向的方向和内容都不可改变
4.局部变量能否和全局变量重名.
可以 局部变量优先级高于全局变量 如果想要使用全局变量则在全局变量前加作用域符号::(c++) 使用extern(c)
5.请简述typedef int(*FUN)(int x, int y)及其作用
定义一个指向两个参数为int并且返回值为int 类型的函数指针
使用typedef为该指针别名为 FUN
作用:使函数指针的声明与使用更加简洁和直观
6.C语言中的main函数返回值有什么用?
返回值类型通常返回一个整型 int
指示程序退出状态 返回值为0 表示程序成功退出 返回值非0 表示程序出现错误或异常
7.VC中有哪些方法避免C编程中的头文件重复包含?
1.宏预处理指令
#ifndef HEADER_FILE_NAME_H // 检查宏是否定义 #define HEADER_FILE_NAME_H // 定义宏
// 头文件内容
#endif // HEADER_FILE_NAME_H // 结束判断
2.#pragma once
8.将程序移植到不同的32位cpu中,经常出现结构字节对齐和大小端的问题,有哪些方法避免?
结构体字节对齐问题,避免方式:
1.手动控制字节对齐 如按照4个字节对齐 #pragma pack(4)
大小端问题:
1.识别大小端是否一致 写一个判断大小端的函数 如果大小端不一致 写一个转换大小端的函数 进行转换
\9. sizeof
struct
{
short a;
long b;
char c;
}d;
sizeof(d)为什么在不同的平台上得到的值不一样?
平台问题 x86 long 4字节 x64 long 8字节
字节对齐问题
10.strcpy()为什么会造成缓冲区溢出?可用哪个函数代替?
strcp(a,b);如果b的长度大于a能存储的最大长度 就会产生缓冲区溢出 该函数没有识别目标缓冲区长度的功能
strcpy_s(a,len,b);
\11. strcat的效率问题,有没有更好的解决方案.
如果知道前一个字符串长度就可以直接从尾部开始拼接
建议答:将前一个字符串长度以参数传入
解决方案 string += ...;
12.Heap和Stack有什么区别
13.请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前操作系统的字节序。
多字节数据在内存的存储方式
大端字节序:高位字节存储在低地址,低位字节存储在高地址
例如,一个32位整数 0x12345678
在大端字节序中的存储顺序为:12 34 56 78
。
小端字节序:低位字节存储在低地址,高位字节存储在高地址
例如,同一个32位整数 0x12345678
在小端字节序中的存储顺序为:78 56 34 12
。
#include <stdio.h>
int main() {
unsigned int num = 0x12345678;
unsigned char *byte = (unsigned char *)#
if (byte[0] == 0x78) {
printf("Little-endian\n");
} else if (byte[0] == 0x12) {
printf("Big-endian\n");
} else {
printf("Unknown endianness\n");
}
return 0;
}
14.全局变量和static变量什么区别
1.作用域:
全局变量作用域是全局的,其他源文件可以通过extern访问该变量
static修饰全局变量 该变量的作用域被限制在当前的文件,其他文件无法访问
static修饰局部变量,该变量的作用域是局部的
2.生命周期: 全局变量:生命周期是整个程序运行期间,从程序启动到程序结束存储在全局/静态区
static:修饰全局变量,生命周期与全局变量相同
修饰局部变量,生命周期延长到整个程序运行期间,作用域仍然是局部的
3.链接属性:
-
-
全局变量:
-
默认是外部链接的,即其他文件可以通过
extern
关键字访问。 -
如果使用
static
修饰全局变量,则变为内部链接,只能在当前文件中访问。
-
-
static 变量:
-
如果
static
修饰全局变量,则该变量是内部链接的,只能在当前文件中访问。 -
如果
static
修饰局部变量,则该变量是无链接的,只能在定义它的函数或代码块内访问。
-
-
15.二进制数11101101转换为十八进制数是多少?
16.在函数体内声明[1] char *str = "abc";和 [2] char str[] = {'a','b','c'}有什么区别
17.strcpy,memcpy,sprintf的区别
1. strcpy
char *strcpy(char *dest, const char *src);
-
功能:用于复制字符串。
-
特点:
-
将
src
指向的字符串(包括结束符\0
)复制到dest
指向的内存中。 -
复制过程会一直进行,直到遇到
src
中的\0
为止。 -
不检查
dest
的内存大小,可能导致缓冲区溢出。char src[] = "Hello"; char dest[10]; strcpy(dest, src); // dest 现在包含 "Hello"
-
-
memcpy
-
功能:用于复制内存块。
-
原型:
void *memcpy(void *dest, const void *src, size_t n);
-
特点:
-
从
src
指向的内存地址开始,复制n
个字节到dest
指向的内存地址。 -
不关心数据的类型或内容,只是简单地按字节复制。
-
不检查
dest
和src
的内存是否重叠。如果内存重叠,行为是未定义的。
-
-
使用场景:复制任意类型的数据(如数组、结构体等)。
int src[] = {1, 2, 3, 4}; int dest[4]; memcpy(dest, src, sizeof(src)); // dest 现在包含 {1, 2, 3, 4}
-
sprintf
-
功能:用于格式化字符串并写入缓冲区。
-
原型:
int sprintf(char *str, const char *format, ...);
-
特点:
-
将格式化的字符串写入
str
指向的缓冲区。 -
类似于
printf
,但输出结果存储在缓冲区中,而不是打印到标准输出。 -
不检查缓冲区的大小,可能导致缓冲区溢出。
-
char buffer[50]; int num = 123; sprintf(buffer, "The number is %d", num); // buffer 现在包含 "The number is 123"
18.define的使用
(1)使用define定义一年有多少毫秒
#define mcount_per_year (365x24x60x60x1000)
(2)使用define定义max函数
#define max(a,b) ((a)>(b)?(a):(b))
(3)define中为何经常会使用 do{ }while(0);来包装多条语句代码
避免宏展开时的语法错误。
避免宏展开时的分号问题。
提高宏的兼容性和可读性。
19.实现一个死循环
while(1);
20.什么是预编译
由预处理器在编译器中对源代码进行处理,生成一个经过修改的源代码文件,供编译器使用
任务:
-
宏展开:处理
#define
定义的宏,将其替换为实际的值或代码。 -
文件包含:处理
#include
指令,将指定的头文件内容插入到当前文件中。 -
条件编译:根据
#if
、#ifdef
、#ifndef
、#else
、#elif
和#endif
等指令,选择性地编译代码。 -
删除注释:删除源代码中的所有注释。
-
处理特殊指令:如
#pragma
、#error
、#line
等。
21.#include<filename.h>和#include"filename.h"有什么区别?
优先在系统路径找
优先当前文件目录找这个文件 找不到再在系统路径找
22.写出三种交换两个int 变量a 和 b的方法:
1.____a= a^b ; b=a^b ; a= a^b; (a^=b; b^=a;a^=b;)
2.____a = a+ b;b = a-b;a = a-b;
3.____int tmp = a; a = b; b = tmp;
23.若x,y均是int型变量,则执行以下语句后,写出x,y的值 x=10 y = 6
for(y = 1,x = 1;y<=50;y++)
{
if(x>=10)break;
if(x%2 == 1)
{
x+=5;
continue;
}
x-=3;
}
24.写出以下代码段的输出结果
void swap(int m,int n)
{
int temp;
temp = m;m = n;n = temp;
}
main()
{
int m = 7,n = 5;
swap(m,n);
printf("m = %d,n = %d\n",m,n);
}
输出结果___m=7,n=5_________
25.请说明下面例子中const的用途()
\1) const int d = 100;__定义一个只读变量_________
2)const char *pStr1 = "ABCD";__内容不可改________
3)char *const pStr2 = "abcd";______方向不可改____
4)int func1(int value)const; ______定义常函数_____
26.写出以下程序的运行结果_____________
int count(int data) { int mask = 1; int i,count = 0; for(i = 0;i<sizeof(data)*8;i++) { if(data &mask) { count++; } mask<<=1; } return count; }
data = 0x3; count =____2_________
data = 0x12345678;count = ____13_______
1. data = 0x3
-
0x3
的二进制表示为:0000 0000 0000 0000 0000 0000 0000 0011
。 -
其中 1 的个数为 2。
-
data = 0000 1101 mask = 0000 0001 ------------------ & result = 0000 0001 (非 0)
2. data = 0x12345678
-
0x12345678
的二进制表示为:0001 0010 0011 0100 0101 0110 0111 1000
。 -
其中 1 的个数为 13。
27.下面程序的运行结果是__19_________
#define ADD(a+b) a+b
int main()
{
printf("%d\n",5ADD(3+4)); 5x3+4
}
28.在C语言程序中,要给绝对地址0x100赋值,我们可以用:
(unsigned int)0x100 = 1234;
那么,要是想让程序跳转到绝对地址0x100的位置上执行。怎样用一段代码实现_____________
void jump_to_address(void) {
// 定义一个函数指针,指向绝对地址 0x100
void (*func_ptr)() = (void (*)())0x100;
// 调用函数指针,跳转到 0x100 执行
func_ptr();
}
int main() {
jump_to_address(); // 跳转到绝对地址 0x100 执行
return 0;
}
29.在C语言中,若要定义一个只允许本源文件中所有函数适用的全局变量,则该变量应该加关键字()修饰。
static
30.请问执行完下面的程序后x[0]至x[5]的值应为__836475_____
int x[6] = {5,7,4,6,3,8}; int i,k,t; for(i = 0;i<5;i++) { for(k=(i+1);k<6;k++) { t = x[i]; x[i] = x[k]; x[k] = t; } }
31.试着写出结果及原因
unsigned char endian[2] = {1,0}; short x; x = *(short*)endian; 代码运行后,x的值是多少?
32.在 int b = { {1} ,{3 ,2},{4, 5 ,6},{0}};中 sizeof(b)是多少()
48
4行3列 4x3x4
33.请写出下面代码的输出结果。__2.5_________
void main(void) { int a[5] = { 1, 2, 3, 4, 5, }; int *ptr = (int*)(&a + 1); printf("%d,%d", *(a + 1), *(ptr - 1)); }
34.在64位机器下的输出为__80__.
int(*p[10])(int);
fprintf(stderr, "%d", sizeof(p));
指针数组 10个Int指针
35.在little-endian机器,以下代码的输出是__8__.
union { int i, j; char a, b; }x; int main(void) { x.a = 1; x.b = 2; x.j = x.a + x.b; x.i = x.a + x.j; printf("0x%x\n", x.i); return 0; }
36 .如果x = 2014下面函数的返回值是__6____.
int fun(unsigned int x) { int n = 0; while (x&255) { n++; x = x&(x - 1); } return n; }
37.
#include <stdio.h>
main()
{
FILE *fp;
int i, a[4] = { 1, 2, 3, 4 }, b;
fp = fopen("data.dat", "wb");//以二进制写的形式打开这个文件并给fp赋值,如果文件没有就创建,如果有,就清空
for (i = 0; i < 4;i++)
{
fwrite(&a[i], sizeof(int), 1, fp);//从这里帮忙解释一下
将a[i] 写入fp指向的文件流,每次写sizeof(int)个字节,写一次
}
fclose(fp); //文件中是 1,2,3,4
fp = fopen("data.dat", "rb");
fseek(fp, -2L * sizeof(int), SEEK_END);//从这里帮忙解释一下
将fp指向的文件流 从文件末尾向文件头跳转2L*sizeof(int)个位置 倒数第二个位置
fread(&b, sizeof(int), 1, fp);//从这里帮忙解释一下
将fp指向的文件流里读取一次,每次读取sizeof(int) 个字节 写入文件b
fclose(fp);
printf("b = %d\n", b);
}
答:____3________
38.程序的局部变量存在于__栈区___中,全局变量存在于__全局区中,动态申请数据存在于__堆区__中。
39.若一个视频中图像分辨率为1920 * 1080,每像素采样精度为16 - bit,每秒25帧图像,则每秒图像占内存______byte 25x2x1920x1080
(所有数据连续存放)。
40.请写出”得到两参数中较小值“的宏:
#define MIN(a,b)__((a)<(b) ? (a): (b))______
41.请写出”判断是否为2的幂次“的宏:
#define IS_POWER_OF_2(a)__________
(a)&&(((a)&((a)-1))==0)
42.int16_t x = 32767; x++; printf("%d", x);
输出的结果为__-32768_____
43.a = 1; a += ++(a++);此时a的值为多少。
a++返回值为常量 ++返回值 非法 不能通过编译
44.count_ones是计算非零整数x的二进制表示下,有多少个bit是1.例如:10 = (1010)2,则返回2,填写空行。
int count_ones(unsigned int x) { assert(x > 0); int ones = 1; while (______x = x_&____________________)ones++; return ones; }