c课堂笔记 day-4

作业讲解:

(1) 将2~100之间的素数 保存到数组中,并遍历输出,每五行一个
#include<stdio.h>
#define N 50
int main()
{
int arr[N];

                    int i=2;
                    int j=0;
                    int k=0;
                    for(i=2;i<100;++i)
                    {
                      for(j=2;j<i;j++)
                      {
                  //从2开始遍历,查找能被i整除的数,
                 //若找到则跳出内层循环
                          if(i%j==0)
                          
                                break;
                       }   
                  //若i==j,则i是素数,否则不是
                         if(i==j)
                          {
                                arr[k]=i;
                                k++;
                                printf("%4d",i);
                                if(k%5==0)
                                printf("\n");
                          }
                      } 
                   

                }

(2) 在一个升序或降序排列的数组中,插入一个元素;提示:数组元素部分初始化

(按升序或降序)至少空一个位置存放要插入的数据。
插入元素后,仍然是按升序或降序排列
#include<stdio.h>
int main()
{
int arr[5]={10,9,12,8};
int i,j,k,temp;
printf("插入一个数:\n");
for(i=0;i<5;i++)
if(arr[i]==0)
scanf("%d",&arr[i]);
for(k=0;k<5;k++)
{
for(j=0;j<5;j++)
{
if(arr[k]<arr[j])
{
temp=arr[j];
arr[j]=arr[k];
arr[k]=temp;
}

                  }
            }
            for(i=0;i<5;i++)
            printf("%4d  ",arr[i]);  
        }

(3)互换数

            #include<stdio.h>
            int main()
            {
                int arr[5];
                int i,temp;
                printf("请输入五位数:\n");
                for(i=0;i<5;i++)
                scanf("%d",&arr[i]);
                   temp=arr[0];
                   arr[0]=arr[4];
                   arr[4]=temp;
                   
                   temp=arr[1];
                   arr[1]=arr[3];
                   arr[3]=temp;
                   
                for(i=0;i<5;i++)
                printf("%d\n",arr[i]);
                
            } 

一、数组

1、二维数组
    行数可以省略,列不可以省!!
    #include<stdio.h>
    int main()
    {
       //以下初始方法均可
       int arr[][3]={1,2,3,4,5,6,7,8,9};
       //int arr[3][3]={1,2,3,4,5,6,7,8,9};
       //int arr[][3]={1,2,3,4,5};
       //int arr[][3]={0};
       //遍历输出二维数组
       int i=0;
       int j=0;
       for(i=0;i<3;i++)
       {
            for(j=0;j<3;j++)
            {
                arr[i][j]=3*i+1;
                //或者手动输入
                //scanf("%d",arr[i][j]);
            }
             
       }
       
       
       for(i=0;i<3;i++)
       {
            for(j=0;j<3;j++)
            {
            //printf("arr[%d][%d]=%d",i,j,arr[i][j]);
                printf("%4d",arr[i][j]);
            }
             printf("\n");
       }
    }

求二维数组的总和余平均值

        #include<stdio.h>
        int main()
        {
           int arr[][3]={1,2,3,4,5,6,7,8,9};
           int i,j,sum=0;
           float k=0;
           for(i=0;i<3;i++)
              for(j=0;j<3;j++)
              {
                 sum=sum+arr[i][j];
              }
              k=(float)sum/9;
              printf("sum=%d k=%f\n",sum,k);
            printf("===========================\n");  
           //每行 的总和即平均值
           int sum1=0;
           float k1=0; //平均值
           for(i=0;i<3;i++)
           {
              sum1=0;
              for(j=0;j<3;j++)
              {
                 sum1=sum1+arr[i][j];
              }
              k1=(float)sum1/3;
              printf("sum1=%d k1=%f\n",sum1,k1);
              
            }
            printf("===========================\n"); 
            //每列  的总和即平均值
           int sum2=0;
           float k2=0; //平均值  
           for(i=0;i<3;i++)
           {
              sum2=0;
              for(j=0;j<3;j++)
              {
                 sum2=sum2+arr[j][i];
              }
              k2=(float)sum2/3;
              printf("sum2=%d k2=%f\n",sum2,k2);
            }
              
        }

二、指针

(1) 指针类型是一种特殊类型
三种定义类型:
DataType name;
DataType
name;
DataType * name;
*:是指针的标志
name: 变量名
指针和普通变量的区别:
指针:存地址
普通变量:存值
指针只能保存与其相同类型的地址
int *p; 只能保存int 型地址
char *pc; 只能保存char 型地址
double *pd; 只能保存double 型地址

(2) 指针初始化

int *p=NULL; //ok

int a=3; //ok
int *pa=&a;

int *pb; //ok
pb=&a;

