c语言数据类型

默认数据类型是整数数据类型

  • 计算时整数是最小的数据类型,即使对更小的数据类型进行相加时, 这些数据类型首先会扩展到整数数据类型

初始化变量

用以下方法可以初始化变量:

  • int zahl = 100;
  • int zahl(100); // c++

在定义全局变量或局部静态变量时必须用常量或字面量赋值。

  • int zahl = 100 + 10 * 3 //正确
  • int zahl = strlen(str1) // 报错

全局变量或局部静态变量在没有赋初始值是会自动赋值为0
局部变量没有被初始化时,其内容取决于先前对堆栈上分配的内存位置的使用情况。

整数数据类型

数据类型所占比特(64位系统)
char8
short/ short int16
int32
long/ long int32/64
long long int64

浮点数

数据类型所占字节
float4
double8
long double10

数据的比较与计算

数据比较或计算时两个数据必须是相同的数据类型,否则将作以下处理:

  • 隐式转化
  • 显式转化

类型的隐式转化

一般来说:隐式转化规则的设置方式是,一个数据类型总是被转换为另一个具有 "更大 "数值范围的数据类型,这样就可以尽可能地减少数据损失。
规则如下:

  • 浮点数第一

    • 如果一个操作数是长双的类型,那么另一个操作数将被转换为长双。
    • 如果一个操作数是双数类型,那么另一个操作数将被转换为双数。
    • 否则,如果一个操作数是float类型,那么另一个操作数将被转换为float。
  • 如果不涉及浮点类型,适用一下规则。无符号数的权重比有符号数高。

    • 如果一个操作数是无符号长类型,那么另一个操作数将被转换为无符号长。
      (注意:如果要转换的数据类型是有符号的long类型,可能会有数据丢失。)

    • if一个操作数是long类型,另一个是无符号int类型,那么如果long可以表示无符号int的所有值(64位到32位),无符号int操作数被转换为long;否则,两个操作数被转换为无符号long(32位到32位)。

    • else if一个操作数是长类型,那么另一个操作数将被转换为长。

    • else if 一个操作数是无符号int类型,那么另一个操作数将被转换为无符号int。

  • 对于指针、指向数组的指针、指向函数的指针,没有隐含的规则

Struct Types

语法:struct [Strukturname] {Datentyp Variablenname; …} [Variablenliste];

定义结构体的不同方式:

  1. 只带结构体名字的定义:
	struct xyz {int x; int y,z;};
	struct xyz   var1;
	var1.x=7;
	//使用结构体定义实例时前面必须带上struct.
	struct xyz {int x,y,z;};
	// 实例的名字可以与结构体的名字相同。
	struct xyz xyz;
	xyz var2;        //KO
  1. 只带变量列表的定义:
    也被称为匿名定义,用这种方式定义的结构体只能够使用结构体后定义好的变量,后面不能够再自己定义该结构体的实例
struct {int x,y,z;} xyz,arr[3],*ptr=&xyz;
	xyz.x=1;   arr[1].y=2;       ptr->x=7;
  1. 即有结构体名字又有变量列表:
    用户既可以使用已经定义好的变量,也可以在后续自己再定义实例

结构体元素的使用

  • 对于变量:‘.’
  • 对于指针:’->’
struct xyz {int x,y,z;};
	struct abc {
		int a,b,c;
		struct xyz xyz;
		struct  {char str[10];} strstr;
		struct xyz *ptr;
	}var1;
	var1.a     var1.b     var1.c
	var1.xyz.x
	var1.strstr.str[0]
	var1.ptr = &var1.xyz;   var1.ptr->x;

初始化结构体

初始化元素通过{}书写。在括号内既可以按顺序初始化值也可以使用’.'操作符

struct dummy{int a,b,c; char str[10];};
struct dummy var1 = {1,2,3,"hallo"};
struct dummy var2 = { .b=3;};   // Rest wird mit 0 initialisiert   //gibt’s nicht bei C++!
struct dummy var1 = {.a=strlen(var1.str);};   //var1.a = 0

结构体的内部原理

