目录
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);
}