指针数组函数(new)

指针函数数组字符串(new)

一、指针数组

指针数组:为数组,每个元素都是指针

数组指针:为指针,指向数组的指针

(1)指针数组

#include <stdio.h>

int main(int argc,char argv[])
{
 	int a[3]={0,1,2};
    //指针数组
    int *p[3];
    p[0]=&a[0];
    p[0]=a;
    
    p[1]=&a[1];
    p[1]=a+1;
    
    p[2]=&a[2];
    p[2]=a+2;
    
    int n=sizeof(p)/sizeof(p[0]);
    int i=0;
    for(i=0;i<n;i++)
    {
        p[i]=&a[i];//a+i
    }
    for(i=0;i<n;i++)
    {
        printf("%d\n",*p[i]);
    }
    
    return 0;
}

二、指针和函数

(1)函数形参改变实参的值

#include <stdio.h>

void swap(int m,int n);
{
    int tmp;
    tmp=m;
    m=n;
    n=tmp;
    printf("m=%d,n=%d\n",m,n);
}

int main(int argc,char *argv[])
{
    int a=11;
    int b=22;
    
    swap(a,b);//swap()函数调研完毕,m,n,tmp自动释放。值传递,形参的修改不会影响到实参
    printf("a=%d,b=%d\n",a,b);
}
//没有实现交换a,b
#include <stdio.h>

void swap(int *m,int *n)
{
	int tmp;
    tmp=*m;
    *m=*n;
    *n=tmp;
}

int main(int argc,char *argv[])
{
    int a=11;
    int b=22;
    
    //swap(a,b);值传递,不管这个变量是什么类型,只有是变量本身传递,就是值传递
    
    swap2(&a,&b);//地址传递,变量的地址
    printf("a=%d,b=%d\n",a,b);
}

(2)数组名做函数参数

#include <stdio.h>

//形参中的数组不是数组,是普通指针变量
//形参数组:int a[10000],int a[],int *a对编译器而已没有任何区别,都是当作int *处理
//形参中的数组和非形参数组区别:形参中数组是指针变量,非形参数组就是数组
//void printf_array(int a[])
void printf_array(int *a)
{
    int i=0;
    int n=sizeof(a)/sizeof(a[0]);
    for(i=0;i<n;i++)
    {
        printf("%d,",a[i]);
    }
    printf("\n");
    
    a=NULL;//形参中的数组,不是数组,是普通指针变量
}

void printf_array2(int *a,int n)
{
    int i=0;
   
    for(i=0;i<n;i++)
    {
        printf("%d,",a[i]);
    }
    printf("\n");
}

int main()
{
    int a[]={1,-2,3,-4,5,-6,7,-8,9};
   // printf_array(a);//传递的是数组的首元素地址,&a[0]
    
    int n=sizeof(a)/sizeof(a[0]);
    printf_array2(a,n);//应该把数组元素个数传递过去
}

(3)返回局部变量的地址

//int *fun()//返回值是指针类型

#include <stdio.h>

int *fun()
{
    int a;
    
    return &a;
}

int main(int argc,char *argv[])
{
    int *p=NULL;
    
    p=fun();//接收函数返回的地址
    *p=100;//操作指针所指向的内存
    
    return 0;
}

(4)返回全局变量的地址

//放在{}外面定义的变量就是全局变量,全局变量在任何地方都能使用
//全局变量只有在整个程序结束后才释放
#include <stdio.h>

int a;

int *fun()
{
    return &a;//fun()调用完毕,a不释放
}

int main(int argc,char *argv[])
{
    int *p=NULL;
    p=fun();
    
    *p=100;
    printf("*p=%d\n",*p);
}

二、字符串

(1)字符串的打印说明

#include <stdio.h>

int main(int argc,char *argv[])
{
    char str[]="hello mike";
    //printf("str=%s\n",str);
    //%s是从首元素开始打印,直到结束符位置
    //%s操作的是指针所指向的内容
    
    //str是首元素的地址,如果想要打印str本身的值,可以用%p,%x,%d,%o
    
    printf("str=%p\n",str);
    
    //*str代表第0个元素,是char类型
    //printf("str3=%s\n",*str);//err
    printf("str3=%c\n",*str);
    
    int i=0;
    while(str[i]!='\0')
    {
        printf("%c",str[i]);
        i++;
    }
    printf("\n");
}

(3)字符指针

#include <Stdio.h>

int main(int argc,char *argv[])
{
    char str[]="hello";
    
    str[0]='1';
    *(str+1)='2';
    printf("str=%s\n",str);//12llo
    
    //定义一个指针,指向首元素
    char *p=NULL;
    p=&str[0];
    //或p=str;//数组名就是首元素地址
    
    *p='a';
    p++;
    *p='b';
    printf("str=%s\n",str);//abll0
    printf("p=%s\n",p);/bllo
}

(4)字符串拷贝

#include <stdio.h>
#include <string.h>

int main01(int argc,char *argv[])
{
    char *p;
    //不是给p变量拷贝内容
    //给p所指向的内存拷贝内容
    //p是野指针,给野指针所指向的内存拷贝内容,结果导致段错误
    strcpy(p,"hello mike abc");
}

int main()
{
    char buf[100];
    char *p=buf;
    //p指向buf的首元素
    //strcpy()是给p所指向的内存拷贝内容,字符串拷贝给了buf
    strcpy(p,"hello mike abc");
    
    printf("p=%s,buf=%s\n",p,buf);
    
    return 0;
}

(5)const修饰的字符指针

#inlude <stdio.h>

int main(int argc,char *argv[])
{
    char buf[]="hello";
    char *p1=buf;
    *p1='a';//改变指针所指向的内存
    p1=NULL;//改变指针变量本身
    
    //const修饰*,指针所指向的内存不能修改
    const char *p2=buf;
    *p2='a';//err
    p2=NULL;//ok
    
    
}

