C语言指针的一些问题

const变量,const的使用是c语言中一个比较微妙的地方。

首先是const变量定义的方式,它有两种定义方式

第一种定义方式 const在类型的前面

const int var = 100;

第二种定义的方式 const在类型的后面

int const var1 = 999;

两种定义的方式没有区别

const变量在定义的时候进行初始化

当一个变量声明为const变量,意味着该变量是一个常量,不可以被修改(const只能做右值不能做左值)

const指针  也叫做常指针

1.在声明的时候进行初始化 

2.指针不能再指向别的变量,指针的value不可更改

3.可以通过指针来修改变量的值

(1)const指针指向的是const变量

根据编译器不同  window不可修改

(2)const指针指向非const变量

可以修改

pointer to constants 指向常量的指针

1. 指向常量的指针 防止通过指针去修改变量的值 不管该变量是否为const

2. 指向常量的指针 该指针可以指向别的变量,指针的value是可以更改的

指针本身不是const

3.指向常量的指针  不能赋值给一个普通的指针

 

 

如果一个变量只有几种可能的值,则可以定义为枚举类型,所谓的枚举就是把可能的值都一一列举出来,变量的值只限于列举出来的值的范围内。

声明枚举类型用enum开头。

例如:enum Weekday{sun,mon,tue,wed,thu,fri,sat};//声明一个枚举类型 enum Weekday

      Enum Weekday workday,weekday;//枚举类型  枚举变量

Enum Weekday{sun,mon,tue,wed,thu,fri,sat}day;

Enum {sun,mon,tue,wed,thu,fri,sat}day;

 /*花括号中的sun,mon......称为 枚举元素或枚举常量。枚举变量和其它数值类型 量不同,它们的值只限于花括号中指定的值之一。

   */

  weekday=mon;//正确 指定的枚举常量之一

  weekday=sun;//正确 同上

  weekday=Monday;//错误 Monday 不是指定的枚举常量之一

1、C编译对枚举类型的枚举元素按常量处理,所以叫做 枚举常量不能因为他们是标识符而把它们看作变量,不能对它们赋值

2、每一个枚举元素都代表一个整数,C语言编译按定义时的顺序默认它们的值为0,1,2...

在上面的定义中,sun的值为0,mon的值为1如果有赋值语句:workday=mon;相当于workday=1;枚举常量是可以引用和输出的。例如printf("%d",workday);输出结果是1

3、枚举元素可以用来作判断比较。

 

不掌握指针,就是没有掌握C的精华。。。

指针是什么

如果程序定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。内存去的每一个字节有一个编号,这就是“地址”,它相当于教室的门牌号。在地址所标志的内存单元中存放的数据则相当于教室里面上课的学生。由于通过地址能找到所需的变量单元,所以,地址指向该变量单元。例如,一个教室的门口挂着门牌号是311,这个311就是教室的地址,即311“指向”该教室,因此,将地址形象化地称为“指针”。意思是通过他们能找到以他为地址的内存单元。

一个变量的地址成为该变量的指针;

一个变量专门用来存放另一个变量的地址(指针),称为指针变量

指针变量

存放地址的变量是指针变量,它用来指向另一个对象(如变量、数组、函数等)。

1、             定义指针变量:

类型名* 指针变量名

如:int* pointer

左端的int是在定义指针变量时必须指定的“基类型”。指针变量的基类型用来指定此指针变量可以指向的变量的类型。

a)指针变量前面的“*”表示该变量的类型为指针型变量。指针变量名是pointer而不是*pointer

b)在定义指针变量时必须指定基类型。一个指针变量只能指向同一个类型的变量,而不能忽而指向一个整型变量,忽而指向一个实型变量

c)指针变量中只能存放地址(指针),不能将一个整数赋给一个指针变量

2、怎样引用指针变量

a)给指针变量赋值。如:int*p;p=&a;。指针变量p的值是变量a的地址,p指向a

b)引用指针变量指向的变量。如果已经执行“p=&a;”,即指针变量p指向了整型变量a,则printf("%d",*p);其作用是以整数形式输出指针变量p所指向的变量的值,即变量a的值

c)引用指针变量的值。如:printf("%o",p);其作用是以八进制数的形式输出指针变量p的值,如果p指向了a,就是输出a的地址,即&a.

d)注意要熟练掌握两个有关的运算符:&:取地址运算符 ;*指针运算符

3、指针变量作为函数参数:

函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量地址传送到另一个函数中

通过指针引用数组

1、数组元素的指针:一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,他们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一个元素的地址放到一个指针变量中),所谓数组元素的指针就是数组元素的地址

2、在引用数组元素时指针的运算:在指针指向数组元素时,可以对指针进行如下运算

加一个整数(用+或+=),如p+1;

减一个整数(用-或-=) 如p-1:

自加运算,如p++,++p;

自减运算,如p--,--p;

两个指针相减,如p1-p2(只有p1和p2都指向统一数组中的元素时才有意义):

a)如果指针变量P已经指向数组中的一个元素,则P+1执行同一数组中的下一个元素,p-1则指向同一数组中的上一个元素

