有关指针的数据类型的小结
定义 |
含义 |
int i; |
定义整型变量i |
int *p; |
p为指向整型数据的指针变量 |
int a[n]; |
定义整型数组a,它有n个元素 |
int *p[n]; |
定义指针数组p,它由n个指向整型数据的指针元素组成 |
int (*p)[n]; |
p为指向含n个元素的一维数组的指针变量 |
int f(); |
f为带回整型函数值的函数 |
int *p(); |
p为带回一个指针的函数,该指针指向整型数据 |
int (*p)(); |
p为指向函数的指针,该函数返回一个整型值 |
int **p; |
p是一个指针变量,它指向一个指向整型数据的指针变量 |
指针运算小结
一、指针变量加(减)一个整数
例如:p++、p--、p+i、p-i、p+=i、p-=i等。
二、指针变量赋值
将一个变量地址赋给一个指针变量。如:
p=&a; (将变量a的地址赋给p)
p=array; (将数组array首元素地址赋给p)
p=&array[i];(将数组array第i个元素 的地址赋给p)
p=max;(max为已定义的函数,将ma x的入口地址赋给p)
p1=p2;(p1和p2都是指针变量,将 p2的值赋给p1)
三、指针变量可以有空值,即该指针变量不指向任何变量,可以这样表示:p=NULL;
四、两个指针变量可以相减
如果两个指针变量都指向同一个数组中的元素,则两个指针变量值之差是两个指针之间的元素个数
五、两个指针变量比较
若两个指针指向同一个数组的元素,则可以进行比较。指向前面的元素的指针变量“小于”指向后面元素的指针变量。
关于 void类型
void真正发挥的作用在于:
(1) 对函数返回的限定;
(2) 对函数参数的限定。
例如:void abc( void );
谈谈 void类型用于指针!
void指针 和 const指针
ANSI C新标准增加了一种“void”指针类型,即不指定它是指向哪一种类型数据的指针变量。
例如:void *p;
表示指针变量p不指向一个确定的类型数据,它的作用仅仅是用来存放一个地址。
void指针它可以指向任何类型数据。也就是说,可以用任何类型的指针直接给void指针赋值。但是,如果需要将void指针的值赋给其他类型的指针,则需要进行强制类型转换。
三个例子谈谈const
#include <stdio.h>
void main(void)
{
const char *str = "Welcome to csdn.net!\n\n";
// 这个语句的含义是:声明一个名为str的指针变量,
// 它指向一个字符型常量,初始化str为指向字符串
// "Welcome to Fishc.com!\n\n"
printf("\n\n%s", str);
#if (0)
str[0] = 'w'; //这条语句是错误的,但可以改变str指针的值
#endif
str = "I love csdn.net!\n\n"; //合法!
printf("\n\n%s", str);
}
#include <stdio.h>
void main(void)
{
char * const str = "Welcome to csdn.net!\n\n";
// 常量指针是一个固定的指针,不可以改变它的值,但它所指的数据可以改变。
str[0] = 'w'; //合法!
//虽然合法,但是在windows下是禁止常量被重写的。
#if( 0 )
str = "I love scdn.net!\n\n"; //非法!!
#endif
printf("\n\n%s", str);
}
#include <stdio.h>
void main(void)
{
const char * const str = "Welcome to csdn.net!\n\n";
// 常量指针是一个固定的指针,不可以改变它的值,但它所指的数据可以改变。
str[0] = 'w'; //非法!
str = "I love scdn,net!\n\n"; //非法!!
printf("\n\n%s", str);
}
最后我们看看 memcpy
/* MEMCPY.C: Illustrate overlapping copy: memmove
* handles it correctly; memcpy does not.
*/
#include <memory.h>
#include <string.h>
#include <stdio.h>
char string1[60] = "The quick brown dog jumps over the lazy fox";
char string2[60] = "The quick brown fox jumps over the lazy dog";
/* 1 2 3 4 5
* 12345678901234567890123456789012345678901234567890
*/
void main(void)
{
printf("Function:\tmemcpy without overlap\n");
printf("Source:\t\t%s\n", string1 + 40);
printf("Destination:\t%s\n", string1 + 16);
memcpy(string1 + 16, string1 + 40, 3);
printf("Result:\t\t%s\n", string1);
printf("Length:\t\t%d characters\n\n", strlen(string1));
/* Restore string1 to original contents */
memcpy(string1 + 16, string2 + 40, 3);
printf("Function:\tmemmove with overlap\n");
printf("Source:\t\t%s\n", string2 + 4);
printf("Destination:\t%s\n", string2 + 10);
memmove(string2 + 10, string2 + 4, 40);
printf("Result:\t\t%s\n", string2);
printf("Length:\t\t%d characters\n\n", strlen(string2));
printf("Function:\tmemcpy with overlap\n");
printf("Source:\t\t%s\n", string1 + 4);
printf("Destination:\t%s\n", string1 + 10);
memcpy(string1 + 10, string1 + 4, 40);
printf("Result:\t\t%s\n", string1);
printf("Length:\t\t%d characters\n\n", strlen(string1));
}