指针是一个值为内存地址的变量(数据对象)
间接运算符,解引用运算符 *,后跟一个指针名或者地址时 *给出存储在指针指向地址上的值。
指针的声明:类型说明符 * 指针名:类型说明符表面了指针所指向对象的类型表明了声明的变量是个指针。
- 所有的指针类型存储的都是一个无符号16进制整型数
- 在32位操作系统下所有指针类型大小的32,在64为os下为64位
- 在定义指针类型一定要和变量对应上,指针回去找 类型*的大小的内存单元
野指针和空指针:
int* p=100;//把100这个地址给了p,这个就是野指针,即指针变量指向一个未知的空间。
程序可能会报错,因为,os把地址0-255作为系统占用,就是中断处理
不建议将一个变量的值直接复制给野指针。
空指针:内存地址编号为0的空间
int* p=NULL;
万能指针:
void* 可以指向任何类型的变量
const修饰的指针变量:
指向常量的指针
1.修饰*,指针指向内存区域不能修改,指针指向可以变
const int* p1 =&a;//等价于 int const* p1=&a;
指针常量
2.修饰ptr ,指针指向不能变,指针指向的内存可以改变
int* const ptr =&a;
在编辑程序时,指针作为函数参数,
如果不想修改指针对应内存空间的值,
需要使用const修饰指针数据类型。
函数、数组、指针
数组名是数组首元素的地址,所以当函数是传入数组名时,
函数的形式参数要定义成一个指针。
如:int sum(int ar,int n),int sum(int ar[],int n),int ar形式和int ar[]形式都表示ar
是一个指向int的指针。但是,int ar[]只能用于声明形式参数。第二种形式,挺像指针ar指向的不仅仅
一个int类型,还是一个int类型数组的元素。
以下原型都是等价的:
int sum(int ar,int n)
int sum(int,int)
int sum(int ar[],int n)
int sum(int [],int)
但是在函数定义中不能省略参数名
注意:
创建一个指针是,系统值分配了存储指针本身的内存,
并为分配存储数据的内存。因此在使用指针前,必须先用已经分配的地址初始它。
#include<stdio.h>
#define SIZE 10
int sum(int ar[], int n);
int sump(int* start, int* end);//使用指针算法
int main0(void)
{
int marbles[SIZE] = { 20,10,5,23,34,2,124,43,122,23 };
long answer;
//answer = sum(marbles, SIZE);
answer = sump(marbles, marbles + SIZE);
printf("The total number of marbles is %ld.\n", answer);
printf("The size of marbles is %zd bytes.\n", sizeof marbles);
return 0;
}
int sum(int ar[], int n)
{
int i;
int total = 0;
for (i = 0; i < n; i++)
total += ar[i];
printf("The size of ar is %zd bytes.\n", sizeof ar);
return total;
}
int sump(int* start, int* end)
{
int total = 0;
while (start < end)
{
total += *start;
start++;
}
return total;
}
//指针的操作
int main(void)
{
int urn[5] = { 100,200,300,400,500 };
int* ptr1, * ptr2, * ptr3;
ptr1 = urn;//把一个地址赋给指针
ptr2 = &urn[2];//把一个地址赋给指针
//解引用指针,以获得指针的地址
printf("pointer value,dereferenced poiter,ponter address:\n");
printf("ptr1=%p,*ptr1=%d,&ptr1=%p\n", ptr1, *ptr1, &ptr1);
//指针加法
ptr3 = ptr1 + 4;
printf("\nadding an int to a piinter:\n");
printf("ptr1+4=%p,*(ptr1+4)=%d\n", ptr1 + 4, *(ptr1 + 4));
ptr1++;//递增指针
printf("\nvalues after ptr1++:\n");
printf("ptr1=%p,*ptr1=%d,&ptr1=%p\n", ptr1, *ptr1, &ptr1);
ptr2--;//递减指针
printf("\nvalues after ptr--+:\n");
printf("ptr2=%p,*ptr2=%d,&ptr2=%p\n", ptr2, *ptr2, &ptr2);
--ptr1;//恢复为初始值
++ptr2;//恢复为初始值
printf("\nPointers reset to original values:\n");
printf("ptr1=%p,ptr2=%p\n", ptr1, ptr2);
//一个指针减去另一个指针
printf("\nsubtracting one pointer from another:\n");
printf("ptr2=%p,ptr1=%p,ptr2-ptr1=%td\n", ptr2, ptr1, ptr2 = ptr1);
//一个指针减去一个整数
printf("\nsubtracting an int from a poiter:\n");
printf("ptr3=%p,ptr3-2=%p\n", ptr3, ptr3 - 2);
return 0;
}