码迷,mamicode.com
首页 > 编程语言 > 详细

c语言指针初级

时间:2015-08-30 10:00:43      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:c语言   指针   野指针   空指针   通配型指针   

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;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

c语言指针初级

标签:c语言   指针   野指针   空指针   通配型指针   

原文地址:http://blog.csdn.net/throneman/article/details/48101699

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!