1、用变量a给出下面定义
(1)一个整型数
(2)一个指向整型数的指针
(3)一个指向指针的指针,它指向的指针时指向一个整型数的指针
(4)一个有10个整型数的数组
(5)一个有10个指针的数组,这10个指针是指向整型数的
(6)一个指向有10个整型数数组的指针
(7)一个指向函数的指针,该函数有一个整型参数并返回一个整型数
(8)一个有10个指针的数组,这10个指针均指向函数,该函数有各异整型参数并返回一个整型数
解析:
(1)一个整型数 : int a;
(2)一个指向整型数的指针 : int *a;
(3)一个指向指针的指针,它指向的指针时指向一个整型数的指针 : int **a;
(4)一个有10个整型数的数组 : int a[10];
(5)一个有10个指针的数组,这10个指针是指向整型数的 : int *a[10];
(6)一个指向有10个整型数数组的指针 : int (*a)[10];
(7)一个指向函数的指针,该函数有一个整型参数并返回一个整型数 : int (*a)(int);
(8)一个有10个指针的数组,这10个指针均指向函数,该函数有各异整型参数并返回一个整型数 : int (*a[10])(int);
2、下面代码输出什么?为什么
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a + b > 6) ? printf(">6") : printf("<=6");
}
解析:
输出 >6。
因为a是无符号整型,b是有符号整型,两者运算会强制将b转换成无符号整型,此时b变成一个很大的数,所以是>6。
3、写出float x 与 “零值”比较的if语句
解析:
if(x < 0.0001 && x < - 0.0001)
4、下面代码有什么错误?
#include <stdio.h>
void main()
{
char *s = "AAA";
s[0] = 'B';
printf("%s",s);
}
解析:
"AAA"是字符串常量,不可以对其进行修改。
建议将其重新声明为:const char *s = “AAA”;
s[0] = 'B’是不合法的。
5、下面代码输出是什么?
#include <stdio.h>
void main()
{
int *a = (int *)2;
printf("%d",a + 3);
}
解析:
输出14
因为(int *)2是将地址2赋给指针a,而a是整型指针,所以a + 3 = 2 + (3 * 4)= 14。
6、下面代码运行后会出现什么现象?
#include <stdio.h>
#define N 500
void main()
{
unsigned char count;
for(count = 0; count < N; count++)
{
printf("--%d--\n",count);
}
}
解析:
会出现死循环。
因为unsgned char count的范围是 0 ~ 255,所以永远无法结束循环。
7、下面函数的返回值是什么?
int foo(void)
{
int i;
char c = 0x80;
i = c;
if(i > 0) return 1;
return 2;
}
解析:
返回2
因为0x80 = 128,而char c的取值范围是 - 128 ~ 127,所以c = -128,所以输出2。
8、结构体内存对齐原则?
解析:
以32位系统位例,CPU按一次4个字节进行处理。按照4字节进行补齐,如下:
情况1:
struct abc
{
char a;//1字节
short b;//2字节
int c;//4字节
double d;//8字节
};
因为 a 和 b 字节数加起来小于4,所以两个被一起读取。一共是 4 + 4 + 8 = 16字节。
情况2:
struct abc
{
char a;//1字节
int c;//4字节
short b;//2字节
double d;//8字节
};
因为 a 和 c 字节加起来大于4字节,所以分开读取,一共是 4 + 4 + 4 + 8 = 20字节。
9、结构体内存对齐的原因?
解析:
编译器为了提高运行速度而牺牲内存的一种做法。
10、给定结构体,它在内存中占用多少字节(32位编译器)?
struct A
{
char t : 4;
char k : 4;
unsigned short i : 8;
unsigned long m;
}
解析:
8个字节,t 占一个字节,k占一个字节,i 占两个字节,刚好4个字节,unsigned long 占4个字节,所以一共是8字节。
11、在32位系统中,有以下结构体,sizeof(fun)的数值是?
#pragma pack(1)
struct fun
{
int i;
double d;
char c;
};
解析:因为设定为一个字节一个字节读取,所以一共是4 + 8 + 1 = 13字节。
12、数组首元素地址和数组地址的异同?
解析:
不同点:数组首地址和数组地址是两个不同概念,数组地址 + 1是将所有数组内存全部跳过,偏移到整个数组的下一个字节,而首地址 + 1则是便宜到第二个数组元素。
相同点:首地址和数组地址是相同的。
13、下面代码输出什么?
#include <stdio.h>
void main()
{
int a[5] = {1,2,3,4,5};
int *ptr = (int *)(&a + 1);
printf("%d,%d",*(a + 1),*(ptr - 1));
}
解析:
输出2,5。
因为*
(a + 1)表示偏移到了数组中第二个元素,即为2。
而(&a + 1)表示偏移到了数组下一个字节,而*
(ptr - 1)则是偏移到了a[4],所以等于5。
14、判断下列表达式正确与否?
char str[2][3] = {"a","b"};
char str[2][3] = {{1,2},{3,4},{5,6}};
char str[] = {"a","b"};
char str[2] = {"a","b"};
解析:
char str[2][3] = {“a”,“b”}; 正确
char str[2][3] = {{1,2},{3,4},{5,6}}; 错误,因为数组是2行3列而不是3行2列。
char str[] = {“a”,“b”}; 错误,char类型数组不能放字符串。
char str[2] = {“a”,“b”}; 错误,char类型数组不能放字符串。
15、查看下面代码,p[6]等于几?
int a[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = &a[1];
解析:
8,因为p指向的是a[1],向后偏移6个指向8。
16、下面代码输出的结果是什么?
#include <stdio.h>
void main()
{
char *str[] = {"ab","cd","ef","gh","ij","kl"};
char *t;
t = (str + 4)[-1];
printf("%s",t);
}
解析:
gh,(str + 4) 指向"ij",而[-1]则是指回gh。
17、变长数组是什么?
解析:
定义数组时不规定其大小。
18、bool类型包含在哪个头文件?
解析:
stdbool.h
19、结构体和联合体的区别?
解析:
结构体:结构体中成员连接在一起,遵循字节对齐原理。
联合体:大小由成员最大的决定,共用首地址。
20、给定一个地址a,分别强制转换类型:int 变量、int指针、数组指针、指针数组、函数指针。
解析:
(int)a;
(int *) a;
(int (*)[])a;
(int *[])a;
(int (*)(int))a;
21、执行完下面代码,c的值是多少?
unsigned int a = 1;
int b = 0;
int c = 0;
c = a + b > 0 ? 1 : 2;
解析:
c = 1,b转换成无符号整型为0,c = 1。
22、C语言中不同数据类型之间的赋值规则?
1、整型和浮点型 :将整型转换成浮点型后运算。
2、长整型和短整型:将短整型转换成长整型后运算。
3、长浮点型和短浮点型:将短浮点型转换成长浮点型后运算。
4、有符号和无符号:将有符号转换成无符号后运算。