C-09 指针基本知识(1)



Hightlight

1.1  自我理解的指针概念

1.2  如果用不同类型的数据来赋值指针

1.3  野指针

1.4  悬空指针

1.5  地址(指针)作为参数

1.6  数组作为形参

1.7  常量指针和指针常量

1.8  举例: 排序一组数据 数据都是const类型 不能改变数据的情况下排序

1.9  主方法参数

1.10  strcmp()函数

1.11  二级指针

1.12  Void* 类型

1.13  Assignment



1. 指针基本知识
  1.1  自我理解的指针概念

       保存地址的变量叫指针
       指针作为数据用的时候 指针就是地址
  

  1.2  如果用不同类型的数据来赋值指针

  1 #include <stdio.h>
  2
  3 int main(){
  4     char x[8]={‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘,‘g‘};
  5     char* p1=&x[0];
  6     char* p2=&x[2];
  7     int * p3=&x[3];
  8     printf("%X\n",*p3);
  9     return 0;
 10 }

    产生警告信息
     *p3的打印结果 其实是从d到g的int值
      |a|b|c|d|e|f|g|h|.....
             ^         ^
             |<- P3->|

   1.3  野指针
    野指针 没有赋值的指针
      避免野指针 任何定以后的指针都加等号=去赋值
    
    0的特殊含义
      --->  ‘\0’
      --->  逻辑判断里的假
    --->  用在指针里表示空地址 0 =NULL

  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     int a[5]={11,22,33,44,55};
  6     int *p;                            //野指针,尽量避面,用空指针代替
  7     printf("%p\n",p);
  8     printf("%d\n",(3>5));
  9     int *q =0;                        //初始化指针为空指针
 10     printf("%p\n",q);
 11 /*****************************************************/
 12 //打印指针的每一个字节
 13     #define T int *
 14     union {
 15         T x;
 16         char b[sizeof(T)];
 17     }u;
 18     u.x=q;
 19     int i;
 20     for(i=0;i<sizeof(T);i++)
 21     {
 22         printf("%d ",u.b[i]);
 23         }
 24     printf("\n");
 25     *p=100;                            //访问野指针    可能引发segmentation fault
 26
 27     p=a;                            //数组当做数据用的时候表示第一个元素的地址
 28 /*****************************/
 29     for(i=0;i<5;i++)
 30         printf("%d ",a[i]);
 31     printf("\n");
 32
 33     for(i=0;i<5;i++)
 34         printf("%d ",*(a+i));        //数组名加上一个下标加上一个整数 就是以那个整数为下表的元素的地址
                                        //数组名加几就表示以几位下表元素的地址
 35     printf("\n");
 36
 37     for(i=0;i<5;i++) printf("%d ",p[i]);printf("\n");      // 11 22 33 44 55
 38
 39     for(i=0;i<5;i++) printf("%d ",*(p+i)); printf("\n");    // 11 22 33 44 55
 40
 41     for(i=0;i<5;i++) printf("%d ",*p+i); printf("\n");      // 11 12 13 14 15
 42
 43     for(i=0;i<5;i++) printf("%d ",*p++); printf("\n");      // 11 22 33 44 55
 44
 45     for(i=0;i<5;i++) printf("%d ",p[i]); printf("\n");      //-1081417716 1 0 0 -712421632

        11    22    33    44    55
        p                          P                

 46
 47     for(i=-5;i<0;i++) printf("%d ",p[i]); printf("\n");     // 11 22 33 44 55
 48    
 49     for(i=0;i++;i<5) printf("%d ", *p--); printf("\n");     // -1079573188 55 44 33 22
 50     for(i=0;i<5;i++) printf("%d ", *--p); printf("\n");     // 55 44 33 22 11
 51     return 0;
 52 }

