【保姆级讲解】C语言---指针精华

指针

1.1 内存地址的理解  

计算机中的存储地址是以字节为单位的一片连续的存储空间,每一块空间都由自己唯一的一个地址编号(非负整数,从1开始自然增长),也叫字节编址。计算机中使用16进制来表示地址编号。

手机128G内存 128是128G字节空间(一个字节为8个位);

这里的0X01 0X02 0X03地址编号类比于生活:主卧床头柜从上第二个抽屉中有块手表

0X01 0X02 0X03(编号) =======主卧床头柜从上第二个抽屉(描述)=====地址值;

0x02地址空间中的数值(8个位空间中内容) == 等同于”手表”;

数据类型/变量/地址描述:

1.2 变量名、变量值和变量地址值

变量名:在定义变量后,编译器会在内存中开辟一个空间(空间大小是根据数据类型进行开辟int 4字节空间 double 8字节空间),变量名就是这个变量所占用内存单元的名字(编程人员提供标识 编译器进行阐述)

变量内容(变量值):就是变量所占内存单元中所表示的数据。可以对变量进行读写操作,读变量就是从这个空间中将变量的值取出来,写变量就是把数值写入到这个变量所占用的内存单元中。

注意:变量内容仅是空间中数值;   10 =100;不能根据内容判定内存中唯一空间   A =100;由于A由编译器绑定了地址所以A能够确定内容中唯一的一块空间;

正在上传…重新上传取消

变量地址: C程序的变量都有自己的数据类型,编译器根据数据类型去开辟对应字节大小的字节空间。所谓的变量地址就是这个字节空间的首地址。

总结:

对于变量地址及变量名都能够确定唯一内存地址空间;对于变量内容不能确定唯一的内存地址空间;

能够确定唯一的内存地址空间的标识/地址,操作者即可以对该空间进行修改/读取内容操作;

1.3指针概述

指针也是一种数据类型(一种地址构造数据类型),32位系统下指针大小位4个字节(32位地址),8位系统下指针大小位3个字节(24位地址),64位系统下指针大小位8个字节(64位地址)。

指针作用:指针变量通常用来保存地址,通过指针可以访问保存在地址中的数据。

不同系统下指针大小区别:

32位系统(32位处理器32根地址线):能够访问2^32次方地址空间:为4GB空间;

采用地址值编号标识4GB空间:需要32位/4字节;

8位系统指针大小3字节; 256字节空间  16位单片机指针大小3字节;

64位系统(处理器64根地址线)寻址地址空间:2^64次方;指针大小为8字节;

总结:指针大小与数据类型无关,它与系统位数有关;

示例1:

Ubuntu16.04  32位系统

Ubuntu16.04  64 位系统

#include <stdio.h>

int main()

{

int *A ;

printf("%u\n",sizeof(A));

return 0;

}

#include <stdio.h>

int main()

{

int *A ;

printf("%u\n",sizeof(A));

return 0;

}

1.4 指针符号

对于指针是构造数据类型(基本数据类型+类似于”关键字”/”特殊的符号”);

&: 取地址符,用于取出指针指向的变量的地址。

*: 取内容符,把地址里的内容取出来(用于取出指针地址中的数值数据)

注意:对于&只能应用于变量名/数组名;不可以&常量值->&10错误;

*使用地址变量/数组能够把指向的空间内容取出;

1.5指针应用

1.5.1指针变量

指针变量定义

在定义变量的时候,在变量名前加上“*”,表示这个变量是一个指针变量。使用“指针类型 变量名”这种格式来定义一个指针变量。

之前变量定义:数据类型  变量名;数据类型有大小影响开辟的空间大小;

现在指针变量定义:指针类型 变量名;指针类型大小(32为例)固定为4字节空间,影响访问内容读取(访问步长);

int *p;在定义语句中,*只是来说明这个变量是一个指针变量,没有实际的意思。

指针类型:使用基本数据类型和星号作为指针变量的指针类型,指针类型中的基本数据类型决定了指针变量所指向的变量的类型。

*: 在定义语句中,*只是来说明这个变量是一个指针变量,没有实际的意思。并不是变量名的一部分,也不是取内容符。