(6)字符串常量

#include <stdio.h>

int main(int argc,char *argv[])
{
    //每个字符串都是一个地址,这个地址就是指字符串首元素地址
    //字符串常量放在date区,文字常量区
    //字符串常量就是此字符串的首元素地址
    
    printf("s1=%s\n","hello mike");//hello mike代表首元素地址
    printf("s1=%p\n","hello mike");
    printf("s3=%s\n","hello mike"+1);//ello mike
    
    //字符串常量。文字常量区的字符串,只读,不能修改
    
}

(7)字符串常量初始化问题

#include <stdio.h>

int main(int argc,char *argv[])
{
    //p指针保存了hello的地址
    //指针所指向的内存不能修改
    char *p="hello";
    
    //把"hello"一个一个字符放在buf数组中
    //数组的元素可以修改
    char buf[]="hello";
    
    return 0;
}

(8)查找匹配字符串出现的次数

#include <stdio.h>

int main()
{
    char *p="11abcd111122abcd1111abcd1111abcd";
    int i=0;
    chat *tmp=NULL;
    
    while(1)
    {
        //查找匹配字符串,如果找到,返回匹配字符串的地址,没有找到返回空
        tmp=strstr(p,"abcd");
        if(tmp==NULL)//没有找
        {
            break;
        }
        else//找到
        {
            i++;//累加
            
            //重新设置寻找的起点
            p=tmp+strlen("abcd");
        }
    }
}

(9)两头堵模型

#include <stdio.h>

int main(int argc,char *argv[])
{
    char *p="       123445678     ";
    char *start=p;//首元素地址
    char *end=p+strlen(p)-1;//尾元素地址
    
    //从左往右
    while(*start==' '&&*start!='\0')
    {
        start++;
    }
    
    //从右往左
    while(*end=='  '&&end!=p)
    {
        end--;
    }
    
    int n=end-start+1;
    printf("n=%d\n",n);
    
    char buf[100]="aaaaaaaaaaaaaa";
    strncpy(buf,start,n)
    buf[n]=0;//结束符
    printf("buf=%s\n",buf);
}

三、main形参使用说明

#include <stdio.h>

//argv[]:是数组,数组每个元素都是char *,每个元素都是字符地址
//argc:argv[]元素个数
//main()函数参数,需要用户传递
int main(int argc,char *argv[])
{
    int i=0;
    for(i=0;i<argc;i++)
    {
        printf("%s\n",argv[i]);
    }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
函数的定义 什么是函数? •函数就是定义在类中的具有特定功能的一段独立小程序。 •函数也称为方法。 函数的格式: •修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,...) { 执行语句; return 返回值; } 返回值类型:函数运行后的结果的数据类型。 参数类型:是形式参数的数据类型。 形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。 实际参数:传递给形式参数的具体数值。 return:用于结束函数。 返回值:该函数运算后的结果,该结果会返回给调用者。 函数的特点 定义函数可以将功能代码进行封装 便于对该功能进行复用 函数只有被调用才会被执行 函数的出现提高了代码的复用性 对于函数没有具体返回值的情况,返回值类型用关键字void表示, 那么该函数中的return语句如果在最后一行可以省略不写。 注意: •函数中只能调用函数,不可以在函数内部定义函数。 •定义函数时,函数的结果应该返回给调用者,交由调用者处理。 函数的应用 两个明确 •明确要定义的功能最后的结果是什么? •明确在定义该功能的过程中,是否需要未知内容参与运算 示例: •需求:定义一个功能,可以实现两个整数的加法运算。 •分析: •该功能的运算结果是什么?两个数的和,也是一个整数(int) •在实现该功能的过程中是否有未知内容参与运算?加数和被加数是不确定的。(两个参数int,int) •代码: int getSum(int x,int y) { return x+y; } 函数的重载(overload) 重载的概念 在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。 重载的特点: 与返回值类型无关,只看参数列表。 重载的好处: 方便于阅读,优化了程序设计。 重载示例: //返回两个整数的和 int add(int x,int y){return x+y;} //返回三个整数的和 int add(int x,int y,int z){return x+y+z;} //返回两个小数的和 double add(double x,double y){return x+y;} 函数的功能一样,仅仅是参与运算的未知内容不同时, 可以定义多函数,却使用统一函数名称,这样方便阅读。 在调用时,虚拟机通过参数列表的不同来区分同名函数数组 数组的定义 概念 同一种类型数据的集合。其实数组就是一个容器。 数组的好处 可以自动给数组中的元素从0开始编号,方便操作这些元素。 格式1: 元素类型[]  数组名 = new 元素类型[元素个数或数组长度]; 示例:int[] arr = new int[5]; 格式2: 元素类型[] 数组名 = new 元素类型[]{元素,元素,……}; int[] arr = new int[]{3,5,1,7}; int[] arr = {3,5,1,7}; 数组内存结构 内存结构 Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因 为每一片区域都有特定的处理数据方式和内存管理方式。 栈内存   用于存储局部变量,当数据使用完,所占空间会自动释放。 堆内存   数组和对象,通过new建立的实例都存放在堆内存中。   每一个实体都有内存地址值   实体中的变量都有默认初始化值   实体不在被使用,会在不确定的时间内被垃圾回收器回收 方法区,本地方法区,寄存器 数组操作常见问题   数组脚标越界异常(ArrayIndexOutOfBoundsException) int[] arr = new int[2]; System.out.println(arr[3]); 访问到了数组中的不存在的脚标时发生。   空指针异常(NullPointerException) int[] arr = null; System.out.println(arr[0]); arr引用没有指向实体,却在操作实体中的元素时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值