C语言数据类型

数据类型

总览图

C语言数据类型

作用

数据类型,也即变量类型,定义了变量所占内存空间规模大小的一个单位模板,它能够方便地让开发者对数据进行定位处理。

本质

数据类型的本质为一段内存地址的别名,表示为变量的起始内存地址+偏移量(数据长度)。

表示方式

基本数据类型:

short、int、long、char、float、double

自定义类型:

typedfe 关键字定义

#define宏定义

typedef char* PCHAR;//typedef用法
#define PINT int*//#define用法
int main()
{
    PCHAR p1,p2;
    char c1='1',c2='2';
    PINT p3,p4;//宏替换后代码为int*p3,p4;而定义两个指针的方式为int*p3,*p4;
    int n1=1,n2=2;
    p1=&c1;//p1为PCHAR类型 即char*
    p2=&c2;//p2为PCHAR类型 即char*
    p3=&n1;//p3为int* 类型 n1为int
    p4=&n2;//p4为int 类型 n2为int 提示警告int与int*的间接级别不同
    return 0;
}
//#define只是替换、无别名概念

enum

//定义一系列的常量,常与switch搭配使用
enum Color
{
    red=0,//默认是从0开始
    yellow,//后一值为前一值+1
    blue
}

struct结构体

#include<stdio.h>
struct Goods
{
	int price;
	int id;
	char name[20];
	char illustrate[20];
	char madeof[20];
};
struct SoftArray
{
	int len;
	int array[];//占位符 不占用内存大小
};
int main()
{
	struct Goods item;
	item.price = 100;
	item.id = 1;
	//item.name="红糖水";
	//字符串是存储在常量区的,也即"红糖水"实际上代表的是一个指向常量区的指针
	//数组名是一个指针常量,不可修改的它的指向,对于字符串应采取库函数
	strcpy(item.name, "红糖水");
	//====================柔性数组=====================================
	int len = 0;
	printf("请输入数组大小");
	scanf("%d", &len);
	struct SoftArray *sa = malloc(sizeof(struct SoftArray) + sizeof(int)*len);
	sa->array[0] = 'q';
	sa->array[1] = 'd';
	sa->array[2] = '0';
	printf("sa:%p,&sa->len:%p,sa->array:%p,sa->array:%s,sizeof(struct SoftArray):%d", sa, &sa->len, sa->array, sa->array, sizeof(struct SoftArray));
	//输入20
    	//输出sa:00857F30,&sa->len:00857F30,sa->array:00857F34,sa->array:q,sizeof(struct SoftArray):4
	free(sa);
	sa = NULL;//是为了误用空指针sa的时候触发空指针异常,否则误用sa的未定义行为是很难调试的
	return 0;
}

union联合体定义

大小端

小端存储,低地址存低位,高地址存高位;大端存储,低地址存高位,高地址存低位。

union Undemo
{
	int num;
	char c;
};
int main()
{

	union Undemo demo;
	demo.num = 10;
	if (demo.c == 1)
	{
		//小端机器
	}
	printf("%d", demo.c);//输出10
	return 0;
}

使用方式

格式:

数据类型 变量名字;

属性:

即变量存储类型,添加在变量名以及变量类型之前,旨在说明该变量的属性,即作用范围,包含cuto、static、register。

auto

在c语言中,局部变量定义的时候编译器会在变量类型前默认添加auto,以此说明定义了一个分配在栈区的局部变量,开发者在定义变量时可省略该关键字,在c11中auto已被废弃。

注意:非C++11的cuto。

//auto int a=0;//全局变量不可使用auto,编译提示有坏的存储类
int main()
{
     auto int b=0;
     int c=0;//同b的定义       
     return 0;
}

static

修饰局部变量:

定义静态局部变量,在静态存储区分配内存空间,改变变量的存储方式,控制变量的生命周期和作用域,并且只会初始化一次。

 void func1()
 {
      static int a=0;
      printf("%d,a++);//输出12345
 }
 void func2()
 {
      int a=0;
      printf("%d,a++);//输出11111
}
int main()
{
     for(int i=0;i<5;i++)
     {
          fun1();
     }
     //i=100;
     //编译报错,i在作用域外不可访问
   //但i的栈未销毁,内存还在,在其作用域外,i的栈可能被用作它用
     for(int i=0;i<5;i++)
     {
         fun2();
     }
     return 0;
}

修饰全局变量和函数:

限制其作用域为本文件。

//test1.cpp
statiic int a=0;
int b=0;
void func1()
{
     printf("%d",a);
}
static void func2()
{
     printf("%d",b);
}
//test2.cpp
extern int a;
extern int b;
int main()
{
     printf("%d",a);
     //printf("%d",b);//编译出错,提示无法解析的外部符号
     fun1();//输出a的值0
     //fun2();//同上,编译出错,提示无法解析的外部符号
     return 0;
}

register

定义寄存器变量,变量存储于寄存器中,因为数据在寄存器中的读取速度会高于内存,可用于提高程序的执行速度。

注意:变量的值必须是单个寄存器能够接受的值,并且仅仅是发送请求,由编译器判断是否采取将其放弃寄存器。不可以对其取地址&,因为不存在地址。

//register int nmb;//编译报错有坏的存储类
//register 不可定义全局变量
int main()
{
    register int num=0;
    //int* p = &num;//CPU当中变量时没有地址
    do
    {}while(num++!=9999999);
    return 0;
}

隐含属性

生命周期:

变量的地址存在的有效时间。

作用域:

对代码进行语法层面的隔离,避免重定义等,一般采取{...}进行定义。

void

//void* 提供一种数据抽象的能力 代表的是一个地址 指向一块未知存储数据类型和大小的内存 
//可用于接受任何的指针类型,void*执行的是降级操作
void swap(void* p1,void* p2,size_ size)
{
    void *ptemp= malloc(size);
    memcpy(ptemp,p1);
    memcpy(p1,p2);
    memcpy(p2,ptemp);
    free(ptemp);
}
void func(void)//void代表无,一般作为返回值和参数
{
    //函数体
}
int main()
{
    //void a;void 无法定义变量 代表的是空 
    int n1=1,n2=2;
    swap(&n1,&n2,sizeof(int));
    return 0;
}
    

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值