指针变量名:自定义标识符(命名规则同变量)。

指针变量名:可以为大小写英文字母、或者数字、下划线、美元$; 数字不能作为指针变量名开始;不能与关键字重名;

指针变量初始化

在使用指针的时候,一定要进行初始化,避免野指针的出现(没有初始化的局部指针变量为野指针)。使用“指针类型 变量名 = 变量地址或NULL”的格式来对指针变量进行初始化。

注:在使用指针的时候,使用NULL来表示0,指向NULL的指针称之为空指针或指针指向为空。

#include <stdio.h>

int main()

{

int *A ; //A在栈区   野指针

//栈区特点:变量值为随机值(垃圾值)

printf("%u\n",sizeof(A));

printf("%p\n",A);

//*A = 10; //就是对A指向的空间中赋值为10 请问该空间有吗?非法访问

 //段错误 就是地址访问错误   在编译器变量表中没有该地值的空间开辟;

//以上A为野指针

/***********************后期咱们使用******************************/

int B =10;

int *PB =&B;//对于PB指针进行赋值为B空间首地址

printf("B:%p\t PB:%p\t*PB:%d\n",&B,PB,*PB);

int *PC =NULL;//将PC指针指向为空 NULL==(void*)0; //避免野指针

  //系统中0-4K只能读不能写;

printf("PC:%p\n",PC);

return 0;

}

指针变量应用

指针指向变量:

函数传参方面:

写swap(交换)函数:int A =5   int B =6;  编写一个函数实现对AB值进行交换;

#include <stdio.h>

//写swap(交换)函数:int A =5   int B =6;  编写一个函数实现对AB值进行交换;

void swap(int *num1 ,int *num2)

{

int temp = *num1;

*num1  = *num2;

*num2 = temp;

}

int main()

{

int A =5;

int B =6;

printf("A%d  B:%d\n",A,B); //5  6

swap(&A,&B);

printf("swap::A%d  swap::B:%d\n",A,B); //王杰 56  浩林 65

return 0;

}

指向变量的指针

指针变量和普通变量之间的关系

    • 指针变量用来指向(存储)普通变量的地址。à指针就是存储地址的;
    • 可以通过指针变量来操作普通变量空间中的值。
    • 一个变量可以有多个指针变量同时指向,但是一个指针变量每次只能指向一个普通变量。

指针:大小为4字节空间(只能存储一个地址)不能存储多个地址;

指针变量指向的地址(指针保存的地址)是一个变量(在程序运行的过程中可以改变指针的指向),普通变量的地址是一个常量(变量地址不可变)。

注:普通变量可以使用C语言运算符进行运算,但指针变量只能进行+、-、++、--运算,不能做*、/、%运算。

归结指针用法;优势;

1.5.2 指向数组的指针

指针和数组一样,都可以通过变量的下标来访问数组中的各个元素。指针变量+1,指针内存放的地址+n(n由指针指向空间类型决定)。使用“++”运算符来访问数组中的下一个元素,使用“--”运算符来访问数组中的上一个元素。

注:指针配合下标使用时,(例如p=num,p就相当于是数组名,跟数组用法一样)当数组的形式来使用;操作的是指针地址的时候,当指针的形式来用。

#include <stdio.h>

int main()

{

//注:指针配合下标使用时,(例如p=num,p就相当于是数组名,跟数组用法一样)当数组的形式来使用;操作的是指针地址的时候,当指针的形式来用。

int buff[10]={1,2,3,4,5,6,7,8,9,10};

for(int i = 0; i < 10; i++)

{

printf("%d\n",buff[i]);

}

//通过指针也能够实现数组的访问

int *buffP=buff;

for(int i =0; i < 10; i++)

{

printf("P:%d\n",buffP[i]);//当数组的形式来使用  //

printf("PP:%d\n",*buffP++);//当指针的形式来用

//该题会出现基准值改变导致打印位置改变

}

return 0;

}

#include <stdio.h>

//对于连续的空间内容,尽量采用传地址方式解决

void function(int * buff_p)

{

for(int i =0;i < 10; i++)

{

//printf("%d\n",buff_p[i]);  //将指针隐含转为数组名,通过下标访问

printf("%d\n",*buff_p++);  //通过指针偏移访问++

}

}