b)如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,它们指向a数组序号为i的元素

c)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i]

d)如果指针变量p1和p2都指向同一数组,如执行p2-p1,结果是p2-p1的值(两个地址之差)初一数组元素的长度,两个地址不能相加

3、通过指针引用数组元素

a)数组元素的指针就是数组元素的地址,数组名不代表整个数组,只代表数组首元素的地址

b)指针指向数组元素时,可以对指针进行运算。

1)如果指针bianliangp已经指向数组中 一个元素,则p+1指向同一个数组中的下一个元素,p-1指向同一个数组中的上一个元素。当执行p+1时并不是将p的值(地址)简单的加1,而是加上一个数组元素所占用的字节数。

2)如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,即他们指向a数组序号为i的元素

3)如果指针变量p1和p2都指向同一个数组,如果执行p2-p1,结果是p2-p1的值(两个地址的差)除以数组元素的长度

4)*p++和*++p和++*p的区别:*p++等价于*(p++),先引用p的值,实现*p的运算,然后在使p自增加1;*++p先使p加1,在取*p。例如:如果p的初值为a(即a[0]),若输出*(p++),得到a[0]的值,如果输出*(++p),得到的是a[1]的值;++(*p).表示p所指向的元素值加1,如果p=a,,则++(*p)相当于++a[0],如果a[0]的值为3,则在执行++(*p)后a[0]的值为4.

c)通过指针引用多维数组:指针变量可以指向一维数组,也可以指向多维数组

4、通过指针引用字符串

a)      字符串的引用方式:

在c程序中,字符串是存放在字符数组中的。想引用一个字符串,可以用一下两种方式:

1)用字符数组存放一个字符串,可以通过数组名和下标引用字符串中的一个字符,也可以通过数组名和格式声明“%s”输出该字符串。

2)用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。

b)字符指针作函数参数:

如果想把一个字符串从一个函数“传递“到另一个函数,可以用地址传递的方法,即用字符数组名作参数,也可以用字符指针变量做参数。

c)字符指针变量和字符数组的比较:

1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第一个字符的地址),绝不是将字符串放到字符指针变量中

2)可以对字符指针变量赋值,但不能对数组名赋值

3)编译时为字符数组分配若干存储单元,以妨各元素的值,而对字符指针变量,只分配一个存储单元

4)指针变量的值是可以改变的,而数组名代表一个固定的值(数组首元素的地址),不能改变

5)字符数组中个元素的值是可以改变的,但字符指针变量指向的字符串常量中的内容是不能改变的

6)用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串。例如:char* format; format="a=%d,b=%f\n";printf(format,a,b);它等价于printf("a=%d,b=%f\n",a,b);

 

1、引用定义前是必须存在的,指针不用。

传参数的时候,如果传的是引用,那就意味着已经存在了,而指针是不存在的。

指针的传递没有引用传递的安全。

引用方式的实现是通过指针来完成的。

传指针的效率比传引用的效率要高一些。

2、常量指针:不能通过该指针去修改指针 , 可以指向别的常量。不能通过该指针去修改指针指向的内存空间的值。

常指针:,该指针的值是不可修改的,不能在指向别的变

量。常指针可以赋值给一个普通指针。

3、形参对实参的一个拷贝;返回值可以返回一个值,一个引用,一个指针。有一个临时的变量用来保存返回的值,函数的返回值不能是一个数组,不能返回本地变量的指针和引用。

4、intstrcmp(const char * s1, const char * s2) 比较字符串s1和s2,小于、等于、大于分别返回负值、0、正值

5、intstrncmp(const char * s1, const char * s2, size_t n) 比较字符串s1和s2的n个字符,结果同strcmp(不比较'\0'后的字符)

6、char * strpbrk(const char * s1, const char * s2) 返回指向s1中首次出现s2中字符的位置的指针,没有返回NULL

7、结构体类型数据的定义方法和引用方法
定义结构体:struct 结构体名
{
成员列表
};
定义结构体类型的变量:有三种形式
① 定义类型时定义变量:struct 结构体类型名
{
成员列表
}变量名列表;
② 直接定义结构类型变量:struct
{
成员列表
}变量名列表;
③ 由已定义的结构体类型来定义变量:struct 结构体类型名变量名列表;
引用结构体类型变量:在定义了结构体类型变量后,采用下列方法引用结构体类型的
变量:
结构体变量名.成员名
这里"."是成员(分量)运算符,它在所有的运算符中优先级最高。
使用结构体时注意:
(1)结构体类型和结构体类型变量是不同的概念,定义结构体类型变量时应先定义
结构体类型,然后再定义变量属于该类型。
(2)定义了—个结构体类型后,系统并没有为所定义的各成员项分配相应的存储空
间。只有定义了一个结构体类型变量,系统才为所定义的变量分配相应的存储空间。结构
体类型变量占用内存的字节数是所有成员占用内存长度之和。

(3)结构体成员的引用。如果一个结构体中又嵌套一个结构体,则要访问一个成员时,应采取外层向内层逐级访问的方法。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值