c语言的400多个问题(部分)

本文探讨了C语言编程中的各种技巧与常见陷阱,包括数据类型取值范围、全局变量和函数的最佳定义与声明方法、函数指针的复杂声明、结构体的正确使用等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.int型取值范围:-2147483648 ~ +2147483647 (4 Bytes)


2.64位机上的64位,可以实现16位短整形,32位整形,64位长整形


3.怎样定义和声明全局变量和函数最好?
尽管一个全局变量可以多次声明,但是定义只能一次,所以最好在相关.c文件中定义,然后再头文件中声明。
不要把外部函数的原型放到.c文件中,容易检查出错。

4.extern在函数声明中的意思。
extern是表明函数和全局变量作用范围的关键字。它声明的函数可以在本模块或其他模块中使用。
extern int a;
这是变量的声明,不是定义。所有全局变量只能定义1次。

5.关键字auto是什么用途。
auto用来声明自动变量。大多数声明方式声明的变量都是auto变量。auto变量在离开作用域会变程序自动释放。
不会造成内存溢出。

6.typedef struct
  {
char *item;
NODEPTR next;
  }*NODEPTR;
  编译器报错。
  结构体可以包含指向自己的指针,报错是因为,声明next域时typedf还没有定义。
  修改后的版本:
  typedef struct
  {
char *item;
struct node *next;
  }
  typedef struct node *NODEPTR;
  
7.如何建立和理解非常复杂的声明?定义一个包含N个指向返回指向字符的指针的函数的指针的数组。
1.char *(*(*a(N)()))
2.使用typedef逐步声明
typedef car *pc; //字符指针
typedef pc fpc();//返回字符指针的函数
typedef fpc *pfpc;//上面函数的指针
typedef pfpc fpfpc();//返回函数指针的函数
typedef fpfpc *pfpfpc;//上面函数的指针
typedef a[N];//上面指针的数组
3.使用cdecl程序,将英文翻译成c代码

8.函数定义了一次,调用了一次,但是提示非法定义。
1.可能该函数与某个头文件中声明的另一个函数重名。
2.没有声明就调用
3.函数在后面声明或定义成其他类型。

9.main函数的正确定义格式
1.int main(int argc, char *argv[])
有参数格式
2.int main(void)
无参数格式
3.int main()
不符合c99标准

10.对于没有初始化的变量有什么假定?如果一个全局变量初始值为0,可否作为空指针或浮点0?
1.具有静态生存期的变量,可以确保初始值为0;(静态生存期就相当于程序运行期)
 如果变量为指针就会初始化为空指针,浮点数会初始化为0.0
2.具有自动生存期的变量,如果没有初始化,则会包含垃圾内容。
3.使用malloc()动态分配的内存可能包含垃圾文件,用calloc()获得的内存为0,但对指针或浮点数不一定有用。

11.int f()
   {
char a[] = "hello!";
   }
无法编译。
可能是编译器过旧,不支持“自动聚集”的初始化。
自动聚集(非静态局部数组,结构和联合);

12.char *p = malloc(10);显示非法初始化。
这个申明是否为静态或非局部变量
注:使用malloc()结束后要free,不然会造成泄漏。
malloc是在堆上分配内存。

13.char a[]与char *pc
用作数组初始值,他指明该数组中字符的初始值。其他情况,他会转化成一个无名的静态字符数组,可能会存在只读内存中,
这就使得不一定能更改。

14.函数指针的初始化方法
extern int func();
int (*fp)() = func;

15.struct x1{...}与typedef struct {...}x2有什么不同?
第一种是个结构标签,第二种是个结构定义。
第二种引用时不需要加struct.

16.struct x {...};
x thestruct;
为什么不对?
c中结构标签不能自动生成类型。

17.c语言中实现抽象数据类型的方法。
使用没有公开定义的结构类型的指针。

18.c中有没有类似于c++中继承的方法。
可以将函数指针加入到结构体中,这样就行了。

19.struct name {int namelen;char namestr[1];};然后使用一些内存分配技巧,这样合法可移植吗?
可以的。还有种方法是namestr[MAX],通常将MAX设置的很大,但是这样不严谨。
c99引入“灵活数组域”,允许结构的最后一个域省略大小。

20.没有自动比较结构体的方法。按照字节比较,结构体中会有空洞,按域比较,重复代码太多。


21.如何向接受结构的参数传入常数值?
只能使用临时结构变量或一个小的结构生成函数。

22.如何从/向 数据文件 读/写结构?
使用fwrite()
fwrit(&somestruct,sizeof(somestruct),1,fp);
fread()调用将它读回来。这样写出的文件无法移植。
移植性好的方法是写一对函数,再用可移植的方法按域读写结构。

23.编译器在结构中留下空洞,是为了保持结构中后面的域的对齐。有些处理器喜欢多字节对象不能处于随意的内存地址,必须是2,4或对象的大小倍数。


24.为了确保分配连续的结构数组时正确对齐,可能有尾部填充,及时结构不是数组成员,填充也会保持,以便sizeof能够总是返回一致的大小。


25.<stddef.h>中的offsetof()宏可以计算出域f的偏移量


26.如何在运行时用名字访问结构中的域?
用offsetof()计算域偏移量。如果structp是个结构实体的指针,而域f是个整数,他的偏移量是offsetf,f的值可以间接的设置:
*(int *) ((char *)structp + offsetf) = value;

27.结构体程序运行出错时,要多注意是否少了分号。


28.枚举和一组预处理的#define的区别很小,c中允许枚举和其他整形类别自由混用。
枚举的优点:
1.自动赋值
2.调试器在检验枚举变量时,可以显示符号值
3.服从数据块作用域规则

29.可以写一个小函数来显示枚举值符号


30.a[i] = i++;无法工作,是因为i++改变了i的值,i在同一表达式的其他地方被引用。
会导致无意义的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值