int ****pc; //这种赋值error
*pc=&a;

            #include<stdio.h>
            int main()
            {
                int num=6;
                //NULL是一个空地址 是一个宏
                int *pa=NULL;
                
                int *pb=&num; 把num 的地址赋给pb, 
                    *号是取pb指向地址里面的值
                
                int *pc;
                pc=&num;
                
                int *pb;  //错误 不能这样赋值
                *pb=&num;
                
                地址的访问
                
                //地址
                printf("&num=%p\n",&num);
                printf("pb=%p\n",pb);
                
                //元素的访问
                printf("num=%d\n",num);
                //*+pb是取地址的值 而pb里面是&num的地址,
                printf("*pb=%d\n",*pb); 
                
            }

(3) 地址的访问

           int a=10;
           int *pb;
           pb=&a;
           变量名    变量地址   变量值
             a        0x00012    10
             pb       0x00024   0x000012
             
             *pb:取指针对应内存里面的值
             可以把指针变量赋值给同类型指针
            #include<stdio.h>
            int main()
            {
               int *p=NULL;
             //  printf("*p=%p\n",p);
               //空地址不能访问里面的值
      //  printf("*p=%d\n",p);//error内存泄漏  核心转储   
               int a=10;
               int *pa=&a;
               printf("&a=%p\n",&a);
               printf("p=%p\n",p);
               printf("&p=%p",&pa);
               
               
               printf("a=%d\n",a);
               printf("*pa=%d\n",*pa);
            }


            #include<stdio.h>
            int main()
            {
         int *p=10; //error  不能将常量直接赋值给指针变量
               printf("p=%p\n",p);
        printf("*p=%d\n",*p);//内存中并未分配0xa这块内存
               
               int a=12;
               int *pa=&a;
               int *pb;
               pb=pa;
               //可以把指针变量赋值给同类型指针
               
               printf("pa=%p\n",pa);
               printf("pb=%p\n",pb);
               printf("*pa=%d\n",*pa);
               printf("*pa=%d\n",*pa);
               
               
     //强制类型转化  临时转化 并不改变pa的属性
               char *pc=(char *)pa;
               printf("*pc=%d\n",*pc);
               
            }

(4) 64位机下所有指针大小为8 32位机为4

一般情况写4
#include<stdio.h>
int main()
{
   printf("sizeof(char *)=%ld\n",sizeof(char *));
   printf("sizeof(short *)=%ld\n",sizeof(short *));   
   printf("sizeof(int *)=%ld\n",sizeof(int *));
   printf("sizeof(long *)=%ld\n",sizeof(long *));
   printf("sizeof(float *)=%ld\n",sizeof(float *));
   printf("sizeof(double *)=%ld\n",sizeof(double *));
}
结果:
    sizeof(char *)=8
    sizeof(short *)=8
    sizeof(int *)=8
    sizeof(long *)=8
    sizeof(float *)=8
    sizeof(double *)=8

(5) 指针的类型和指针所指向的类型
int pa;
double pd;
指针的类型: 是类型+
如 int *
指针所指向的类型 :就是类型 int
一句话就是指针的类型int
指向的是int类型

二、 指针与数组

       (1)  数组名是一个地址
         数组元素的访问的方法:
            int arr[5]={1,2,3,4,5};
            int *pa=arr;
            
            arr[0];  arr[3];
            *(arr);  *(arr+3);
            *(pa);   *(pa+3);
            pa[0];   pa[3]; 

            #include<stdio.h>
            int main()
            {
                int arr[5]={1,2,3,4,5};
                //数组名表示的是一个地址
                int *pa=arr;
                printf("===========================\n");
                printf("arr=%p\n",arr);
                printf("&arr[0]=%p\n",&arr[0]);
                printf("pa=%p\n",pa);
                printf("===========================\n");
                //地址是一样的
                printf("arr+1=%p\n",arr+1);
                printf("pa+1=%p\n",pa+1);
                //地址是一样的
                printf("===========================\n");
                printf("arr+2=%p\n",arr+2);
                printf("pa+2=%p\n",pa+2);
                //地址里面的值是一样的
                printf("===========================\n");
                printf("*(arr+2)=%d\n",*(arr+2));
                printf("*(pa+2)=%d\n",*(pa+2));
            }    
           
           
            #include<stdio.h>
            int main()
            {
                int arr[5]={1,2,3,4,5};
                //数组名表示的是一个地址

                int *pa=arr;
                 //数组元素的访问
                printf("arr[0]=%d\n",arr[0]);
                //指针对数组元素的访问
                printf("pa[0]=%d\n",pa[0]);
                
                printf("arr[4]=%d\n",arr[4]);
                printf("pa[4]=%d\n",pa[4]);
               
            }


            #include<stdio.h>
            int main()
            {
                char arr[16]={"hello,shanghai!"};
                //数组名表示的是一个地址
                char *pc = arr;
                
                for(pc=arr;pc<arr+16;pc++)
                {
                    if(*pc>='a' && *pc<='z')
                         *pc -= 32;
                 }
                 pc=arr;
                printf("%s\n",pc);
                 
            } 

