C语言学习——指针精华(2)

简介: C语言学习——指针精华(2)



字符指针作函数参数


[用函数调用实现字符串的复制]


⑴用字符数组作参数

#include <stdio.h>
void copy_string(char  from[], char to[]);
int main()
{ 
  char a[] = "I am a teacher.";
  char b[] = "You are a student.";
  printf("string_a=%s\n string_b=%s\n", a, b);
  printf("copy string_a to string_b : \n");
    copy_string(a, b);   /* 数组名作参数是地址传递*/
  printf("\nstring_a = %s\nstring_b = %s\n",a,b);
  return 0;
}
void copy_string(char  from[], char to[])
{
  int i = 0;
  while (from[i] != '\0')
  {
    to[i] = from[i];  i++;
  }
  to[i] = '\0';
}


结果:



【字符指针变量作形参】

#include <stdio.h>
void FuncPArs(char *s)
 {
  printf("Result:%s\n", s);
}
int main()
{
  char rsa[] = "Welcome To C/C++.\n";
  FuncPArs(rsa);
  return 0;
}

结果:


对使用字符指针变量和字符数组的讨论


char *cp; 与 char str[20]; 的区别


str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址


赋值方式:


字符数组只能对元素赋值。 char str[20];


str=“I love China!”; ()


字符指针变量可以用: char *cp;


cp=“I love China!”; ()


赋初值:char *cp=“China!”; 等价 char *cp; cp=“China!”;


char str[14]={“China”};不等价char str[14]; str[ ]=“China” ()


【用下标法引用指针变量所指的字符串中的字符】


#include <stdio.h>
int main()
{
  char *a = "I love China!"; int i;
  printf("The sixth charcter is %c\n", a[5]);
  for (i = 0; a[i] != '\0'; i++)
    printf("%c", a[i]);
  printf("\n");
  return 0;
}


结果如下:




