关键字(保留字)
C、C++系统中预定义的、在语言或编译系统的实现中具有特殊含义的单词。
定义变量而未赋值
字符型指向NULL 输出空格
整型与指针已经有了内存空间,指向随机(上一次使用过的内存空间)
int a;随机一个值(有相应的内存地址)
int *p; 随机指向一个地址数字(野指针,有相应的内存空间)
char *p;
printf("%c",p);//输出D
int a;
printf("%d",a);//输出8
用NULL来避免野指针(C语言和C++中默认被替换为0)。
int *p=NULL 等于 int *p=0;
就是指向一个空指针。这个p的值为0,有相应的地址。
1.基本数据类型
数值类型
整形(表示整数:short、int、long)
一种数据类型占用的字节数,称为该数据类型的长度。例如,short 占用 2 个字节的内存,那么它的长度就是 2。
short int a =3;
printf("%d\n",sizeof(a)); // 输出为2
短整型short 或 short int
长度:固定为2字节 可表示正的2的16次方-1 个数(可以再表示同样数量的负数)
int 和 long 的长度无法确定,在不同的环境下有不同的表现。
整形int
int的长度不能小于 short,一般为4字节
长整型long
long 的长度不能小于 int。一般32位编译器将long编译为4字节,64位编译为8字节
注:64位系统可兼容32位软件
long long类型
长度固定为8字节
总结起来,它们的长度(所占字节数)关系为:
2 ≤ short ≤ int ≤ long
一般来说64位为 2 4 8
32位为 2 4 4
有符号整数、无符号整数(unsigned定义无符号数据、signed有符号数)
无符号整数与有符号整数 相加结果默认为无符号数(运用补码运算)
%d输出,printf默认这个数是有符号整数(可将无符号数转变为有符号数输出)
unsigned i=-10; //unsigned:无符号整数
printf("%d",i);//输出-10
浮点型/实型(表示实数:float、double)
printf("%f\n",b); // 默认输出小数和点后六位
printf("%.6f\n",b); // 输出小数和点后六位
实数:有理数和无理数的总称,包括整数和小数点数
单精度浮点型float:32位 4bytes
可以输出小数点后6位
双精度浮点型double:64位 8bytes
可以输出小数点后15位
字符型(表示一个字符:char 1byte)
1、字符仅为单引号
2、字符与整形的辨析
char ch1 = 'a';
printf("字节:%ld\n",sizeof(ch1)); //字节:1
printf("字节:%ld\n",sizeof('a')); //字节:4
printf("字节:%ld\n",sizeof((char)'a')); //字节:1
C语言:'a’叫做整型字符常量,被看成是int型。
C++:'a’叫做字符字面量,被看成是char型,所以占1字节。
3、字符与ASCII码一一对应(char类型相当于小范围的整形类型,0-127)
如ASCII码98与‘b’,相互对应
char ch=98;
printf("%c\n",ch);//输出b
printf("%d\n",ch);//输出98
int a='b';
printf("%d\n",a);//输出98
printf("%c\n",a);//输出b
因为字符等同于相应的ASCII码,所以字符可与整数/字符进行运算,理解为ASCII码的运算
printf("%c\n",'a'+1);//输出b
printf("%d\n",'a'+1);//输出98
printf("%d\n",'a'+'b'); //输出195(97+98)
printf("%c\n",'a'+'b'); //输出?(97+98,没有对应的ASCII码)
printf("%d",'1'+'2'); //输出99(49+50)
printf("%c",'1'+'2'); //输出c(ASCII码为99)
‘0’-‘9’:ASCII码从48到57
‘A’:ASCII码为65
‘a’:ASCII码为97
//输出ASCII码为0的字符
printf("%c\n",0);//输出空白,实际是(null)
printf("%s\n",0);//输出(null)
字符串(C++)
2.指针类型(长度等同机器字长,如32为4bytes)
指针取值与输出:
*(p+i), p[i]都是第(i+1)个元素的值
printf("%d\n",*p++); //先*p,再p++
printf("%d\n",*(p++)); //先*p,再p++
printf("%d\n",(*p)--); //先*p,再*p指向的值-1
C输出:
printf(“%s”,p); printf(p); →输出字符串(p指向的字符串)
printf(“%d”,p); →输出指针p值
C++ 输出:
cout <<*p ; →输出字符串(指针指向的内存空间)
cout <<p ; →输出指针中存放的地址
3.构造类型
数组
声明:type arrayName [ arraySize ];
arraySize 必须是一个大于零的整数常量,type 可以是任意有效的 C/C++ 数据类型
int ch[5]; //通用,声明数组需设置内存空间
ch[0]=1; //通用,声明后赋值
int b[]={1,23,4}; //通用,声明时初始化赋值,内存空间为成员数量
int c[5]={1,23,4}; //通用,声明时初始化赋值,内存空间为5
数组长度
#include<iostream>
using namespace std;
#define foo(arr) sizeof(arr)/sizeof(arr[0])
//仅C++
template<class T>
int length(T& arr)
{
return sizeof(arr) / sizeof(arr[0]);
}
int main() {
int temp[]={1,2,3,4,5};
cout<<length(temp)<<endl; //sizeof 是运算符 strlen是函数
temp[6]=13;
cout<<foo(temp)<<endl;
cout<<temp[5]; //输出随机值
}
数组作为参数
#include<iostream>
using namespace std;
#define foo(arr) sizeof(arr)/sizeof(arr[0])
// 三个函数效果一样
//temp[2]=666; 同 *(temp+2)=666; 都会改变原数组
void pv1(int temp[],int length)
{
cout<<foo(temp)<<endl; //长度固定为1
}
void pv2(int temp[6])
{
cout<<foo(temp)<<endl; //长度固定为1,也是只把基地址传了过去
}
void pv3(int * temp)
{
// 不用长度,只是一个指针指向了一个地址,该地址存放int数据
cout<<foo(temp)<<endl; //长度固定为1
}
int main() {
int i[6]={1,2,3,4,5,6};
pv1(i,foo(i));
pv2(i);
pv3(i);
}
结构体(struct为关键字)
struct结构:一种可以存放不同数据的集合
C语言结构体中不能包含函数, 只能包含函数指针。
C++的结构体才可以包含函数
集合:元素仅有“同属于一个集合”的关系
结构包含多个变量或数组变量,称为结构体的成员(理论上各个成员在内存中是连续的)
1)结构体直接定义
如strut stu{int num;char *name;}stu1;
成员在定义时不能初始化
成员类型可以为基类型,也可以为其他构造类型
struct stu为结构体类型名(定义的新数据类型/构造类型)
stu1为结构体类型的变量
若stu结构体只使用一个变量stu1就足够 不打算再定义新变量 定义结构体名字可省略 只留变量名如strut {}stu1;
2)定义+typedef换名
typedef struct Stu{}a;
为结构体类型struct Stu 增加(换)一个新的名字a
→struct Stu,a都是该结构体类型名。
可省略:(Stu)定义时可以省略(a作为类型名即可)
不可省略:但如果定义结构体时,内部需要用本身的结构类型(名)定义变量,则不可以省略本身的结构名
结构体类型指针 换名
typedef struct Stu{}*a;
⇔ typedef (struct Stu *)a;
将struct Stu指针类型(如整形指针类型,int *)
换名为a
a a1; 定义了一个struct Stu 类型 的指针变量a1
3)结构体类型声明变量
①定义结构体后声明变量如strut stu stu1;
②在定义结构体时声明变量如 strut stu {}stu1;
若stu结构体只使用一个变量stu1就足够
不打算再定义新变量 定义结构体名字可省略 只留变量名如strut {}stu1;
③使用typedef 换名后 声明变量
typedef struct stu a
a stu1(a是结构体类型struct stu)
stu1是结构体类型的声明变量
成员的赋值和获取
初始化
struct tag
{chara;int b;
}x = {‘A’, 1};/*初始化*/
按字段,变量名.成员名
如输出 stu1.name
通过指针访问
结点结构体定义一个指针指向一个 特定结点结构体类型 变量
如elm *p=&stu1;(等同于elem *p;p=&stu1;)
可通过(*p).name 来访问 stu1.name:
(*p).name ⇔ p→name :p所指结构体变量(结点)的name成员
(5)notes
①(整体赋值/同数组 只可在定义整体时进行)
如 strut {}stu1={12,‘栗波’};
使用变量过程中只能对成员逐一赋值
②结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间,结构体变量包含了实在的数据,需要内存空间来存储。
4.空类型void
5.数据类型的组合
1-1)字符数组(C中可替代字符串,可读/写/扩展)
由于C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中.
char ch[10]={'1','2','3'}; //通用,单个元素赋值,分配10个空间
char ch[]="123"; //通用,整个数组赋值,分配3个空间(实际是4个,包括终结符)
输出单个字符:
printf("%c\n",ch[0]); //输出'1'
printf("%d\n",ch[0]); //输出'1'对应的ASCII码值49
将字符串全部输出:以字符串形式输出时,会自动往后取字符,直到该字符串结束。
printf("%s\n",ch); //输出"123"
数组在栈的存储,以字符数组为例:
int main(int argc1,char *argv1[])
{
char a='5';
printf("%d\n",&a); //假设为34
char ch[]="234";
printf("%s\n",ch); //输出234
printf("%d\n",sizeof(ch)); //4(初始的分配空间)
printf("%d\n%d\n",&ch[0],&ch[3]); //30-33,其中ch[3]为终止符(空字符 '\0' ,'\0'就是8位的00000000)
输出终极符以外的值
printf("%c\n",ch[4]); //输出5,其实是输出*(ch+4),也就是a的值
char b='1';
printf("%d\n",&b); //29
改变终结符以外的值:
ch[4]='8'; //对于ch指向字符串来说,终结符在ch[3].所以以下输出不会改变,相当于a='8'
printf("%s\n",ch); //仍输出234
printf("%d\n",sizeof(ch)); //仍为4(初始的)
改变终结符的值:
ch[3]='5'; //把原本终极符改成了'5',则终结符会下移到一个处女空间(没有被变量存放的空间)
printf("%s\n",ch); //输出23458**(若干个,此处为23458D)
printf("%d\n",sizeof(ch)); //仍为4(初始的)
return 0;
}
1-2)数组指针(数组的指针,可写。数组等价于数组指针)
数组指针(数组的指针 即数组被指针指向,指针中存放的是数组的基地址)
当一个指针变量被初始化成数组名时,就说该指针变量指向了该数组(p中存放str的首地址)
如 char str[20], *p; p=str;
2)常量字符型指针(C中可替代字符串。常量,仅可读)
只可读,不可修改,ch为该常量字符串的首地址
char *ch="123"; //定义
或
char * ch; ch = "I love China!";
"123"这个字符串被当作常量,放置在程序的内存静态区。字符串“123”是个常量,存储在一片连续的内存中,末尾有结尾符表示字符串的结束。
ch为一个字符型指针,若为局部变量,则存储在栈内。该指针变量里面存放为字符串中第一个字符’1’的地址。
输出单个字符:
printf("%c\n",ch[0]); //输出'1'
printf("%d\n",ch[0]); //输出'1'对应的ASCII码值49
对字符型指针str做输出字符串的命令,就会将常量字符串全部输出。(打印完第一个字符会自动打印完整个字符串)
printf("%s\n",ch); //输出"123"
3)指针数组(指针的数组,每个成员都是指针)
p作为指针数组,其每个元素存放的都是一个数组的基地址。
char *p [] = {"123","456"};
printf("%s",p[0]); //输出123
双星指针变量
双星:声明一个指针变量,每个存储单元存放一个指针变量(值为其他内存的地址)。
当每个指针指向的是一个数组时,双星等同于指针数组。
char *p [] = {"123","456"};
printf("%s\n",p[0]); //输出123
将指针数组的基地址传给(双星)指针变量,等同于指针数组
char **q = &p;
printf("%s",p[0]); //输出123