C05_声明和初始化

基本类型

1. 我该如何决定使用哪种数据类型?
  1. 如果可能用到很大的数值(大于32767或者小于-32767),就使用long类型.否则,如果空间很重要(例如有很大的数组或者很多的结构),就使用short类型.其他的情况就用int类型.
  2. 尽管字符类型(尤其是无符号的 unsigned char类型)可以当成小整数使用,但是尽量不要这么用.编译器需要生成额外的代码来进行char和int类型之间的转换.
  3. 决定使用float类型还是double类型的时候,也要有类似的空间/时间权衡.(很多编译器在表达式求值的时候仍然把所有的float类型转换为double类型进行运算).但是如果一个变量的地址确定切必须为特定的类型的时候,就不会再进行强制的转换.
2.C语言类型大小没有精确的定义,只能确保如下几点
  1. char类型可以存放小于等于127的值
  2. short intint 可以存放小于等于32767的值
  3. long int可以存放小于等于2147483647的值
  4. char至少有8位,short intint至少有16位,而long int至少有32位,long long 至少有64位

指针声明

1. 指针声明有什么问题?

char *p1,p2;

声明的本身没有问题,但是p2不是一个指针.指针声明中的*号不是基本类型的一部分,它只是包含被声明标识符的声明符的一部分.声明的语法和解释并非

类型 标识符
而是
基本类型 生成基本类型的东西

其中生成基本类型的东西-声明符-或者是一个简单的标识符,例如*p a[10] f()这样的符号,表明被声明的变量是指向基本类型的指针,基本类型的数组或者返回基本类型的含糊.

所以以上的声明,基本的类型都是char,只是第一个是指针,第二个是基本类型char,而非指针.
正确的声明是这样的

char *p1, *p2

2. 声明指针,并且分配空间

char *p;
*p = malloc(10);

注意声明的指针是p而不是*p

3. 怎么样声明和定义全局变量和函数最好?
  1. 尽管一个全局变量或者函数可以(在多个编译单元中)有多处声明,但是定义却最多允许出现一次.对于全局变量,定义是真正分配空间并赋初始的声明.对于函数,定义是提供函数体的声明.
  2. 这些是声明 extern int i,extern int f(), 这些是定义: int i = 0 int f() { return 1;}
  3. 函数的声明中,extern是可选的.
  4. 当希望多个源文件中共享变量或者函数的时候,需要确保定义和声明的一致性.最好的安排是在某个相关的.c文件中定义,然后在头文件.h中进行外部声明,在需要的时候,只要包含对应的头文件即可.定义变量的.c文件也应该包含该头文件
  5. 永远不要把外部函数的原型放到.c文件中.如果函数的定义发生了改变,很容易忘记修改原型,而错误的原型贻害无穷

存储类型和类型定义

1. extern在函数的声明中是什么意思?

存储类型extern只对数据声明有意义.对于函数声明,它可以用作一种格式上的提示,表示这个函数的定义可能在另一个源文件中.本质上并没有任何的区别

2. typedef 和 #define有什么区别?

一般来说,最好使用typedef,它能正确的处理指针类型.

#include <stdio.h>
typedef char *String_t;
#define String_d char * 


int main()
{
    String_t s1,s2; // 这里的s1 和 s2都是指针类型. 因为String_t代表的是一种char*类型
    String_d s3,s4; // 这里的String_d 只是字符串的替换,等价于 char * s3,s4. s3是char*类型,
    //而s4是char类型
    return 0;
}

主要区别如下

  1. 原理不同 #define是C语言中的定义的语法,是预处理指令,在预处理进行简单的机械的字符串的替换,不作正确性检查.typedef是关键字,在编译时处理,有类型检查的功能.它在自己的作用域内给一个已经存在的类型的一个别名,但不能再一个函数定义里面使用typedef.
  2. 功能不同 typedef是用来定义类型的别名,祈祷类型易于记忆的功能.另一个功能是定义机器无关的类型.如定义一个REAL的浮点类型,在目标机器上它可以获得最高的精度 typedef long double REAL.在不支持long double的机器上,看起来是这样的,typedef double REAL,在不支持double的机器上,是这样的 typedef float REAL #define 不只是可以为类型取别名,还可以定义常量,变量,编译开关等
  3. 作用域不同 #define么有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,而typedef有自己的作用域

结构体的定义

1. 什么是结构体
  1. 结构体是多种类型的数据的集合
  2. 结构体是一种由用户自定义的特殊的复合型的数据类型
  3. 结构体就像一个模板,结构体存放的东西在内存上整体上是连续的,但是因为有对齐的需要,所以实际上成员变量之间存在裂缝.
2. 结构体的声明
#include <stdio.h>
struct stu
{
    char *name; // 姓名
    int num; // 学号
    int age; // 年龄
    char group; // 所在
    float score;
};


int main()
{
    stu s1,s2;
    return 0;
}

3. 定义链表的时候,结构体指向自己的问题
typedef struct {
	char *item;
	NODEPTR next;
} *	NODEPRT;


在C语言中的结构当然可以包含指向自己的指针.
这里的问题是typedef,typedef定义了一个新的类型名称.但是不能再定义typedef类型以前使用它.
在上面的代码中,在next域声明的地方还没有定义NODEPTR.

要解决这个问题,首先赋予这个结构一个标签(‘struct node’),然后声明next域为struct node *,或者分开typedef声明和结构定义.

修正后版本

typedef struct node{
	char *item;
	struct node *next;
} *NODEPTR;

也可以在声明结构之前先用typedef,然后就可以在声明next域的时候使用类型定义NODEPTR了

struct node;
typedef struct node *NODEPTR;
struct node {
	char *item;
	NODEPTR next;
};

两种风格都使用的版本

struct node{
	char *item;
	struct node *next;
};
typedef struct node *NODEPTR;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值