数组指针用法:

    p[i] = *[p+i] ==*p++ (但是之后的指针移动到最后一次++的位置)

    p[i-1] = *p--

  1.4 悬空指针

  保存了可能已经消失的地址的指针 成为悬空指针

   不要返回不通局部变量的地址 除非加上static

  1 #include <stdio.h>
  2
  3 char* func()
  4 {
  5     char a=‘#‘;
  6     return &a;        //返回局部变量指针 Warning!
                        // 保存了可能已经消失的地址的指针                         成为悬空指针        除非加上static
  7     }
  8
  9 int main()
 10 {
 11     char c=‘@‘;
 12     char *p =&c;
 13     *p=‘S‘;
 14     printf("c=%c\n",c);
 15     printf("*p=%c\n",*p);
 16     p=func();        //指向一个可能已经不存在的地方(或者是释放过的地方)
 17     printf("*p=%c\n",*p);
 18     return 0;
 19     }

 1.5 地址(指针)作为参数

  注意1:指针本身并不是关注本身,所以指针在使用时 基本都要到*号

       想要目标单位交换时候 要操作目标本身 而不是指针。

  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     int a=10, b=20;
  6     //  int* p=&a, q=&b;    //需要注意q是int类型 编译报错
  7     int x,y[5],*p=&a, *q=&b;
  8     //int t=a;a=b;b=t;
  9     int t=*p;*p=*q;*q=t;
 10     printf("%d, %d\n",a,b);
 11
 12     int m=10, n=20;
 13     int* u=&m, *v=&n;
 14     int *w=u;u=v;v=w;
 15     printf("%d, %d\n",m ,n);  // 为何m,n的值不变?  要想目标发生变化需要操作目标本身 而不是指针。
                                //int *w=u(&m);            u=v(&n);        v=w(&m);    其实是指针w和v交换了 但是目标m和n没有交换。
 16
 17     return 0;
 18     }

  c语言里面参数传递永远是值传递

    --->f2()传递的是地址 地址传递

  1 #include <stdio.h>
  2
  3 void f1(int *p, int *q){
  4     int *t=p;p=q;q=t;
  5 }
  6
  7 void f2(int* p,int *q){
  8     int t=*p;*p=*q;*q=t;    
  9 }
 10
 11 void f3(int a, int b){
 12     int t=a;a=b;b=t;
 13 }

 15  int main()
 16 {
 32     printf("aa=%d, bb=%d\n",aa,bb);
 33     f1(&aa,&bb);printf("f1()---> aa=%d, bb=%d\n",aa,bb);
 34
 35     f2(&aa,&bb);printf("f2()---> aa=%d, bb=%d\n",aa,bb);
 36
 37     f3(aa,bb);printf("f3()---> aa=%d, bb=%d\n",aa,bb);
 38     return 0;
 39     }

  1.6 数组作为形参

  ---当数组做为形参时候 其实传递的是数组首地址的指针~

        任何类型的指针计算sizeof都是4个字节

  1 #include <stdio.h>
  2
  3 show(double a[], int n)
  4 {
  5     double x=123.45;
  6     printf("sizeof[a]=%d\n",sizeof(a));     //a其实是一个指针 输出结果为4
  7     a=&x;
  8     printf("*a=%g\n",*a);
  9 }
 10
 11 void print(double *p, int n)
 12 {
 13     int i;
 14     for(i=0;i<n;i++){
 15         printf("a[%d]=%g ",i,*(p+i));  //*(p+i))==p[i]
 16         }printf("\n");
 17     }
 18
 19 int main()
 20 {
 21     double a[5]={1,2,3,4,5};
 22     show(a,5);
 23     print(a,5);
 24
 25     char al[3]={‘a‘,‘b‘,‘c‘};
 26     printf("sizeof[al]=%d\n",sizeof(al));   \\al是一个数组 所以大小是3 有3个char类型的变量在al数组里
 27     char *t=&al[0];
 28     printf("sizeof(t)=%d\n",sizeof(t));     \\ 这里问的仅仅是t这个指针的sizeof值 任何指针的sizeof都是4
 29
 30     return 0;
 31     }

1.7 常量指针和指针常量

---->  字符串: 从指定位置开始 以空字符“\0”结束的字符数组。

---->  const char *p (或者 char const* p)  

            不会通过指针修改数据,指针p保存字符常量的地址

---->  char * const r =a+1;  

            r是一个const类型的指针 所指向的内容可以修改 但是指针本身不能修改 必须初始化

 1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     char a[100]={‘h‘,‘e‘,‘\0‘,‘w‘,‘o‘};  //如果把字符数组当做字符串来使用的话 只到反斜杠0
  6                 //"csd1007" 这样一个字符串其实是在只读存储区里保存一个8个字节的char类型
                    // const char[8]={‘c‘,‘s‘,‘d‘,‘1‘,‘0‘,‘0‘,‘7‘,‘\0‘}
  7     puts(a);    //输出缓冲区遇到反斜杠0之后就结束
  8     puts("csd1007");
  10     char* p=a;
 11     printf("%c\n",*p);
 12     *p=‘w‘; 
 13     puts(a);
 14
 15     p="csd1007";
 16     printf("%c\n",*p);
 17
 18     *p=‘w‘;                   //修改const类型数据,导致运行的core dump
 19     const char* q=NULL;      // q是保存字符常量, 指针q所指的字符目标当做常量    不会通过指针修改目标的数据
 20     q="csd1007";              //只是把字符串的首地址赋值给指针, 并不是复制字符串
 21     *q=‘w‘;                   // 编译报错
 22
 24     p=a; 25     strcpy(a,"NB"); 26     puts(p); 27  28     q=a+3;                  // 29     puts(q); 30      31     char* const r=a+1;        //r是一个const类型的指针 所指向的内容可以修改 但是指针本身不能修改 32     //r=a;                    //编译错误 33     puts(a); 34     *r=‘A‘; 35     puts(a); 36           //  危险代码如下 37     char * str;               //str首先是野指针 38     scanf("%s",str);           // scanf把输入的数据的地址放到str去, 如果str是const类型 可能导致段错误 39     strcpy(str,"hello");       //  同上 40     return 0; 41     }            

