您的位置:首页 > 编程语言 > C语言/C++

c语言指针初级

2015-08-30 09:20 531 查看
1:

/*

 变量能够使用,就要在计算机中存储起来;
 */int main(int argc, const char * argv[])
{
int a=10;//栈上的四个字节;
//&取地址符,&a表示a的地址
printf("a的地址是:%p\n",&a);//打印a的地址 a的地址是:0x7fff5fbff81c
//*间接寻址符
printf("a的地址上的值是:%d\n",*(&a));//打印a的值 a的地址上的值是:10

return 0;
}<span style="color:#e32400;">
</span>

2:

/*

 指针:存储变量的地址的一种变量;

 指针定义: int *p;// *是指针标识,说明p是指针名,int表示指向的数据类型,或者说p保存的是一个int型变量的地址;

 */
int main()
{
int *p;//*只是指针标识
int a=10;
int b=20;
p = &a;//p可以保存一个int型数据的地址;a是一个int,所以p就可以保存a的地址;如果p保存a的地址,就说明p指向a;
printf("p=%p,&a=%p\n",p,&a);
printf("*p = %d\n",*p);//p指向的内容;

*p = 100;//通过地址,修改了地址上的内容;*间接寻址符,取出p地址里的内容;
printf("a=%d\n",a);

p = &b;//p的值变了;p指向的数据变了;p指向了另一个数据;

*p = 200;//修改了指向的内容,b被修改;
printf("a=%d,b=%d\n",a,b);
return 0;

}

int main()
{
int a=10;
int *p = &a;//int *p;*是指针标识,int * 只是说明了p得类型;等价于 int *p ;p=&a;
printf("%d\n",*p);

int *q;//定义了一个指针变量,如果没有指向就是任意的,*q操作可能会异常;指针也要先赋值,后使用(告诉指针指向哪个变量)
//    *q = 100;
printf("*q=%d\n",*q);
return 0;
}

int main()
{
int *p;
//    char *q;//其他的指针类型
//    long *w;
printf("sizeof(p)=%lu\n",sizeof(p));//sizeof(p)=8
printf("sizeof(int *)=%lu\n",sizeof(int *));//sizeof(int *)=8
printf("sizeof(char *)=%lu\n",sizeof(char *));//sizeof(char *)=8
printf("sizeof(long *)=%lu\n",sizeof(long *));//sizeof(long *)=8
printf("sizeof(double *)=%lu\n",sizeof(double *));//sizeof(double *)=8

//各种指针类型在内存中占有的内存都是一样的,在64位系统下都是8字节;
return 0;
}


3:

/*

 指针的运算 ++, --, +, -

 地址的运算;

 */
int main()
{
int a[] = {1,2,3,4,5};//a是数组名,里面保存的是数组首个元素的地址,也就是a=&a[0];
int *p;//p可以保存int型数据的地址;a里面有5个int,p可以指向里面任何一个元素;
//p指向第一个元素a[0]?
p = &a[0];//等价于p=a;
printf("p = %p\n&a[0] = %p\na = %p",p,&a[0],a);//p = 0x7fff5fbff810  &a[0] = 0x7fff5fbff810  a = 0x7fff5fbff810
p++;//p向后偏移了一个int的距离,就是4个字节=p指向的数据类型的大小;
printf("\np = %p\n *p=%d\n",p,*p);//p指向了a[1]  p = 0x7fff5fbff814   *p=2

p = a;
for (int i=0; i<5; i++)//1 2 3 4 5
{
printf("%d ",*p);
p++;
}
p = &a[4];
for (int i=0; i<5; i++)//5 4 3 2 1
{
printf("%d ",*p--);
}
return 0;
}

int main()
{
int a[]={1,2,3,4,5};
int sum = 0;
int *p = a;
p++;//p指向a[1];
printf("%lu\n",p-a);//地址1-地址2:表示两个地址之间可以放几个指向的数据的类型,放几个int;  1
printf("%d \n",*(p-1));//地址-一个数,是一个地址,就是指针往前偏移 N*N个指向的数据类型;    1
p = a;
//通过p+i来遍历数组;p+i = &a[i] ,*(p+i) = a[i];
for(int i=0;i<5;i++)//1 2 3 4 5
{
printf("%d ",*(p+i));
}
p = &a[4];
for(int i=0;i<5;i++)//5 4 3 2 1
{
printf("%d ",*(p-i));
}
p = a;
for(int i=0;i<5;i++)
{
sum += *(p+i);
}
printf("\nsum = %d\n",sum);//sum = 15
return 0;
}