int main()

{

int inputNumBuff[10]={1,2,3,4,5,6,7,8,9,10};

function(inputNumBuff);

return 0;

}

1.5.3通过C库部分函数了解指针应用

本章节采用libc进行讲解:

/* Copy SRC to DEST.  */

char * strcpy (char *dest, const char *src)    //C库拷贝函数

{

  char c;

  char *s = (char *) src;

  const ptrdiff_t off = dest - s - 1;

  do

    {

      c = *s++;

      s[off] = c;

    }

  while (c != '\0');

  return dest;

}

有时间请静心看一下呦;

1.5.4指向字符串的指针

  1. 指向字符串指针和字符串数组的区别
  2. 指针是一个地址变量,可以指向不同的字符串(指向不同的地址)。
  3. 数组是一个地址常量,只能用固定的地址来保存字符串(地址是个常量)。

1.5.5指向指针的指针

指向指针的指针也称为二级指针,一般是配置指针数组使用。一般情况下很少使用,使用的时候慎用。使用“指针类型 *变量名”的格式来定义一个二级指针。例如:int ** p。

#include <stdio.h>

int main()

{

int A =10;

int *PA =&A;

int ** PPA= &PA;

printf("&A:%p\tA:%d\n",&A,A);

printf("&PA:%p\tPA:%p\n",&PA,PA);

printf("PPA:%p\t*PPA:%p\t**PPA:%d\n",PPA,*PPA,**PPA);

return 0;

}

正在上传…重新上传取消

总结:函数传参方面 一级指针可以做到形参改变实参(普通变量)

二级指针可以做到形参改变实参(一级指针变量)

  函数传参方面:要想改变一级指针所指向的位置需要通过二级指针进行修改;

#include <stdio.h>

//总结:函数传参方面 一级指针可以做到形参改变实参(普通变量)

//  二级指针可以做到形参改变实参(一级指针变量)

void fun(char **a,char **b)

{

char *temp = *a;

*a = *b;

*b = temp;

}

int main()

{

char *PA = NULL;

char *PB = NULL;

char Src1[10]="hello";

char Src2[10]="123456789";

PA = Src1;

PB = Src2;

//置换地址操作 PA = Src1  PB = Src2 --> PA = Src2  PB =Src1;

printf("PA:%s\n",PA);

printf("PB:%s\n",PB);

fun(&PA,&PB);

printf(">PA:%s\n",PA);

printf(">PB:%s\n",PB);

return 0;

}

规律:函数传参 要想形参改变实参(普通变量)采用一级指针方式

                  要想形参改变实参(一级指针)采用二级指针方式;

  1. 二级指针与指针的关系: 

二级指针是指向一级指针的地址(二级指针保存它指向的一级指针的地址)。

*二级指针是取一级指针指向的变量的地址(取得是一级指针保存的地址)。

**二级指针的内容是取一级指针指向的变量地址中的内容(取得是数值)

#include <stdio.h>

int main()

{

int A =10;

int *PA =&A;

int ** PPA= &PA;

printf("&A:%p\tA:%d\n",&A,A);

printf("&PA:%p\tPA:%p\n",&PA,PA);

printf("PPA:%p\t*PPA:%p\t**PPA:%d\n",PPA,*PPA,**PPA);

return 0;

}

课堂练习:

  1. 编写一个函数,使用指针方法实现在键盘上输入10个数,求输入的数的和。

#include <stdio.h>

) 编写一个函数,使用指针方法实现在键盘上输入10个数,求输入的数的和。

int  inputNum(int * inputAddress)

{

int sum =0 ;

for(int i = 0;i < 10 ; i++)

{

printf("请输入%d个数值\n",i);

scanf("%d",inputAddress+i);

sum+=*(inputAddress + i);

}

return sum;

}

int main()

{

int input[10]={0};

printf("sum:%d\n",inputNum(input));

return 0;

}

  1. 编写一个函数,实现在键盘上输入一个字符串,检测字符串是否为回文。

#include <stdio.h>

#include <string.h>

)2) 编写一个函数,实现在键盘上输入一个字符串,检测字符串是否为回文。

