C语言的数据类型及其对应变量
声明,定义和初始化
声明标识符iden是告诉编译器"有这么一个变量var,具体var里是什么,你自己去看"。声明只需要标识符的类型和标识符名字,C语言的任何标识符在使用前都需要声明,当然变量也不例外;如果标识符的定义代码在使用之前,那么定义的代码可以看作是声明,否则需要声明
定义标识符iden是告诉编译器"这个iden是什么";
初始化标识符iden是定义iden时给iden赋值,一个没有被赋值的iden里面存的是之前这块内存的值,就可能是任意的值,一不小心使用这样的标识符是十分危险的,所以一个好的习惯是定义一个标识符后立即初始化;另外一个原因是常量的值必须在初始化时确定,如果不进行初始化,那么这个常量以后永远都不能赋值了
通常情况下,当我们写int atom=10;时,就同时进行了变量的定义和初始化。
指针
- 内存就是一排大小都是一byte,且自己编号的抽屉。编号即抽屉的地址,里面的东西即抽屉的内容
- 指针即"地址"。即抽屉的编号
- 指针变量即存储"标识符地址"的变量,即存放了另一个抽屉编号的抽屉,对指针变量"取值"即得到标识符的地址,即"指针的指向",对该变量"取址"即该变量本身存放的地址。当提及指针的时候,一定要注意说的是一个指针常量(一个地址), 还是一个指针变量,这是国内的教材非常差劲的一个习惯
- 一个指针变量理论上可以存储任何标识符的地址,但是为了便于管理,C语言把指针变量也按照标识符的类型进行了划分。所以有了函数的指针,字符指针,数组指针etc. 但他们其实都一样,即虽然所有的抽屉的编号都是一张纸条,但某个抽屉只用来存储装了苹果的抽屉的编号,另一个抽屉只用来存储装了橘子的抽屉的编号。
定义并初始化一个指针变量,由于运算符优先级的问题,并没有固定的定义格式,基本上每种不同的标识符都有自己的指针定义格式
int* pVar=&var; //数据类型指针变量
char (*ptr)[3]={'a','b','c'}; //数组指针变量,本质是指针,指向一个数组 VS char* str[10]={"this","is","a","string"};指针数组,本质是数组,每个元素都是一个指针
int (*pFcn)(int x)=fcn; //函数指针变量,指向一个函数的地址,函数名就是一个指针
使用指针
int var2=*pVar;//取值
int** ppVar=*pVar;//取址,这里定义一个指向指针的指针变量
指针常量VS常量指针
指针常量const int* ptr表示不能通过指针修改指向的变量的内容
常量指针int* const ptr表示指针的指向不能改变。
基本数据类型char int etc.
基本数据类型是C语言规定好的数据类型,它们占据内存的大小,对该块内存的使用方式都是编译器规定好的,我们只能使用,不能更改。
在一个典型的32位操作系统中:
| 数据类型 | 占位符 | 长度 | 数值范围(指数表示) | 数值范围(数字表示) |
|---|---|---|---|---|
| char | %c | 1 | -27~27-1 | -128~127 |
| unsigned char | %c | 1 | 0~2^8-1 | 0~255 |
| short | %hd | 2 | -215~215-1 | -32768~32767 |
| unsigned short | %hu | 2 | 0~2^16-1 | 0~65535 |
| int | %d | 4 | -231~231-1 | -2147483648~2147483647 |
| unsigned int | %u | 4 | 0~2^32-1 | 0~4294967295 |
| long | %ld | 4 | -231~231-1 | -2147483648~2147483647 |
| unsigned long | %lu | 4 | 0~2^32-1 | 0~4294967295 |
| float | %f或%g | 4 | ||
| double | %lf或%lg | 8 |
Note:
- %f和%lf会保留小数点后多余的0(就算你写的5.2,也会输出5.200000),而%g和%lg不会保留哪些0
- 不同平台(eg:32位VS64位系统)数据类型的长度会有不同,具体需要用sizeof测,上表针对一般32位系统,以int为例,一个int占4byte,一个byte占8位,所以一个int由32位二进制表示,故int共能表示2^32个数
- float和double的范围是由指数的位数来决定的。float的指数位有8位,而double的指数位有11位,分布如下:
float: 1bit(符号位) 8bits(指数位) 23bits(尾数位)
double: 1bit(符号位) 11bits(指数位) 52bits(尾数位)
So,float的指数范围为-127+128,而double的指数范围为-1023+1024,并且指数位是按补码的形式来划分的。其中负指数决定了浮点数所能表达的绝对值最小的非零数;而正指数决定了浮点数所能表达的绝对值最大的数,也即决定了浮点数的取值范围。
float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;
double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308 - 有符号的数据类型不是分“正数” 和 “负数”,而是 “非负数” 和 “负数”,其中的区别在于 0 是非负数里的,所以,只需要记住有多少个和有无符号就可以计算其范围
基本数据类型与指针
int var=10;
int* pVar = &var; //定义并声明一个指向int类型变量的一个指针,并将其指向var
int res=*pVar; //对一个指针取值
int* pTest=pVar;
字符串
C语言中的字符串用"有效字符"来表示。
C编译器会自动在有效字符之后再加一个\0(即ASCII的数字0)表示字符串的结束,所以一个字符串实际占用的byte数目是"有效字符数+1","Tom"!='T''o''m',前者是字符串,有'\0'结尾,占4byte,后者不是"字符串",而是"一串字符",没有'\0'结尾,占3byte。 有两种方式测试字符串的长度:sizeof和strlen()
定义一个字符串常量
char* str="this is a string";
定义一个字符串数组
char str[]="this is a string";
字符串与指针
当我们定义一个字符串常量的时候,C编译器其实干了三件事,1.找一块内存,把这个字符串的有效值放进去,2.字符串的结尾加一个'\0',3.把这个字符串的首地址放在标识符中。
C语言的字符串有两种存储方式,字符串常量和字符串数组,二者存储的内容都一样,也都是一个返回字符串的首地址,区别是前者是常量,内存的内容不能修改,后者可以修改。
数组[]
数组是在内存里一块区域里连续的存储数目固定的同一类型数据,这里的同一类型,既包括基本数据类型,也包括复合数据类型,指针等。一块数组可以用它的数组名唯一的表示,这个数组名其实就是这块内存的首地址,即第一个元素的首地址。定义数组时,元素的个数从1开始算,访问数组时,元素的个数从0开始算。所以数组名arr是第一个元素arr[0]的地址,arr+1是第二个元素arr[1]的地址,注意,arr+1不是第二个byte的地址,编译器会以一个元素所占的byte数为单位进行地址的增减。a[i]的实质就是将地址从a开始移动i个单位长度再解引用,即*(a+i)。
定义一个一维数组
元素类型 数组名[元素的个数];
二维(多维)数组本质上还是在一块连续的内存中存储数目确定的同一类型数据,只不过对这块数据进行了"分组",比如,同样的一块存储了1,2,3,4...,9,10的内存,用一维数组表示是int num[10]={1,2,3,4,5,6,7,8,9,10};,而用二维数组表示是int num[2][5]={1,2,3,4,5,6,7,8,9,10};,内存还是那块内存,只不过表达方式变了,二维数组相当于把这10个数分成了两组,每组5个数
定义一个二维数组
元素类型 数组名[组数][每组元素数]
定义并初始化一个数组
char stu1Name[20]="Tom"; //定义并初始化字符数组,数组中前4byte被赋值
char remark[20]={‘y‘,’e‘,’s‘}; //数组中前3byte被赋值
int vector[]={1,2,3}; //如果数组元素全部列出,可以省略定义时的元素个数
int vector2[][2]={1,2,3,4}; //如果没有歧义,二维数组的第一维可以省略,没有赋值的部分会被初始化为'0';
指针数组VS数组指针
指针数组的核心词是"数组",所以指针数组表示的是里面的成员都是指针类型的数组
int* arr[10]; //arr用来存储10个指向int类型的指针
char* strarr[10]; //strarr用来存储10个指向char类型的指针,因为字符串的实质就是char*,所以strarr是存储了10个字符串首地址的数组
数组指针的核心词是"指针",数组名本身就是一个指针常量,就是第一个元素的地址
int arr[10] = {1,2,34};
int* pArr=arr; //将数组的地址赋值给数组指针
但是数组指针多用在二维数组中,一个int* ptr可以指向int arr[3],但是不能指向二维数组,二维数组指针一定要除了元素类型还要至少标明数组的列数,形如int (*ptr)[3],则这个ptr才可以指向任何一个以int为元素类型,列数为3的数组,当然,也可以同时指定指向数组的行数和列数做进一步的限定。
二维数组指针有行指针和列指针之分
结构体struct
结构体是把不同的数据类型进行打包的一种数据类型,由程序员自己定义。既然说结构体是一种数据类型,而一个数据类型是没有值的,所以结构体在定义时不能进行赋值。
定义一个有名结构体类型,使用变量列表创建变量,使用初始化列表进行初始化
struct StuInfo{
int age;
char name[20];
}stu1={10,"Tom"},stu2={11,"Rendo"};
定义一个结构体类型,习惯上将自定义的结构体类型的首字母大写,以便和变量进行区分
struct StuInfo{
int age;
char name[20];
};
//或
typedef struct{
int age;
char name[20];
}StuInfo2;
定义一个结构体类型的变量并进行列表初始化,列表初始化,即只能在初始化时使用,如果定义变量的时候不用,那么之后就只能逐个元素的赋值。
struct StudInfo stu1={10,"Tom"};
//或
StudInfo2 stu2={11,"Rendo"};
给结构体变量赋值
stu.age=10;
stu.name[0]='T';
stu.name[1]='o';
stu.name[2]='m';
stu.name[3]='\0';
结构体与指针
struct StuInfo* pSt; //定义一个指向结构体StuInfo类型的指针
struct StuInfo stu; //定义一个结构体StuInfo类型的变量
pSt = &stu; //将结构体变量stu的地址赋给pSt
共用体union
共用体的各个成员共享同一块内存,如果各个成员的长度不同,会取最长的那个成员的长度作为共用体的长度
定义一个union
union Data{
int num1;
double num2;
};
//或
typedef union{
int num1;
double num2;
}Data;
创建共用体变量
union Data{
int num1;
double num2;
};
//或
typedef union{
int num1;
double num2;
}Data;
定义一个共用体变量
union Data data1,data2;
//或
Data data1,data2;
使用共用体
data1.num1=2;
data2.num2=3.3;
枚举enum
顾名思义,枚举就是一个一个的列举,枚举类型用自定义的元素来代替列举元素的编号,方便记忆,但是其本质上还是一个整数。
定义一个enum类型weekday
enum weekday{sun,mon,tue,wed,thu,fri,sat};
定义了一个weekday类型的变量
enum weekday day;
使用day变量
day=mon;
C语言的数据类型及其对应变量的更多相关文章
- 谈谈C语言的数据类型
本文摘要: 本文主要讲述C语言中的数据类型,从基本的数据类型到派生的数据类型,从int ,char ,float double ....到指针,数组,函数,指向指针的指针,指向数组的指针,指向函数的指 ...
- C语言的数据类型
复习之余,做点笔记<C语言之数据类型> 一.整数数据类型 (1)整数数据类型 整数类型 char 字符型变量 1字节(8Bit) short 短整型 2字节(16Bit) i ...
- Swift语言指南(一)--语言基础之常量和变量
原文:Swift语言指南(一)--语言基础之常量和变量 Swift 是开发 iOS 及 OS X 应用的一门新编程语言,然而,它的开发体验与 C 或 Objective-C 有很多相似之处. Swif ...
- 初识 go 语言:数据类型
目录 数据类型 指针 结构体 数组 切片 切片的方法 映射 函数闭包 结束语 前言: go语言的第三篇文章,主要讲述go语言中的数据类型,包括指针,结构体,数组,切片,映射,函数闭包等,每个都提供了示 ...
- JavaScript 引入方式 语言规范 语言基础 数据类型 常用方法 数组 if_else 比较运算符 for while 函数 函数的全局变量和局部变量 {Javascript学习}
Javascript学习 JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript ...
- R语言学习 第一篇:变量和向量
R是向量化的语言,最突出的特点是对向量的运算不需要显式编写循环语句,它会自动地应用于向量的每一个元素.对象是R中存储数据的数据结构,存储在内存中,通过名称或符号访问.对象的名称由大小写字母.数字0-9 ...
- c语言基础:数据类型 分类: iOS学习 c语言基础 2015-06-10 21:43 9人阅读 评论(0) 收藏
C语言基本数据类型大体上分为: 整型 和 浮点型 字节: 计算机中最小的储存单位 1 Byte = 8 bit 整型: int 4 ...
- Go语言学习笔记二: 变量
Go语言学习笔记二: 变量 今天又学了一招如何查看go的版本的命令:go version.另外上一个笔记中的代码还可以使用go run hello.go来运行,只是这种方式不会生成exe文件. 定义变 ...
- 「C语言」数据类型及混合运算与类型转换
深入学习C语言时,有必要先了解一下数据类型的概念,以及它们之间的混合运算与类型转换. 本篇文章便是根据<C语言程序设计教程>和在线翻阅资料后整理而出.(练习题将逐步更新) 目录: ...
随机推荐
- ASP.NEt MVC5--创建下拉列表
Adding Search by Genre If you added the HttpPost version of the Index method, delete it now. Next, ...
- 2015 Multi-University Training Contest 1 - 1001 OO’s Sequence
OO’s Sequence Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5288 Mean: 给定一个数列,让你求所有区间上满足 ...
- Linq专题之Linq查询from子句
Linq查询表达式包含8个常用的子句:from.where.select.join.into.orderby.group.let.我们来看看详细的说明. from: 指定查询操作的 ...
- Asp.NET MVC JSON序列化问题
最近在做项目的时候遇到一个JSON序列化问题. 环境:ASP.NET MVC 4.0 数据库:SQL 2008 在将获取的数据从后台以json的形式传给前台的easyui treegrid绑定的时候通 ...
- WebApi传参总动员(五)
上回说到涉及多个实体的传参,用常规的方法已经不能解决了.这回我们用终极大招搞定她. WebApi:注意要引用JSON.Net [HttpPost] public string GetData(stri ...
- 转 PHP在JVM上的实现JPHP
前两天还在想,像Quercus只封装了PHP在Java上的Web接口,有没有实现了完整的JVM语言特性的东东,这不,来了. JPHP是一个面向Java虚拟机的PHP实现,支持PHP(5.3+)的很多特 ...
- web ppt
先记录,以后再试试 https://github.com/gnab/remark/wiki http://segmentfault.com/blog/sweetdum/1190000000484121 ...
- 【NOIP训练】【Tarjan求割边】上学
题目描述 给你一张图,询问当删去某一条边时,起点到终点最短路是否改变. 输入格式 第一行输入两个正整数,分别表示点数和边数.第二行输入两个正整数,起点标号为,终点标号为.接下来行,每行三个整数,表示有 ...
- SwipeRefreshLayout下拉刷新
1.SwipeRefreshLayout是Google在support v4 19.1版本的library更新的一个下拉刷新组件,实现刷新效果更方便. 弊端:只有下拉 //设置刷新控件圈圈的颜色 sw ...
- Linux编辑器vim键盘详解
下面的这张图,一看就明白了,从此,学习变的不再艰难! 补注:图中没有关于查找和替换的,应该用下面的.自上而下的查找操作 /word小写的n和N自下而上的查找操作 ...