/*
可用如sizeof(char),sizeof(char*)等得出
32位编译器:
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
*/
#include<stdio.h>
//枚举
enum Case
{
STR,
NUM,
POINT,
ARRAY
};
void change_point(int** ppp)
{
int number = 10;
*ppp = &number;
printf("&number:0X%X\n",&number);
}
/*-----------------------------------------------------------------------------------*/
void num_func()
{
//数值类型
short num_short = 3;
int num_int = 21;
long num_long =3;
printf("\n----int-----\n");
printf("leng of short:%dByte\t2^16[-32768-->32767]\tnum:%d\n",sizeof(num_short),num_short);
printf("leng of int:%dByte\t2^32[-2147483648-->2147483647]\tnum:%d\n",sizeof(num_int),num_int);
printf("leng of long:%ldByte\t2^64[-2^63-->(2^63)-1]\tnum:%d\n",sizeof(num_long),num_long);
unsigned short us_num_short_int = 6;
unsigned int us_num_int = 3;
unsigned long us_num_long =5;
printf("leng of unsigned short:%dByte\t2^16[0-->65535]\tnum:%d\n",sizeof(us_num_short_int),us_num_short_int);
printf("leng of unsigned int:%dByte\t2^32[0-->4294967295]\tnum:%d\n",sizeof(us_num_int),us_num_int);
printf("leng of unsigned long:%ldByte\t2^64[0-->2^64]\tnum:%d\n",sizeof(us_num_long),us_num_long);
//unsigned 和 signed 在占用内存大小上是一样的,唯一的区别是signed最高位是符号位
//字符类型
printf("\n----char-----\n");
char num_char = 4;
unsigned char us_num_char = 4;
printf("leng of char:%dByte\t2^8[-128-->127]\tnum:%d\n",sizeof(num_char),num_char);
printf("leng of unsigned char:%dByte\t2^8[0-->255]\tnum:%d\n",sizeof(us_num_char),num_char);
/*
----int-----
leng of short:2Byte 2^16[-32768-->32767] num:3
leng of int:4Byte 2^32[-2147483648-->2147483647] num:21
leng of long:8Byte 2^64[-2^63-->(2^63)-1] num:3
leng of unsigned short:2Byte 2^16[0-->65535] num:6
leng of unsigned int:4Byte 2^32[0-->4294967295] num:3
leng of unsigned long:8Byte 2^64[0-->2^64] num:5
----char-----
leng of char:1Byte 2^8[-128-->127] num:4
leng of unsigned char:1Byte 2^8[0-->255] num:4
*/
}
/*-----------------------------------------------------------------------------------*/
void interchange(char *a_,char *b_)
{
char temp = 0;
temp = *b_;
*b_=*a_;
*a_=temp;
}
void point_func()
{
char p_num = 12;
unsigned char *p=NULL;
p = &p_num;
printf("%d\t%p\t%p\n",p_num,p,&p_num);
/*
* 指针是一个其数值为地址的变量,指针的数值表示的是地址
* 指针声明,int *pi //pi是指向一个整数变量的指针
* (&)地址运算符,后面跟一个变量名时,&给出该变量的地址 &num,表示变量num的地址
* (*)间接运算符, 后面跟一个指针名字或者地址时,*给出储存在被指向地址中的值
*/
/*
尽管interchange()只使用的是局部变量,但是通过使用指针,该函数可以操作point_fun()中的变量的值
通过传入函数的指针,可以操作指针指向地址的变量
*/
char a=5,b=10;
printf("Original value %d %d\n",a,b);
interchange(&a,&b);
printf("After interchange %d %d\n",a,b);
/*
12 0x7fffd0b7f547 0x7fffd0b7f547
Original value 5 10
After interchange 10 5
*/
}
/*-----------------------------------------------------------------------------------*/
void array_func()
{
/*
数组赋值,C不支持把数组作为一个整体来进行赋值,也不支持用花括号括起来的列表形式进行赋值(初始化除外)
可以借助数组索引(即下标)对数组成员进行赋值。
int oxen[5]={1,1,2,5};
int yaks[5];
yaks=oxen;//不允许
yaks[5]=oxen[5];//不正确
yaks[5]={1,21,3,10};//不起作用
oxen[1]=23;//正确
yaks[4]=12//正确
*/
short dates[4];
short *pti;
short index;
double bills[4];
double *ptf;
pti = dates;
ptf = bills;
printf("\t\tsize short:%d size double:%d\n",sizeof dates,sizeof bills);
printf("\t\tsize short[0]:%d size double[0]:%d\n",sizeof dates[0],sizeof bills[0]);
printf("%23s %13s\n","short","double");
for(index = 0;index<4;index++)
printf("pointers + %d: %10p %10p\n",index,pti+index,ptf+index);
/*
按照字节编地址,short类型是2个字节,double是8个字节。
在这个例子中,最指针加1的结果是对该指针增加1个存储单元。对于数组而言,地址会增加到下一个元素地址,而不是下一个字节
这就是为什么在声明指针时必须声明它所指向对象的类型。计算机需要知道存储对象所用的字节数,所以只有地址信息是不够的。
(即使指针是指向标量的,也需要声明指针类型,否则*pt操作不能正确返回数值)
* 指针的数值就是它所指向的对象的地址。地址内部表示方式是有硬件来决定的,很多计算机都是以字节编址的,这意味着对每个内存字节顺序进行编号
对于包含多个字节的数据类型,比如double类型的变量,对象的地址通常指的是其首字母的地址。
* 在指针前运用运算符*就可以得到该指针所指向的对象的数值
* 对指针加1,等价于对指针的值加上它所指向的对象的字节大小
dates+2 == &dates[2]
*(dates+2) == dates[2]
C语言标准在描述数组时,确实借助了指针的概念。例如定义ar[n],意思是*(ar+n),即"寻址到内存中的ar,然后移动n个单位,再取出数值"
*(dates+2) //dates的第三个元素的值
*dates + 2 //第一个元素的值加2
指针以2字节为单位增加,因为pit是int类型那个的
pti pti+1 pti+2 pti+3
2ea0 2ea1 2ea2 2ea3 2ea4 2ea5 2ea6 2ea7 2ea8 --->机器地址
|-----|-----|-----|-----|-----|-----|-----|-----|
| dates[0] | dates[1] | dates[2] | dates[3] | --->数组元素
|-----|-----|-----|-----|-----|-----|-----|-----|
int dates[y],*pti;
pti=dates (或者pti=&dates[0]);
short double
pointers + 0: 0x7fff3dbb2ea0 0x7fff3dbb2e80
pointers + 1: 0x7fff3dbb2ea2 0x7fff3dbb2e88
pointers + 2: 0x7fff3dbb2ea4 0x7fff3dbb2e90
pointers + 3: 0x7fff3dbb2ea6 0x7fff3dbb2e98
*/
}
/*-----------------------------------------------------------------------------------*/
void str_func()
{
//C语言没有专门定义字符串的类型变量,而是把它储存在char数组当中
//下面是定义数组的几种方式
char str_1[5]="str_1";//注意定义的数组大小,每个字符占一个字节,最后\0自动处理
char str_2[]="str_2";
char *str_3="str_3";//指针类型
char *str_4[3]={"abc","sdf","wed"};//定义一个字符串指针数组
printf("str:%s\n",str_1);//字符打印%s
printf("str:%s\n",str_2);
printf("str:%p\n",str_3);
printf("str:%s\n",str_3);//指针类型,可以直接打印,也是字符串地址
printf("str:%p\n",str_4);
printf("str:%s\n",str_4[0]);//abc
char c_str[3]={'n','u','m'};
printf("str %p\n",c_str);//指针
printf("str %c\n",c_str[0]);
printf("str %c\n",c_str[1]);
/*
str:str_1
str:str_2
str:0x400cc6
str:str_3
str:0x7fff4a319740
str:abc
str 0x7fff4a319730
str n
str u
*/
}
/*-----------------------------------------------------------------------------------*/
/*
argc ,用于存放命令行参数的个数。
argv,是个字符指针的数组,每个元素都是一个字符指针,指向一个字符串,即命令行中的每一个参数。
argc参数个数
第1个参数 argv[0]-->字符串1 --->./run
第2个参数 argv[1]-->字符串2 --->1
第3个参数 argv[2]-->字符串3 --->2
./run 1 2
*/
void main(int argc,char *argv[])
{
unsigned char argv_value=0;
if(argc!=2)
{
printf("parameters error!\tlike run [parameters]\n");
}
else
{
argv_value=atoi(argv[1]);
switch(argv_value)
{
case STR:
str_func();
break;
case NUM:
num_func();
break;
case POINT:
point_func();
break;
case ARRAY:
array_func();
break;
default:break;
}
}
}