4:

/*

 野指针

 */
int main()
{
int *p;//只定义,没有赋值,指向是任意的,就是野指针;
printf("p=%p\n",p);
*p = 100;//修改了不确定的东西;禁止使用,禁止这样操作,低级错误;
return 0;
}


5:

/*

 空指针:如果p的值=NULL,p就是空指针;

 NULL是个非法地址;  *p既不能读,也不能写;

 指针使用前必须判空;

 

 */
int main()
{
int *p = NULL;
printf("p=%p",p);
//    printf("*p=%d\n",*p);//错误,程序出错
if(p == NULL)
{
printf("p是个空指针不能使用\n");
}
else
{
printf("p合法\n");
}
}


6:

/*

 void * 指针,通配型指针,可以指向任意的数据类型,但是在使用时要注意强制转换成指向的类型;

 */
int main()
{
void *p;
char ch = 'a';
int i=1234;
double b=12.38;
printf("sizeof(p)=%lu\n",sizeof(p));//sizeof(p)=8
p = &ch;//p指向char型的变量
//    printf("%c\n",*p);//编译失败,类型不匹配;
printf("%c\n",*(char *)p);//(char *)是类型说明; a

p = &i;
printf("%d\n",*(int *)p);//1234

p = &b;
printf("%lf\n",*(double *)p);//12.380000

return 0;
}

void swap(int a,int b)//只是形参传递,函数结束即销毁,达不到交换的目的
{
int temp = a;
a = b;
b = temp;
}
void swap_true(int *a,int *b)//地址传递,操作的任然是地址内存储的值,可以达到交换目的
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int x=10,y=20;
swap(x,y);
printf("x=%d,y=%d\n",x,y);//x=10,y=20

swap_true(&x,&y);
printf("x=%d,y=%d\n",x,y);//x=20,y=10
return 0;
}


7:

/*

 数组和指针

 

 数组作为函数的入参传递的时候

 形式参数和实际参数都可以是指针形式或者是数组形式;

 */
void setArray(int a[],int len)//形式参数是数组形式
{
//    printf("sizeof(a)=%lu\n",sizeof(a));//结果为8 a就是个指针,8个字节,只能传递数组的首地址,不能传递元素的个数
for(int i=0;i<len;i++)
{
a[i]=100;
}
}
void printArray(int a[],int len)//形式参数是数组形式
{
for(int i=0;i<len;i++)
{
printf("%d ",a[i]);
}
}
void setArray1(int *a,int len)//形式参数是指针形式
{
//a[0]=*a  &a[0]=a   a[i]=*(a+i)
for(int i=0;i<len;i++)
{
*(a+i)=10;
}
}
int main()
{
int a[5] = {1,2,3,4,5};//a是数组名,保存数组的首地址;数组的名字a可以看成是常量指针;
int *p = a;//p只能指向一个int,指向一个元素,不能指向一个数组;这里p指向的是数组首地址
setArray(a, 5);//实际参数是数组形式
printArray(p,5);//实际参数是指针形式
setArray1(p,5);
printArray(p,5);
printf("%d\n",*(a+2));
return 0;

}


8:

/*

 数组和指针的总结

 1:数组作为函数的入参传递的时候

 形式参数和实际参数都可以是指针形式或者是数组形式;

 形参是数组的时候,其实本质是已经完全是指针变量;

 setArray(int a[],int len)

 这个里面,a就是指针,不能根据它计算元数组元素的个数

 这个里面,a是个变量,可以被赋值,a++是允许的;

 

 2:数组名可以看成是常量指针(指向首个元素的常量指针);  
保存数组的首个元素的地址;

 int a[5];

 此时a不能被赋值,a++就是错误的;

 a[i] = *(a+i) = *(p+i)

 */
