指针的总结(2)

目录


1.指针与const的结合

2.类型重命名

3.指针内容

4.输入输出函数


一.指针与const的结合

int *const p :p指针的指向不能改变

int const*p以及const int *p:p指向的地址空间的取值不能改变

int const* const p :p指向的地址空间的取值和p指针的指向都不能改变。

举例:

const和一级指针的结合

const int a=1;
const int b=1;
/*
int*p=&a;  
*p=10;
error,a不可以更改,不可通过解引用的方式改变a的值
*/
const int*p=&a;//正确写法
const int*q=&a;
q=&b;
/*
int*const s=&a;
s=&b;
*s=20;
error,a不可以更改,不可通过解引用改变a的值;int *const s=&a;即s的值也不可更改
*/
const int* const t=&a;
//t的指向内容,t本身的元素值均不可以更改
/*
*t=10;
t=&b;    error
*/

const和二级指针的结合

//a,b不为常变量
int a=0;
int b=0;
const int*p=&a;
int *const q=&b;
const int**s=&p;
int* const *t=&q;
const int* const *z=&p;
//*p=10;  error 由于const int*p=&a;p指向a的取值不能改变,即a的值不能改变
p=&b;
*s=&b;
//**s=2; error **s为a的值,不可改变
//*t=&a;  error 由于int*const q=&b;即q的值不可改变
**t=3;
//*z=&a; **z=4; error 由于const int* const *z=&p;即p和a的值均不能改变


//a,b为常变量
const int a=0;
const int b=0;
const int*p=&a;
//int*const q=&b;  error  b的值不可改变
const int*q=&b;
const int**s=&p;
//int* const*t=&q;  error b的值不可改
const int **t=&q;
const int* const *z=&p;
//*p=10; error a的值不可改变
p=&b;
*s=&b;
//**s=2; error a的值不可改变
*t=&a;
//**t=3;   error  b的值不可改

二.类型重命名typedef

类型重命名:给一个已有的数据类型声明一个新名字。新名字是数据类型的别名。

 1.简单地用一个新的类型名代替原有的类型名

例如:typedef int tnteger;//指定用integer为类型名,作用与int相同

typedef float Real;//指定用Real为类型名,作用与float相同

typedef int count;//指定count代表int

count i,j;//用count定义变量i和j,相当于int i.j;

将变量i,j定义为count类型,而count等价于int,因此i,j是整形。在程序中将i,j定义为count类型,可以使人更一目了然地知道它们是用于计数的。

2.命名一个简单的类型名代替复杂的类型表示方法

有些类型行书复杂,难以理解,容易写错。C允许程序设计者用一个简单的名字代替复杂的类型形式。

(1)先按定义变量的方法写出定义体(如 int i;)

(2)将变量名换成新类型名(例如:将i换成count)

(3)在最前面加typedef(例如:typedef int count)

(4)然后可以用新类型名去定义变量。

                                                       ——摘自《C程序设计》

举例: 

char *p;   //定义变量p

char * String ;  //用新类型名取代p

typedef char*String;   //加typedef

String p;  //用新类型名定义变量,相当于char*p;

注意:

(1)用typedef只是对已经存在的类型指定一个新的类型名。

(2)typedef和#define 

#define 是在预编译时处理的,只能作简单的字符串替换。typedef 是在编译阶段处理的

(3)当不同源文件中用到同一类型数据,常用typedef声明一些数据类型。可以把typedef名称声明单独放到一个头文件中,需要时再用#include指令调出。

三.指针内容

(1)一级指针/二级指针;

(2)数组指针:指向数组的指针

定义形式: int (*p)[];

注意:

[]的优先级高于*,加括号表面p是一个指针;

在32位操作系统下,任何类型的指针所占内存大小都为4个字节。

//定义一个指针,指针+1,+1个整形,即增加4个字节
int *s=&arr[0][0];
s++;
//定义一个指针,指针+1,+4个整形,即16个字节
int arr[3][4];
int(*p)[4]=arr;
//等价于 int(*p)[4]=&arr[0];
p++;
//定义一个指针,指针+1,+12个整形,即48个字节
int (*w)[3][4]=&arr;
w++;
//&arr,二维数组首元素地址的地址(三级指针)

(3)指针数组:一个保存指针类型数据的数组

定义形式:int(*p)[10];

int*int*int*int*int*int*int*int*int*int*
const char*arr[5]={"hello","world"};
//    类型  数组(存储数据)  指针类型的数组
const char*p=arr[0];//指向“hello”中的h
printf("%c\n",p+1)
//输出结果为:“ello”
const char**p=&arr[0];
printf("%c\n",*(p+1));//指向“hello”
//输出结果为:“world”

 

(4)函数指针:指向函数的指针

typedef int (*PFUN)(int, int);

int add(int a, int b) {
	return a + b;
}
int mul(int a, int b) {
	return a * b;
} 

int main() {
    int a, b;
	char op[10] = {0};  //"+"  "*"
	scanf("%d%d",&a,&b);
	scanf("%s", &op);
	定义一个函数指针,指向add  指向mul
	if (strcmp(op,"+") == 0) {
		pfun = add;
	}
     else {
		pfun = mul;
	}
	int result = pfun(a, b);
	printf("%d\n",result);
}

四.输入输出函数

(1)字符输入输出getchar/putchar

一般形式:

char ch;

ch=getchar();

putchar(字符数据);

(2)字符串输入输出函数gets/puts

char arr[20];

gets(arr);

puts(字符串);

(3)scanf和printf

printf一般形式:printf(格式控制,输出表);

scanf一般形式:scanf(格式控制,地址表);

注意:再用%c格式符时,空格字符和转义字符都会被当做有效字符输出

int main(){
int a;
char c;
scanf("%d",&a);
printf("%d\n",a);
/*
scanf("%c",&c);
printf("%c\n",c);
输入输出整形之后直接进行字符型的输入输出程序无法进入这一步,因为“\n”会被当做有效字符读取
*/
//正确方法:在输入输出之前加一个getchar();将“\n”丢弃
getchar();
scanf("%c",&c);
printf("%c\n",c);
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值