//函数类型 1为成功  0失败

int  checkStringToHW(char * str)

{

int checkTrueFlage = 1;

int stringLen = strlen(str);//长度

//判断 1234321

for(int i = 0; i < stringLen/2;i++)

{

if(*(str +i) != *(str + stringLen-1-i) )

{

checkTrueFlage = 0;

break;

}

}

return checkTrueFlage;

}

int main()

{

char inputString[100]={0};

printf("请输入一串字符串\n");

gets(inputString);

printf("%s\n",checkStringToHW(inputString)?"是回文":"不是回文");

return 0;

}

1.5.6 指针数组和数组指针

  1. 指针数组

指针数组本质上是一个数组(指针类型的数组),数组中的每一个元素的类型都是指针类型,使用的时候结合数组和指针规则使用。

指针数组格式:

指针类型 数组名[];

例如:int * buff[10];为指针数组 本质还是数组

[]优先级大于*优先级,本质还是数组;

每个元素所存放的为指针类型;

实际中使用:

#include <stdio.h>

#include <string.h>

int main()

{

int A =10;

int B =20;

int C =30;

int D =40;

int E =50;

//定义指针数组

int * numP[10]={&A,&B,&C,&D,&E,NULL,NULL,NULL,NULL,NULL};

printf("%d\t%d\t%d\t%d\t%d\n",*numP[0],*numP[1],*numP[2],*numP[3],*numP[4]);

//存放文本常量区中的字符串首地址

char * stringBuff[] = {"1234","2345","3456","4567","5678"};

printf("%s\n",stringBuff[2]);

return 0;

}

  1. 数组指针  

数组指针的本质是一个指针(数组类型的指针),数组指针常用于访问二维数组时使用。使用“数据类型(*变量名)[数组长度]”的格式来定义一个数组指针。

使用场景: 数组指针常用于访问二维数组时;

数组指针格式:

数据类型 (*变量名)[数组长度];

通过上面看:()优先级最高 指针 *

例如:int (*p)[4]; ()起来以后p先与*号进行结合,再与[]进行结合;

Int:规定指向数组的类型;

[4]:规定了指向的数组长度(列长度);

注:数组指针又称为行指针;

#include <stdio.h>

#include <string.h>

int main()

{

int baseArr[3][4]={

{1,2,3,4},

{2,3,4,5},

{3,4,5,6}

};

int (*p)[4] = baseArr;

//数据

printf("baseArr[0][0]:%d\n",baseArr[0][0]);

printf("baseArr[1][0]:%d\n",baseArr[1][0]);

printf("baseArr[2][0]:%d\n",baseArr[2][0]);

//地址

printf("&baseArr[0][0]:%p\n",&baseArr[0][0]);

printf("&baseArr[1][0]:%p\n",&baseArr[1][0]);

printf("&baseArr[2][0]:%p\n",&baseArr[2][0]);

//数组指针 访问行地址  数组指针又称之为 行指针  p==

printf("p:%p\n", p);

printf("p+1:%p\n", p +1);

printf("p+2:%p\n", p +2);

//内容  获取每一行首个元素内容

printf("%d\n",**p);

printf("%d\n",**(p+1));

printf("%d\n",**(p+2));

return 0;

}

1.5.7 指针函数和函数指针

  1. 指针函数

指针函数的本质上是一个函数(函数的类型是指针类型),函数的返回值(如果是局部变量(由于}后会释放会导致程序崩溃),该变量必须是静态局部变量,返回值是该静态局部变量的地址)也是一个指针或数组首地址。用法和函数一样,常用于返回数组以及指针变量。

函数类型:指针类型  int * fun(void)  该函数返回一个地址;

注:地址的返回只能返回静态变量的首地址、动态开辟(malloc)的地址,全局变量的地址、指针地址等,不能返回局部变量的地址。

需要将空间存活于访问之后;

#include <stdio.h>

#include <string.h>

//指针函数的本质上是一个函数(函数的类型是指针类型),函数的返回值(如果是局部变量,该变量必须是静态局部变量,返回值是该静态局部变量的地址)也是一个指针或数组首地址。用法和函数一样,常用于返回数组以及指针变量。

char * mystringcat(char * str1,char *str2)