//用指针传递数组,进行排序
void sortArray(int *p,int len)//排序
{
for(int i=0;i<len-1;i++)
{
for(int j=0;j<len-i-1;j++)
{
if(*(p+j) > *(p+j+1))
{
int temp = *(p+j);
*(p+j) = *(p+j+1);
*(p+j+1) = temp;
}
}
}
}

void printArray(int *p,int len)//打印
{
for(int i=0;i<len;i++)
{
printf("%d ",*(p+i));
}
}

int printMax(int *p,int len)//找最大值
{
int max = *p;//定义最大值为数组第一个元素
for(int i=0;i<len;i++)
{
if(max < *(p+i))
{
max = *(p+i);
}
}
return max;
}

int main()
{
int a[] = {43,54,32,1,43,67,543,6578,867,64,53,2};
int len = sizeof(a)/sizeof(a[0]);
sortArray(a, len);
printArray(a,len);
printf("\nthe max is %d\n",printMax(a,len));
return 0;
}


9:

/*

 字符数组和指针

 */

/*

 常量字符串和字符数组的差别;

 常量字符串不能改;

 字符数组可以改,字符数组必须要有自己的空间;

 */
int main()
{
char str[100]="helloworld";//常量字符串给变量字符数组赋值;
char *p = "helloworld";//p指向常量字符串,不能通过*p去修改常量字符串;p指向常量字符串里的'h'
//    *p = 'H';//不可修改,p指向常量区,只读,不可写;
printf("%s\n",p);
str[0] = 'H';//str的元素都是char型变量;如果要修改字符,就需要定义成数组形式;
printf("%s\n",str);
return 0;
}

<span style="color:#ff0000;">//通过指针来传递字符数组,不需要传递数组的长度;因为在做字符串处理的时候,字符串本身到'\0'结束</span>
//把小写字母改成大写
#include <string.h>
void convert(char *s)//将小写字母改成大写字母
{
printf("in convert s is %s\n",s);
int len = (int)strlen(s);
for(int i=0;i<len;i++)
{
if(*(s+i)>='a' && *(s+i)<='z')//如果是字母的话就转换
{
*(s+i) -= 'a'-'A';
}
}
}

char * convert(char *s)//一般字符数组需要返回价值
{
char *p = s;
while(*p)//当*p不等于0的时候进入循环
{
if(*p>='a' && *p<='z')
{
*p -= 'a'-'A';
}
p++;
}
return s;
}

int main()
{
char str[100]="helleworld";
convert(str);
printf("in convert s is %s\n",str);
return 0;
}


10:

/*

 "hello"-->"heLLo"替换的目标是给定的  l-->A

 replace(char *s,char old,char new)

 */
char *replace(char *s,char old,char new)
{
char *p = s;
while(*p)
{
if(*p == old)
{
*p = new;
}
p++;
}
return s;
}

//计算字符串的长度,实现strlen的功能;
int myStrlen(char *s)
{
char *p = s;
int count=0;
while(*p)
{
count++;
p++;
}
return count;
}
int main()
{
char str[100] = "helloworld";
replace(str,'l','Y');
printf("%s \n",str);
int len = myStrlen(str);
printf("%d \n",len);
return 0;
}


//字符串里面插入一个字符

//pos表示插入的位置,ch表示插入的字符;
char *insert(char *s,int pos,char ch)
{
int len = (int)strlen(s);
char *p = s;
int count=1;
while(*p)//当*p不等于0的时候进入循环
{

if(pos == len+1)//如果需要插入的元素的位置是字符数组的最后一个位置,也就是'\0'处的时候直接将原'\0'处赋值为目标字符,然后退出循环
{
*(s+len) = ch;
break;
}
if(pos == count)//如果插入的位置为数组中间任意位置的时候进入判断
{
for (int i=len-1; i>=pos-1; i--)//将数组插入位置(包括插入位置)之后到'\0'之前的所有元素往后移位
{
*(s+i+1) = *(s+i);//也就是'\0'之前的第一个元素移位到'\0'位置,依次类推
}
*(s+pos-1) = ch;//将原数组中移动的最后一个元素赋值为需要插入的字符;
break;
}
count++;
p++;
}
return s;
}
int main()
{
char str[100]="helloworld";
insert(str,1,'M');
printf("%s \n",str);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息