C语言--变量 指针 链表

常量:其值不能被改变的值

变量:运行过程中,可以改变的,对程序编译连接时由编译系统给每一个变量名分配对应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据。先定义后使用

标识符:对变量、符号常量、函数、数组、类型等数据对象命名的有效字符序列;就是一个名字;只能由字母、数字和下划线3种字符组成,且第一个字符必须为字母或下划线。

数据类型

  基本类型

     整型

       常量:十进制,八进制,以0开头,如0123,1*8的2次方+2*8的一次方+3,十六进制,以0x开头,如0x123,值是1*16的2次方+2*16的一次方+3。

       变量:数据在内存中以二进制存放。以补码的形式表示,正数的补码和该数相同,负数的补码是该数的绝对值按照位取反再加1。通常以一个机器字(word)存放一个int数据,通常把long定为32位,把short定为16位,而int可以是16位也可以是32位。注意取值范围,溢出不会报错,只会影响结果。

     字符型

        常量:单撇号括起来的字符如‘a’和转义字符

        变量:只能放一个字符,在所有的编译系统中都规定以一个字节存放一个字符,以该字符对应的ASCII码存放在内存单元中。如‘a’的ASCII码为十进制97,在内存中以二进制形式存放的,与整数存储形式类似,这样使字符型数据和整型数据之间可以通用。一个字符型数据既可以以字符形式输出,也可以以整数形式输出。有些系统将字符变量定义为signed char,其存储单元最高位为符号位,如果不想按有符号处理,可以在程序中将字符变量定义为unsigned char类,与unsigned int 相仿,但是只有一个字节。

     字符串

         常量:双撇号括起来的字符序列。‘\0’:字符串结束标志,是一个ASCII码为0的字符,空操作字符,它不引起任何控制操作,也不是一个可显示的字符。所以“a”在内存中占两个字节

         变量:没有专门的字符串变量,必须使用字符数组,数组中每一个元素存放一个字符。

     浮点型

        常量:有两种表示方式:十进制小数形式(必须有小数点);指数形式,e前面要有数字,e后面为整数。如1.234e2是规范写法,表示123.4。一般在内存中占4个字节,32位,按照指数形式存储的。在4个字节中,多少位存小数部分,多少位存指数部分,没有具体规定,由编译系统来定。

        单精度型

        双精度型

      数组类型

          一维数组的定义:类型说明符数组名【常量表达式】

          一维数组元素的引用:数组名【下标】

          一维数组的初始化:全部元素赋初始值,如int a[5]={1,2,3,4,5}  int

a[5]={0,0,0,0,0} int a[5]={0} int a[]={1,2,3,4,5}。部分元素赋初始值inta[5]={1,2,3}后面补0

          二维数组的定义:类型说明符 数组名【常量表达式】【常量表达式】

          二维数组元素的引用:数组名【下标】【下标】

          二维数组的初始化:全部元素赋初始值int a[3][4]={{1,2,3,4}{5,6,7,8}{9,10,11,12}}