用指针变量指向的格式字符串代替printf中的格式字符串(可变格式输出函数)char *format; format="a=%d,b=%f\n"; printf(format,a,b);相对于:` printf("a=%d,b=%f\n"a,b);


可以用字符数组实现:


   char format[ ]="a=%d,b=%f\n";
   printf(format,a,b);



二、函数指针与指针函数


函数指针的实质(还是指针变量)


函数指针定义格式


类型名 (*函数名)(函数参数列表);


int (*pfun)(int, int);


函数指针的定义_赋值_调用


void FuncTest(void) //定义一个函数,以方便下面定义函数指针

{

printf(“FunPointer DemoTestFunc.\n”);

}


【案例如下】


void (*pFunc)(void);// 函数指针定义
pFunc = FuncTest;   // 函数指针赋值
(*pFunc)();         // 函数指针调用;用函数指针来调用以调用该函数,注意*pFunc要用()括起来
pFunc();            // 调用的第二种写法,效果和上面一样


函数指针作用:函数指针有两个用途:调用函数和做函数的参数。


注意:函数指针声明为指针,它与变量指针不同之处是,它不是指向变量,而是指向函数。


(1)函数指针的实质还是指针,还是指针变量。本身占4字节;


(2)函数指针、数组指针、普通指针之间并没有本质区别,区别在于指针指向的内容是什么;


(3)函数的实质是一段代码,这一段代码在内存中是连续分布的(一个函数的大括号括起来的所有语句将来编译出来生成的可执行程序是连续的),所以对于函数来说很关键的就是函数中的第一句代码的地址,这个地址就是所谓的函数地址,在C语言中用函数名这个符号来表示;


(4)结合函数的实质,函数指针其实就是一个普通变量,这个普通变量的类型是函数指针变量类型,它的值就是某个函数的地址(也就是它的函数名这个符号在编译器中对应的地址值)。


指针函数实质是一个函数


指针函数实质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。


*指针函数定义格式:类型名 函数名(函数参数列表);

int *pfun(int, int);


指针函数的声明_定义_调用


int * sum(int x);       //指针函数的声明;返回类型位一个指针变量 可以通过*p来获取值
int * sum(int x)      //指针函数的定义
{       
  int static sum = 0;     //static 修身的变量在数据段;不会被函数栈回收
  int *p;
  int i;
  for (i = 1; i <= x; i++)
  {
    sum += i;  // sum=sum+i;
    return p;       //返回类型是某一类型的指针
  }
}
int *p1;
p1 = fun(a);            //指针函数的调用

指针函数作用:可以使代码更简洁并在一定程度节约内存;如当你需要返回一个数组中的元素时,你就只需返回首元素的地址给调用函数,调用函数即可操作该数组(让函数返回多个值)。


或者是malloc函数动态分配内存,返回该内存的地址给另外一个函数,另一个函数才好操作该内存。当然还有其他的作用,请读者自行在实践中体会。


注意:指针函数本质是一个函数,使用方法与普通函数没什么两样。既然是函数,就与变量不一样。变量需要定义、赋值、调用(比如函数指针);而函数需要声明、定义、调用。


【工程案例】


输入第几周的第几天获取这天是这个月的几号

#include<stdio.h>
int * GetDate(int wk, int dy);  // 声明指针函数
int main()
{ 
        int wk, dy; 
        do 
        {
                 printf("Enter week(1 - 5)day(1 - 7)\n");
     scanf_s("%d%d", &wk, &dy);
        } while (wk < 1 || wk>5 || dy < 1 || dy>7);
        printf("%d\n", *GetDate(wk, dy)); 
  // 调用,GetDate()函数返回的是一个指针(地址)
  // * GetDate()则是取其内容
        return 0;
}
int * GetDate(int wk, int dy)
{
         static int calendar[5][7] = { 
  { 1, 2, 3, 4, 5, 6, 7 },
  { 8, 9, 10, 11, 12, 13, 14 },
  { 15, 16, 17, 18, 19, 20, 21 },
  { 22, 23, 24, 25, 26, 27, 28 },
  { 29, 30, 31, -1 } };
        //返回一个地址
        return &calendar[wk - 1][dy - 1]; 
}

结果如下:





【工程案例】


#include <stdio.h>
int main()
{
  int x = 89;
  int y = 92;
  int *p[2];  // 指针数组  元素里面全部都是指针
  printf("x的地址:%p , y的地址:%p\n",&x,&y);
  p[0] = &x;  p[1] = &y;
  printf("p[0]的值:%p , p[1]的值:%p\n", p[0],p[1]);
  printf("\n输出指针数组所指向地址里面的值:\np[0]的值:%d , p[1]的值:%d\n", *p[0], *p[1]);
  return 0;
}




【工程案例】

#include <stdio.h>
// 函数申明
void mymemset(void *data, int num, int byteSize);
int main()
{ 
  int nums[20];
  mymemset(nums, 0, sizeof(nums));
  int i, len = sizeof(nums) / sizeof(int);
  for (i = 0; i<len; i++) 
  {
    printf("%d ", nums[i]);
  }
  printf("\n");
  return 0;
}
void mymemset(void *data, int num, int byteSize)
{ 
// char就是一个字节,而计算机中是以字节为单位存储的
  char *ptr = (char*)data;
  int i;
  for (i = 0; i<byteSize; i++) 
  {
    *ptr = num;
    ptr++;
  }
}

结果如下:




一、函数参数传递方式之一(值传递)


#include <stdio.h>
void ExceFun(int x, int y)
{
  int temp;
  temp = x;
  x = y;
  y = temp;
  printf("x=%d, y=%d\n", x, y);
}
int main()
{
  int a = 89, b = 65;
  ExceFun(a, b);
  printf("a=%d, b=%d\n", a, b);
  return 0;
}


二、函数参数传递方式之二(地址传递)


#include <stdio.h> 
void ExceFun(int *px,int *py)
{
  int temp;
  temp=*px;
  *px=*py;
  *py=temp;
  printf("*px=%d, *py=%d\n", *px,*py);
}
int main( )
{
  int a=89, b=65;
  ExceFun(&a,&b);
  printf("a=%d, b=%d\n",a,b);
  return 0;
}



相关文章
|
17天前
|
存储 人工智能 Java
一文轻松拿捏C语言的指针的基础使用
本文介绍了C语言中的指针概念,包括直接访问和间接访问内存的方式、指针变量的定义与使用、取址运算符`&`和取值运算符`*`的应用,帮助读者深入理解指针这一C语言的核心概念。君志所向,一往无前!
20 0
|
3月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
348 9
|
3月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
77 7
|
3月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
135 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
4月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
4月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
86 1
|
4月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
274 3
|
4月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
4月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
4月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。