{

int len  =  strlen(str1);

int len2  =  strlen(str2);

strcpy(str1+len,str2);

return str1;

}

int main()

{

char buff[100]="hello";

char buff2[100]="123456";

printf("%s\n",mystringcat(buff,buff2));

return 0;

}

#include <stdio.h>

#include <string.h>

//指针函数的本质上是一个函数(函数的类型是指针类型),函数的返回值(如果是局部变量,该变量必须是静态局部变量,返回值是该静态局部变量的地址)也是一个指针或数组首地址。用法和函数一样,常用于返回数组以及指针变量。

int * function(void)

{

static int A =100;

return &A;

}

int main()

{

int* num = function();

printf("%d\n",*num);  //A的生命周期远大于*num访问周期√

return 0;

}

  1. 函数指针

函数指针本质上是指针,指针指向的类型是一个函数类型,用法和指针一样。使用“函数类型 (*变量名)(形参列表) = (初始化内容)”的格式去定义一个函数指针。

格式:

函数类型 (*变量名)(形参列表) = (初始化内容)

void  (*functionP)() ;

#include <stdio.h>

#include <string.h>

/********************************************************/

void functionA(void)

{

printf("void functionA(void)\n");

}

void functionB(void)

{

printf("void functionB(void)\n");

}

void functionC(void)

{

printf("void functionC(void)\n");

}

/********************************************************/

int functionD(int num)

{

printf("int functionD(int num)\n");

}

/********************************************************/

int functionE(int num,int num1)

{

printf("int functionE(int num,int num1)\n");

}

int main()

{

//void (*fun_P)(void) = functionA;  //函数指针 指针指向的类型是一个函数类型  指向函数的指针为函数指针

void (*fun_P)(void) = NULL;  //函数指针 指针指向的类型是一个函数类型  指向函数的指针为函数指针  函数指针名称为fun_P    函数指针变量名fun_P

//void (*fun_P)(void)只能指向函数类型为void 形参列表为void的函数

fun_P = functionA;

fun_P();

fun_P = functionB;

fun_P();

fun_P = functionC;

fun_P();

/********************************************************/

//int (*fun_P)(int)只能指向函数类型为int 形参列表为一个int的函数

int (* fun_intp)(int) = NULL;//避免野指针

fun_intp = functionD;

fun_intp(10); //运行

/********************************************************/

//int (*fun_P)(int)只能指向函数类型为int 形参列表为2个int的函数

int (*fun_intintp)(int,int) = NULL;

fun_intintp = functionE;

fun_intintp(10,20);

return 0;

}

利用函数指针实现简易计算器:

#include <stdio.h>

#include <string.h>

/******************子函数***************************/

//加法

int add(int num1,int num2)

{

return num1+num2;

}

//减法

int sub(int num1,int num2)

{

return num1-num2;

}

//乘法

int mul(int num1,int num2)

{

return num1*num2;

}

//除法

int div(int num1,int num2)

{

return num1/num2;

}

int main()

{

//函数指针类型

int (*bc)(int,int) =NULL;

int data1,data2;

char op;

printf("data1 op data2\n");

scanf("%d%c%d",&data1,&op,&data2);

//通过switch语句实现计算器选择----函数指针方式

switch(op)

{

case '+': bc = add;break;

case '-': bc = sub;break;

case '*': bc = mul;break;

case '/': bc = div;break;

}

printf("结果:%d\n",bc(data1,data2));

return 0;

}

例如:int (*p)(int a) = NULL;  /* 定义一个函数指针p,指向为空 */

p:变量名

int(*)(int int):指针类型,int(*)(int int)是p的数据类型,指向一个整型函数,并且该函数有两个整型的形参。

注,四种类型的格式对比

指针数组

数据类型*变量名[数组长度]:char*x[10]

数组指针

数据类型(*变量名)[数组长度]=(初始化内容)

指针函数

数据类型*变量名[形参]:char*fun(void)

函数指针

返回值类型(*变量名)(形参) =(初始化内容)

1.5.8空类型指针以及指针四要素

  1. 空类型指针

空类型指针可以指向任何类型的元素的指针。

void *p:万能型指针

提高代码复用性:

