地址与内存
给内存编的号是地址。
内存常见单位及其换算。常见单位:bit(比特),Byte(字节),KB,MB,GB,TB……。1KB = 8bit,1KB = 1024Byte, 1MB = 1024KB, 1GB = 1024MB, 1TB = 1024GB。
认识指针
指针是变量的地址。
代码1:打印变量地址
#include<stdio.h>
int main(){
int a = 0;
printf("%p\n",&a);//%p表示打印的数据类型是指针,此句打印a的地址,每次运行结果都不相同
return 0;
}
代码1编译后,每次运行都会打印a的地址,每次运行结果中a的地址都不相同。
代码2:
#include<stdio.h>
int main(){
int a = 0;
int* pa = &a; //这是一个指针变量的定义以及赋初值
//int表示pa所指向的数据类型(主要用于确定内存大小),*表示pa是一个指针变量,&a表示pa的初值是a的地址
printf("%p\n",pa);
printf("%p\n",&a);
printf("%d,\n",sizeof pa);
return 0;
}
int与*之间可以有空格,也可以没有空格。这里更倾向于int和*之间不加空格,看作是int*定义了一个int类型指针(既将int*单独看作一种类型)。
*与pa之间可以有空格,也可以没有空格。这里更倾向于int和*之间加空格。
*被称为解引用操作符。*pa可以简单认为是取地址pa中存放的数据。
代码3:
#include<stdio.h>
int main(){
int a = 10;
int* pa = &a;
printf("%d\n",*pa);
*pa = 20;//地址pa中的数据变成了20,也就是a的值变成了20
printf("%d\n",*pa);
return 0;
}
代码3第输出结果为 10 20。
第6行,意思是pa地址所存储的数据被赋值(改变)成20,也就是pa所指向的地址(变量a所在位置)的值变成了20,换句话说就是a的值变成了20。第5、6、7行中,*和pa之间有没有空格都是可以的,这里更倾向于没有空格,将*看成是一个单目操作符。
代码4:
#include<stdio.h>
int main(){
printf("%d\n",sizeof(char*));
printf("%d\n",sizeof(short*));
printf("%d\n",sizeof(int*));
printf("%d\n",sizeof(long*));
printf("%d\n",sizeof(float*));
printf("%d\n",sizeof(double*));
printf("%d\n",sizeof(long long*));
return 0;
}
代码4的运行结果取决于操作系统。众所周知,主流操作系统有32位和64位之分。在32位操作系统中,打印结果全是4;而在64位操作系统中,打印结果全是8。这是因为,32位操作系统的地址数是32位,也就是32 bit = 8 bit * 4 = 4 Byte。所以sizeof的结果全是4。而64位操作系统的地址数是64位,也就是64 bit = 8 bit * 8 = 8Byte。所以sizeof的结果全是8。
结构体
代码1:
#include<stdio.h>
struct Num{
int num;
unsigned int level;
char name[20];
char sex;//X is female and Y is male
}typedef Num;
void show_info_print(Num numinfo);
int main(){
Num num01={1,0,"ABCD0123",'X'};
show_info_print(num01);
num01.num++;
show_info_print(num01);
return 0;
}
void show_info_print(Num numinfo){
printf("Number:\n\t%010d\n",numinfo.num);//输出10个数,不足处用0补足
printf("Level:\n\t%d\n",numinfo.level);
printf("Name:\n\t%s\n",numinfo.name);
printf("Sex:\n\t");
if(numinfo.sex == 'X')
printf("%s\n","Female");
else if(numinfo.sex == 'Y')
printf("%s\n","Male");
}
第2行至第7行是定义结构体。第2行struct Num定义了一个Num结构体,需要使用这个结构体定义时可用代码struct Num a;。第3行至第6行规定了结构体的内容。它们有编号(num)、等级(level)、名字(name[20])和性别(sex)。第7行的“}”表示结构体定义结束。typedef是定义别名,这样定义结构体变量时就可以不用打Struct Num这个这么长的名字,可以直接如第10行,可以直接用Num代替typedef Num。
第8行声明了函数show_info_print。该函数定义在第14行至第23行。
第10行定义了一个结构体变量num01,用“{}”初始化这个结构体变量。大括号内的顺序和3至6行的定义顺序一致,即num为1,level为0,name为ABCD0123,sex为X。
结构体中内容的使用如第12行所示。用操作符“.”来引用结构体中的某个元素。如第12行中,num01.num表示num01结构体中的元素num,那么num01.num就表示num01结构体中的元素num加1。