1.8  例子: 排序一组数据 数据都是const类型 不能改变数据的情况下排序

  -->通常指针只能保存地址 地址也只能被指针来保存

  -->数组名仅仅表示起始地址

  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     char* names[9]={"Hejunjun","yangYong","WangGang","LongWang","SSSS5555","SSS666","77","888","9999"};
  6
  7     int i;
  8     for(i=0;i<9;i++){
  9         printf("welcome the following guys %s\n",*(names+i));
 10     }
 11     /*数组不变的情况下排序*/
 12     const int a=10,b=80,c=20,d=60,e=98,f=76;
 13     const int * p[6]={&a,&b,&c,&d,&e,&f};
 14     int j;
 15     for(i=0;i<6;i++){
 16         for(j=i+1;j<6;j++){
 17             if(*p[j]<*p[i]){
 18                 const int * t=p[j];p[j]=p[i];p[i]=t;
 19                 }
 20         }
 21     }
 22     for(i=0;i<6;i++){
 23         printf("%d\n",*p[i]);
 24     }
 25
 26     return 0;
 27     }

1.9 主方法参数

  int main(int argc,char* argv[])

  argc--> 一共几个字符串

  char* argv[] -->  存每个字符串的首地址

1.10 strcmp()函数

  atoi()

  atof();

  strcmp();

 1.11 二级指针

  保存指针的地址的变量 称为二级指针

需要简介修改指针的值,需要修改指针的指向的时候

  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     char c;
  6     char* pc;
  7     int n;
  8     int * pn;
  9     short s;
 10     short* ps;
 11     double d=1.23;
 12     double * pd=&d;
 13     double** pp=&pd;
 14
 15     printf("&c=%p\n",&c);
 16     printf("&pc=%p\n",&pc);
 17     printf("&n=%p\n",&n);
 18     printf("&pn=%p\n",&pn);
 19     printf("&s=%p\n",&s);
 20     printf("&ps=%p\n",&ps);
 21     printf("&d=%p\n",&d);
 22     printf("&pd=%p\n",&pd);
 23     printf("&pp=%p\n",&pp);        //pp是一个指向double* 变量的指针
 24
 25     return 0;
 26     }

一个数字字符减去字符0 (‘0’), 就得到数字  ‘3’-‘0’=3

一个数字加上字符0 (‘0’), 就得到数字字符

  1 #include <stdio.h>
  2 #include <ctype.h>
  3
  4 int str2int(const char* str, const char** q)    //2级指针,想改变p的位置
  5 {
  6     int r=0;
  7     while(isdigit(*str)){
  8         r=r*10+*str-‘0‘;
  9         ++str;
 10         }
 11     *q=str;
 12     return r;
 13     }
 14
 15 int main()
 16 {
 17     const char* p=NULL;
 18     int n= str2int("3926abxys",&p);
 19     printf("number=%d, p=%s\n",n,p);
 20     return 0;
 21     }    

 1.12 Void* 类型

 1 #include <stdio.h>
  2
  3 void showbyte(void* addr, int byte)    //void*不能直接取变量 使用时候必须做类型转换
  4 {
  5     int i;
  6     while(bytes-->0)
  7         printf("%02x ",*(unsigned char*) addr++);
  8     printf("\n");
  9     }
 10
 11 int main(){
 12     int n=1234567890;
 13     float f=1234567890;
 14     double d =1234567890;
 15     short s=1234567890;
 16
 17     //  printf("%x,%hs\n",n,s);
 18     showbyte(&n,sizeof(n));
 19     showbyte(&f,sizeof(f));
 20     showbyte(&d,sizeof(d));
 21     showbyte(&s,sizeof(s));
 22     return 0;
 23     }

Assignment:

1. 指针基本用来处理字符串

2. 写一个函数用来统计一个字符串中是否是数字字符串。