#include <stdio.h>

#include <string.h>

//内存拷贝函数

void mymemcpy(int * desc,int * src,int size)

{

for(int i = 0; i< size; i++)

{

desc[i] = src[i];//*(desc +i ) = *(src +i)

}

}

int main()

{

/*********************int*******************************/

int a[10]={1,2,3,4,5,6,7,8,9,10};

int b[10]={0};

mymemcpy(b,a,10);

for(int i = 0; i < 10 ;i++)

{

printf("%d\n",b[i]);

}

/*********************char*******************************/

char char_a[10]={1,2,3,4,5,6,7,8,9,10};

char char_b[10]={0};

mymemcpy(char_b,char_a,10);  //char*  int*类型 有区别  读取内容 步长

for(int i = 0; i < 10 ;i++)

{

printf("%d\n",char_b[i]);

}

return 0;

}

好好看看

#include <stdio.h>

#include <string.h>

//内存拷贝函数

void mymemcpy(void * desc,void * src,int size)

{

char *src_p = (char *)src;

char *desc_p = (char *)desc;

for(int i = 0; i< size; i++)

{

desc_p[i] = src_p[i];//*(desc +i ) = *(src +i)

}

}

int main()

{

/*********************int*******************************/

int a[10]={1,2,3,4,5,6,7,8,9,10};

int b[10]={0};

mymemcpy(b,a,40);

for(int i = 0; i < 10 ;i++)

{

printf("%d\n",b[i]);

}

/*********************char*******************************/

char char_a[10]={1,2,3,4,5,6,7,8,9,10};

char char_b[10]={0};

mymemcpy(char_b,char_a,10);  //char*  int*类型 有区别  读取内容 步长

for(int i = 0; i < 10 ;i++)

{

printf("%d\n",char_b[i]);

}

return 0;

}

  1. 指针四要素
    • 指针必须有类型,指针类型是声明指向对象的类型。
    • 指针所指向的数据类型,决定了指针值(指针指向对象地址里的数值)的数据类型。
    • 指针在使用时必须要有指向,避免野指针出现。
    • 指针本身也占内存空间(指针本身也是一个变量)。

1.5.9 指针应用场合

  • 当函数需要改变实参的时候,需要使用指针实现。
  • 写一个函数,求字符串长度。
  • 当函数需要传递一个数组时,需要使用指针实现。
  • 当函数需要返回一个地址(例如函数需要返回数组)的时候,需要使用指针实现。

1.6 指针练习

基础作业:

  1. 编写一个函数用指针方法来实现求字符串的长度

#include <stdio.h>

#include <string.h>

/*******************************************

1.编写一个函数用指针方法来实现求字符串的长度

方法:地址差方式

********************************************/

int getStringLen(char *src)

{

//借鉴上strcpy函数 C库中函数

char *offset = src; //偏移指针

while(*offset++ != '\0'); //先引用后加一 导致 结果多加1

return offset - src - 1; //结束地址减去起始地址

}

int main()

{

printf("%u\n",getStringLen("hello"));

}

  1. 编写一个函数实现在键盘上输入两个字符串,比较输入的字符串是否一样

#include <stdio.h>

#include <string.h>

/*******************************************

2. 编写一个函数实现在键盘上输入两个字符串,比较输入的字符串是否一样

函数名称:int checkStringCmp(char *str1,char *str2)

函数参数:str1字符串1  str2字符串2

返 回 值:0表示不同 1表示相同

********************************************/

int checkStringCmp(char *str1,char *str2)

{

int returnval = 1;

//先比较长度 长度不一致 会导致字符串不同

int strLen1 = strlen(str1);

int strLen2 = strlen(str2);

if(strLen1  == strLen2)

{

while(*str1 != '\0')

{

if(*str1 != *str2)

{

returnval =0;

break;

}

str1++; str2++;

}

}

else

{

returnval = 0;

}

return returnval;

}

int main()

{

char readBuff1[100]={0};

char readBuff2[100]={0};

printf("请输入第1串字符串\n");

gets(readBuff1);

printf("请输入第2串字符串\n");

gets(readBuff2);

printf("%s\n",checkStringCmp(readBuff1,readBuff2)?"相同":"不相同");

}

  1. 编写一个名为sumnarrays()的函数,它接受两个数组作为参数,长度为4将两个数组中的所有值相加,并返回得到的结果。