int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12} int a[][4]= {{1,2,3,4}{5,6,7,8}{9,10,11,12}}int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}。部分元素赋初始值 inta[3][4]={{1}{5}{0 9} int a[3][4]={{1}{0 5}} int a[][4]={{0 0 3}{}{5}} 其余的都补0。

          字符串数组初始化:char a[]={“china”}  char a[]={‘c’,’h’,’i’,’n’,’a’,’\0’}printf(“%s”,a) 按照数组名a找到数组起始地址,然后逐个输出直到遇到\0。printf(“%c”,a[0]) scanf(“%s”,a)

      结构体类型

                         将不同类型的数据组合成一个有机的整体。

定义结构体类型变量:

1 先声明结构体类型再定义变量名

                     struct 结构体名

                     {成员列表};  成员列表:类型名 成员名

struct 结构体名 结构体变量名

struct student{

int num;

char sex;

};

Struct student stu1 stu2;

2 在声明类型的同时定义变量定义变量

Struct student{

int num;

char sex;

}stu1,stu2;

3 直接定义结构体类型变量

Struct {

int num;

char sex;

}stu1,stu2;

结构体变量名.成员名

  stu1.num   &stu.num 

&stu1:stu1的首地址

结构体变量的初始化

  结构体变量的初始化

struct student

{

int num;

char sex;

}a={1,'M'};

结构体数组

struct student stu[3]={{1,'M'},{2,'M'},{3,'W'}};

指向结构体类型数据的指针

struct student stu1;

struct student *p;

p =&stu1;

stu.num等价于(*p).num等价于p->num

用结构体变量和指向结构体的指针作函数参数

#define FORMAT "%d"

{

struct student stu;

print(stu);

print1(&stu);

}

void print(struct student stu)

{

printf(FORMAT,stu.num);

}

void print1(struct student *p)

{

printf(FORMAT,p->num);

}

用指针处理链表

因为数组必须事先定义固定的长度,但是比如有的班级100人,有的班级30人,固定100人就有点浪费内存,用链表就没有这种缺点,它根据需要开辟内存单元,动态地进行存储分配。链表有一个"头指针"变量,存放一个地址,该地址指向一个元素,链表中每一个元素称为结点,每一个结点都应该包括两个部分:用户需要用的实际数据和下一个结点的地址。定义struct student类型时并不实际分配存储空间,只有定义了变量才分配内存单元。

eg:所有结点都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表叫静态链表

#include <stdio.h>

#define NULL 0

struct student {

int num;

char sex;

struct student *next;

};

void main()

{

struct a,b,c,*head,*p;

a.num=1;

a.sex='M';

b.num=2;

b.sex='M';

c.num=3;

c.sex='W';

head=&a;

a.next=&b;

b.next=&c

c.next=NULL;

p=head;

do{

printf("%d,%c",p->num,p->sex);

p=p->next;

}while(p!=NULL);

动态分配存储:

void *malloc(unsigned int size);在内存的动态存储区中分配一个长度为size的连续空间,此函数的值(即返回值)是一个指向分配域起始地址的指针(类型为void),如果分配不成功则返回空指针。

void *calloc(unsigned n,unsigned size);在内存的动态存储区分配n个长度为size的连续空间,可以用来为一位数组开辟动态存储空间,n为数组元素个数,每个元素长度为size

void free(void *p);释放由p指向的内存区,使这部分内存区能被其他变量使用。

动态建立链表

#define LEN sizeof(struct student)

#define NULL 0

struct student {

int num;

char sex;

struct student *next;

};

struct student *creat(void)

{

struct student *head;

struct student *p1,p2;

p1=p2=(struct student *)malloc(LEN);

head = NULL;

scanf("%d,%c",&p1->num,&p1->sex);

while(p->num!=0)

{

n = n+1;

if(n==1) head=p1;

else p2->next=p1;

p2 = p1;

p1 = (struct student*)malloc(LEN);

scanf("%d,%c",&p1->num,&p1->sex);

}

p2->next=NULL;

return (head);

}

void main

{

creat();

}

      共用体类型:几种不同类型的变量存放到同一段内存单元中。

枚举类型:如果变量只有几种可能的值,将变量的值一一列举出来

声明enum weekday{sun,mon,tue,wed,thu,fri,sat};

定义 enum weekday workday,week_end;

用typedef定义类型

用typedef声明新的类型名来代替已有的类型名

typedef int COUNT;COUNT i,j;

typedef long COUNT;便于移植

typedef struct {

int month;

int day

}DATE;

DATE birthday;

位运算

位段:C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为位段或者位域(bit field)eg:

struct packed_data{

unsigned a:2;

unsigned b:4;

unsigned c:6;

unsigned d:2;

int i;

}data;

其中a,b,c,d分别占2位,4位,6位,2位。i为整数,共占4个字节

struct packed_data data;

data.a = 2;注意位段可以赋的最大值,为2位最大值是3,所以data.a=8是错误的

data.b=7;

注意:

位段成员的类型必须指定为unsigned或int类型




指针:地址

变量的指针:变量的地址

指针变量:存放地址的变量

定义指针:基类型 *指针变量名  在定义指针变量时必须指定基类型,一个指针变量只能指向同一个类型的变量。

Eg:

 voidswap(int *p1,int *p2)

{

int temp;

temp = *p1;

*p1 = *p2;

*p2 = temp

}

void main()

{

int a,b;

int *pointer_1,*pointer_2;//定义

icanf(“%d,%d”,&a,&b);

pointer_1 = &a;pointer_2=&b;//赋地址

if(a<b) swap(pointer_1,pointer_2);

printf(“%d,%d\r\n”,a,b);

}

数组与指针:

Eg:

void sort(int x[],int n)  或者void sort(int*x,int n)

void main(){int *p,a[10];  p =a ;sort(p,10);}

字符串与指针:

char a[]=”l love china”;

char *a = “I love china”;

char a[10]; char *p=a;

指向函数的指针变量:数据类型(*指针变量名)(函数参数列表):每一个函数都占用一段内存单元,他们有一个起始地址。函数名代表该函数入口。

int add (int x,int y)

void process(int a,inty,int(*fun)(int,int))

{

int result = (*fun)(x,y);

}

void main()

{

int a,b;

scanf(“%d,%d”,&a,&b);

process(a,b,add);

}

返回指针值的函数

类型名 *函数名(参数列表)

int *a(int x,int y);

eg:

float *search(float (*pointer)[4])

{

int i;

foat *pt;

pt = *(pointer + 1):

for (i=0;i<4;i++)

{

  if(*(*pointer + i)<60) pt = *pointer;

return (pt);

}

}

void main()

{

float score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};

float *search(float (* pointer)[4]);

float *p;

int I,j;

for(i=0;i<3;i++)

  {

  p =search(score+i);

 if(p == *(score+i))

{

 printf(“No.%d scores:”,i);

 for (j=0;j<4;j++)

   Printf(“%5.2f”,*(p+j));

}

}

}

指针数组和指向指针的指针

指针数组:其元素是指针类型数据,每一个元素相当于一个指针变量

类型名 *数组名[数组长度]

char *name[]={“follow”,”success”,”great”};

指向指针的指针:指向指针数据的指针变量

char **p

char *name[]={“follow”,”success”,”great”};

p=name+i;

指针数组做main函数的形参

void main(int argc,char*argv[])

main函数由操作系统调用的,argc指命令行中参数的个数,argv是一个指向字符串的指针数组。Main函数的形参不一定命名为argc和argv,可以是任意的名字,只是人们习惯了argc和argv。argc指命令行中参数的个数

echo命令实现:

echo.c:

#include <stdio.h>

void main (int argc,char *argv[])

{

  while(--argc>0)

printf(“%s%c”,*++argv,(argc>1)?’’:’\n’);

}

echo computer and c language

输出 computer and c language

argc为5, arcgv[0]:echo ,argv[1]:computer

void main()

{

char *p;

scanf("%s",p);

}

没有对p赋值就引用它是错误的,应该改为:

void main()

{

char *p,c[20];

p=c;

scanf("%s",p);

}

void main()

{

char c[20];

printf("%c",c++);  错误c是数组名,是首地址,是固定的。应该用指针char *p=c;p++;

}







猜你喜欢

转载自blog.csdn.net/rinezy/article/details/80566427
今日推荐