(2) 野指针

           没有初始化,或者其指向的内存被释放,
           而指针没有被置空
           
           危害:造成系统资源的浪费,容易造成未知的致命错误
            #include<stdio.h>
            int main()
            {
                int num = 10;
                int *pa = &num;
                printf("*pa=%d\n",*pa);
                
                
                int *pb;
                //error ,未经初始化而使用,容易出现段错误
                printf("*pb = %d\n",*pb);
                
            }

(3) 指针地址的运算

            指针的自增和自减
            自增:指针指向高地址方向
            自减:指针指向低地值方向
            #include<stdio.h>
            int main()
            {
                int arr[5]={1,2,3,4,5};
                int *p = arr+3;
                
                printf("arr+3=%p\n",arr+3);
                printf("p=%p\n",p);
                
                p--;
                printf("p-- = %p\n",p);
                
                p++;
                printf("p++ = %p\n",p);
                
                
            }
            
            #include<stdio.h>
            int main()
            {
                int a=10;
                int b=34;
                
                int *pa=&a;
                int *pb=&b;
                //指针相减,表示两指针之间的距离
                printf("pa-pb=%ld\n",pa-pb);
                //指针相加没有意义
                printf("pa+pb=%ld\n",pa+pb);
                
            } 

1、两个类型相同的指针相加毫无意义。
比如p1和p2都是类型为int的指针,
虽然他们指向的内存中保存了两
个int数N1和N2,但是这两个数在内存中
可能挨着,也可以能间隔很远,甚至有
可能是一个地方。假设p1值也就
是N1位置起始值为1234,P2为2345,这个时候如果直接相加得到的数据
3589有可能已经超出了内存最大值或者指向某个无意义的内存地址,所以
指针相加没有意义可言。正确的应该是N1和N2相加才是合理的算数运算。

2、指针可以相减,可以和立即数加或减,是有意义的,是允许的。比如我想知道N1和N2之间到底间隔了多少字节的内存,两者相减就相当于尺子上两个刻度相减,也就是长度或者宽度了。另外,和立即数的加减主来快速寻址,比如我有一个数组,起始指针为P0,如果数组保存的是一系列INT值那么 P0+2*sizeof(int)得到的值就是第三个元素的所在位置的地址,也是一个
指针,是有意义的(因为不同的语言和系统,int值每次所占的字节数可能不一致,
所以使用sizeof函数去求得而不是直接加常规的4)。

(3) 指针加减一个常量,表示地址往高字节或底字节方向移动

                 常量值*sizeof(对应数据类型)个字节
                 
                 
              (4) 概念区分
                  int arr[3];
                  //数组大小为3,存放三个int型变量
                  int *pb;
                  //指针,棋类型为int *型
                  int *arr[3];
                  //指针数组  具体是什么看后面的两个字
                  
                  int (*pa)[3]; 
                  //首先是指针 后是数组  所以是
                    数组指针,又称 行指针
                    
                    #include<stdio.h>
                    int main()
                    {
                        int arr[4]={1,2,3,4};
                        int *buf[4];
                        int (*pa)[4];
                        int i=0;
                        for(i=0;i<4;i++)
                        {
                           buf[i]=&arr[i];
                        }
                        pa=&arr;
                        printf("%d\n",*buf[2]);  =3
                        printf("%d\n",(*pa)[1]); =2
                        
                    } 

2.二级指针

 DataType **PointorName;
 
 int a = 10;
 
 int *q = &a;
 
 int **p = &q;
 
 *p=q;
 **p=*q=a;
 定义一个指针,
 或对地址进行操作时,
 一定要确定指针的指向
    #include<stdio.h>
    int main()
    {
        int a=10;
        int *p=&a;
        int **pa=&p;
        
        printf("&a=%p\n",&a);
        printf("p=%p\n",p);
        printf("&p=%p\n",&p);
        printf("pa=%p\n",&pa);
        
        printf("*p=%d\n",*p);
        printf("**pa=%d\n",**pa);
        
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 作业整理; 指针的基本的结构与基础知识整理; 作业讲解:(1) 将2~100之间的素数 保存到数组中,并遍历输出,...
    比莉吉恩阅读 368评论 0 0
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,430评论 3 44
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,513评论 1 51
  • 一、框架 1、Mac系统及常用工具、进制;C数据类型、常量变量、运算符、表达式、格式化输入输出 2、关系运算符、逻...
    师景福阅读 685评论 0 1
  • 今天继续来聊聊L小姐的故事。 自从L小姐与男友分手后的这一年来,她变了很多。就像微博上狂刷不停的热点一样,通常男女...
    水木梁鱼阅读 562评论 0 3