#include <stdio.h>

#include <string.h>

/*******************************************

3.编写一个名为sumnarrays()的函数,

它接受两个数组作为参数,长度为4将两个数组中的所有值相加,

并返回得到的结果。

********************************************/

int sumnarrays(int * numbuff1,int * numbuff2,int len)

{

int sum = 0;

for(int i =0;i < len ;i++)

{

sum +=*(numbuff1 + i)+*(numbuff2 + i);

}

return sum;

}

int main()

{

int buff1[4]={1,2,3,4};

int buff2[4]={2,2,2,2};

printf("%d\n",sumnarrays(buff1,buff2,4));

}

  1. 编写一个名为addarrays()的函数,它接受三个长度相同的数组,两个数组中对应的元素相加,并将结果放到第三个数组中。

#include <stdio.h>

#include <string.h>

/*******************************************

4.编写一个名为addarrays()的函数,它接受三个长度相同的数组,

两个数组中对应的元素相加,并将结果放到第三个数组中。

********************************************/

void addarrays(int * src1,int * src2,int *desc,int len)

{

int * offset = desc;

for(int i = 0; i < len ;i++)

{

*(offset+i) = *(src1+i) + *(src2+i);

}

}

int main()

{

int buff1[4]={1,2,3,4};

int buff2[4]={2,2,2,2};

int desc[4]={0};

addarrays(buff1,buff2,desc,4);

for(int i =0; i < 4 ;i++)

{

printf("%d\t",desc[i]);

}

}

  1. 写一个函数实现在一个字符串中查找键盘上输入的字符,并且返回这个字符的地址。Qwertyuiop

#include <stdio.h>

#include <string.h>

/*******************************************

5. 写一个函数实现在一个字符串中查找键盘上输入的字符,

并且返回这个字符的地址。Qwertyuiop

是相对地址 相关字符在字符串内 位置

********************************************/

int getStringAddress(char * str,char ch )

{

int len = strlen(str);

int offset =0;

for(int i =0; i < len;i++)

{

offset++;

if(*(str+i) == ch)

{

break;

}

if(i == len -1) return 0;

}

return offset;

}

int main()

{

printf("%d\n",getStringAddress("Qwertyuiop",'Q'));

}

提高作业: 

  1. 写一个函数:对字符数组的内容进行排序。提示:冒泡排序。

#include <stdio.h>

#include <string.h>

/*******************************************

5.6.写一个函数:对字符数组的内容进行排序。提示:冒泡排序。

********************************************/

char * function(char * str)

{

if(*str == '\0')  return NULL;

else if((*str != '\0')&&((*(str+1) == '\0'))) return str;

else if(str == NULL) return NULL;

else

{

int len = strlen(str);

for(int i = 0; i < len -1; i++)

{

for(int j =0; j< len-1-i;j++)

{

char ch;

if(*(str+j) > *(str+j+1))

{

ch = *(str+j);

*(str+j) = *(str+j+1);

*(str+j+1) = ch;

}

}

}

return str;

}

}

int main()

{

char buff[100]="987654321";

printf("%s\n",function(buff));

//printf("%s\n",function("987654321"));//在文本常量区 只能读不能写

}

扩展作业:

  1. 写一个函数实现字符串的连接(strcat)。  "hello" "world"把两个字符串连接成一个字符串,并且返回连接好的字符串的首地址。

#include <stdio.h>

#include <string.h>

/*******************************************

7.写一个函数实现字符串的连接(strcat)。

 "hello" "world"把两个字符串连接成一个字符串,并且返回连接好的字符串的首地址。

想学习strcpy操作 小端存储

********************************************/

char * mystrcat(char * str1,char *str2)

{

int i =0;

//先忽略掉空间不足

int len  = strlen(str1);

while(*str2 !='\0')

{

*(str1+len+i) = *(str2+i);

i++;

}

return str1;

}

int main()

{

char buff[100]="hello";

char buff2[100]="world";

printf("%s\n",mystrcat(buff,buff2));

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

面试僧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值