编译器为结构体保留相应数据结构大小的储存空间

	struct {int x,y,z;} var1;   //Speicherplatz = 4+4+4 = 12 Byte
	sizeof(var1)                //12

变量名称对应于结构中第一个元素的指针(对应于一个数组)。因此,结构体内部的元素应被视为基址的偏移运算符。 因此,变量var1中的元素y通过变量的地址(例如地址0x100)加上元素y的偏移量(这里是4,因为第一个结构元素占用了0…3的偏移量)来寻址。

offsetof操作符

语法:offsetof(a,b)-> 给出结构体成员b在结构体a中的偏移量
该操作符在stddef.h头文件中

struct xyz {int a,b,c;} var1;
offsetof(var1,c)         //报错,第一个参数应当是结构体的名字而不是实例
offsetof(struct xyz,c)   //8

结构体的比较

通过比较别的变量的方式来比较结构体是错误的

struct xyz {int x,y,h} var1,var2;		
if(var1 == var2)   //报错

结构体的比较应当是这样:

if(var1.x == var2.x && var1.y == var2.y …)
if(memcmp(&var1,&var2,sizeof(var1) == 0)

int memcmp (const void *s1, const void *s2, size_t n)

  • memcmp()用来比较s1 和s2 所指的内存区间前n 个字符。
  • 字符串大小的比较是以ASCII 码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1 第一个字符值减去s2 第一个字符的值,若差为0 则再继续比较下个字符,若差值不为0 则将差值返回。例如,字符串"Ac"和"ba"比较则会返回字符’A’(65)和’b’(98)的差值(-33)。
  • 返回值:若参数s1 和s2 所指的内存内容都完全相同则返回0 值。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值。

结构体显示转化

不可以将一个普通的变量显示转化为结构体

typedef

用于生成一种数据类型的别名
语法:typedef datentyp alias[,alias][,*alias];

typedef unsigned int  uint32_t;
typedef unsigned int UINT1,UINT2,*PINT;
UINT1 var1;
PINT1 ptr1;
struct test {int a,b,c;};
typedef struct test test_t1;
typedef struct {int a,b,c;}  test_t2;    //Anonyme Deklaration von Struct ist ausreichend
typedef struct xyz {struct xyz *next;} test_t3;
typedef enum {STATUS_OK, STATUS_KO} STATUS;
STATUS func() {return STATUS_OK; return 0; return drei;}

union

union中,所有的组件并不像struct那样从连续的内存地址开始,而是从相同的内存地址开始,也就是说,它们的内存区域完全或至少部分地重叠。因此,union只能包含一个元素。一个联盟所占的内存与它最大的组成部分一样多

语法:Syntax: union 共用体名 {
成员列表
} [Variablenliste];

定义union的不同方式

  1. 只带联合体名字的定义:
union data{
    int n;
    char ch;
    double f;
};
union data a, b, c;
  1. 只带变量列表的定义:
    也被称为匿名定义,用这种方式定义的联合体只能够使用结构体后定义好的变量,后面不能够再自己定义该联合体的实例
union{
    int n;
    char ch;
    double f;
} a, b, c;
  1. 即有结构体名字又有变量列表:
    用户既可以使用已经定义好的变量,也可以在后续自己再定义实例
union data{
    int n;
    char ch;
    double f;
} a, b, c;

应用

#include <stdio.h>
union data{
    int n;
    char ch;
    short m;
};
int main(){
    union data a;
    printf("%d, %d\n", sizeof(a), sizeof(union data) );
    a.n = 0x40;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.ch = '9';
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.m = 0x2059;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.n = 0x3E25AD54;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
   
    return 0;
}

运行结果:

4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

在这里插入图片描述

enum

语法:enum [enumation-name] {definition-list[=expression]} [Variablenliste] ;

不同的定义方式

前三种方式与struct与union类似,但是enum类型的匿名定义方式也是有意义的

enum {HALLO,WELT};
int var1=HALLO,var2=WELT;
// var1 = 0, var2 = 1

在定义是使用计算也是可以的

{bill=10, john=bill+2, fred=john+1}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值