isdigitstr("123"):1, isdigitstr("asfw“):0, isdigitstr("12f"):0

3. 写一个函数用来统计一个字符串中是否是实数字符串。

isreal("12.3"):1,isreal("-45"):1,isreal("ase"):0,isreal("1.ew")

4. 写一个函数用来把一个字符串用制定的字符作为分隔符 分割成若干个字符子串 并且输出

substr("abc:de:fghi:jk",‘:‘) 输出

abc  de  fghi  jk

5. 一个函数用来返回一个字符串中重复出现的最长子串的长度以及开始位置。

const char* P = NULL;

int len=maxsubstr("qweohiuweyowohifpw",&p)

len3, p是"ohi"的地址

printf("len=%d,substr=%s\n",len,p)

输出len=3,substr=ohifpw

时间: 2024-10-25 16:49:12

C-09 指针基本知识(1)的相关文章

二级指针基础知识

/* ============================================================================ Name : TestDoublePointer.c Author : lf Version : Copyright : Your copyright notice Description : 二级指针基础知识 ================================================================

Boost智能指针-基础知识

简单介绍 内存管理一直是 C++ 一个比較繁琐的问题,而智能指针却能够非常好的解决问题,在初始化时就已经预定了删除.排解了后顾之忧.1998年修订的第一版C++标准仅仅提供了一种智能指针:std::auto_ptr(现以废弃),它基本上就像是个普通的指针:通过地址来訪问一个动态分配的对象. std::auto_ptr之所以被看作是智能指针.是由于它会在析构的时候调用delete操作符来自己主动释放所包括的对象. 当然这要求在初始化的时候,传给它一个由new操作符返回的对象的地址.既然std::a

指针基础知识

1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int num = 20; 7 int *p = &num; //存储num的地址 8 cout<< num <<endl; 9 cout<< p <<endl; //输出指针存储的地址 10 cout<< *p <<endl; //输出指针地址的值 11 return 0; 12 }

指针相关知识

1.指针:内存地址 指针变量:专门用一个变量来存放指针,这种变量成为指针变量.因此,一个指针变量的值就是某个内存单元的地址(或指针) “指针”是指地址,是常量,“指针变量”是指取值为地址的变量 2.二级指针 指针变量中主要存放目标变量的地址,这种指针称为一级指针.如果指针变量中存放的不是变量的地址,而是存放一级指针变量的地址,则这种指针称为二级指针. 格式: [存储类型]  数据类型符    **变量名: 例如: int a=5; int *p1; int **p2; p1=&a; p2=&

【C语言】【指针相关知识小结】

1.int *p = NULL 和 *p = NULL的区别 int *p = NULL指的是将一个指针初始化为NULL,具体过程为 int *p; p = NULL. 2.&a与a的区别 int a[5]; int *p = &a;//?? int *q = a;//?? 这样的代码对吗? 解释: &a得到数组的地址. a表示数组首元素的首地址. &a的a的值一样,两个指向的位置是相同的,但是意义不同. 3.指针和数组的定义与声明 什么是声明和定义: C语言中的对象必须只

对于链表的链式存储的初始化操作,遇到的有关“二级指针”的知识小结

首先解释一下“二级指针”: 一级指针所关联的是其值(一个地址)名下空间里的数据,这个数据可以是任意类型并做任意用途,但二级指针所关联的数据只有一个类型一个用途,就是地址. 指针就是两个用途:提供目标的 读取 或 改写, 那么二级指针就是为了提供对于内存地址的读取或改写. 指针的表现形式是地址,核心是指向关系指针,运算符“*”的作用是按照指向关系访问所指向的对象. 如果存在A指向B的指向关系,则A是B的地址,“*A”表示通过这个指向关系间接访问B. 如果B的值也是一个指针,它指向C,则B是C的地址

StdC--11 指针基本知识(2)

Hightlight 1. Review & summary 2. 指针数组&数组指针(指向数组的指针) 3.数组和字符串 4. 函数指针(指向函数的指针) 5. 堆分配内存 malloc函数 6. 堆分配内存其他相关函数: 6.1 calloc 函数 6.2 realloc 函数   1. Review & summary 1.1 指针作为形参 指针做为函数的形参 得到的是变量的地址 通过地址访问可以访问到原始变量 所以有机会修改到原始数据 (方法就是:对指针加*号 去操作数据)

void指针

1回顶部 热门文章:C++中extern “C”含义深层探索 编程实现盗2005版QQ源码 1.概述 许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误.本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧. 2.void的含义 void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据. void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,让我们试

指针的美丽传说

一.浅谈指针 说起指针,不知道有多少的C学者被这座大山所困住,很多人都说数组是最难学的,但是没想到指针比数组还难.没听多久就完全被绕晕了,什么一级指针啊,二级指针啊,三级指针啊,最后还莫名其妙的出来一个n级指针,就这样一节课下来就完全晕了.当然这里面还包括一些和指针搭配用的伙伴.数组.函数.结构体等等,我接下来说的可能只是指针的皮毛,你们也可以认为是概念,所以我希望你们看看就行,具体还要自己去想. 1.指针是什么呢?说白了其实是地址,说的再通俗点也就是门牌号,因为你如果需要找到某人的家,是否要先