首页 > 其他分享 >C语言指针的应用场景

C语言指针的应用场景

时间:2023-11-18 17:33:33浏览次数:28  
标签:场景 return int void C语言 char include 指针

C语言指针的应用场景

指针是C语言的精华和灵魂,不懂指针,基本等同于不会C语言。掌握指针,让学会C语言不再成为梦想而成为现实。
指针基本上有三大类:

  • 指向数据的指针
  • 指向函数的指针
  • 泛型指针(void *

指针的应用场景可以分为以下10类:

- 1. 与函数相关的使用
  - 1.1 在函数中用作输出型参数,产生副作用(更新被调用函数中的局部变量的值)
  - 1.2 在函数中用作输出型参数,用于返回多个值
  - 1.3 在函数中用作输入型参数,指向符合类型,避免传值的副作用(性能损耗)
  - 1.4 用作函数返回值,返回一个左值
  - 1.5 用于指向函数的函数指针,使用函数指针调用回调函数
- 2. 用于指向堆内存
- 3. 与`void`配合使用,用`void*`来表示一个泛型指针
- 4. 用于指向数组名(数组指针)
- 5. 用于指向字符串常量(字符串常量指针)
- 6. 在数据结构中,用作链式存储

1. 与函数相关的使用

1.1 在函数中用作输出型参数,产生副作用(更新被调用函数中的局部变量的值)

#include<stdio.h>
void demo(int *arr, int size, int *max){//计算数组最大值
	*max = arr[0];
	for(int i=1;i<size;i++){
		if (arr[i] > *max)
		*max=arr[i];
	}
}

int main(){
	int max, arr[5] = {12, 23, 34, 45, 54};
	demo(arr, 5, &max);
	printf("Max=%d\n",max);
	return 0;
	
}

结果:

1.2 在函数中用作输出型参数,用于返回多个值

#include<stdio.h>
#include<math.h>

int equationSolve(double a, double b, double c,double *x1, double *x2){
	int delta = a*a - 4*a*c;
	if(delta >= 0){
		*x1 = (-b + sqrt(delta))/2*a;
		*x2 = (-b - sqrt(delta))/2*a;
		return 1;
	}
	else
		return 0;
}

int main(void){
	double x1, x2;
	if(equationSolve(1,3,-14,&x1,&x2)){
		printf("x1=%2.f\nx2=%.2f\n", x1,x2);
	}
	else{
		printf("无实根!\n");
	}
	return 0;
}

结果:

1.3 在函数中用作输入型参数,指向复合类型,避免传值的副作用(性能损耗)

#include<stdio.h>

typedef struct Inventory{
	int sku;
	char name[36];
	char unit[12];
	char suppler[48];
	double price;
	double stock;
}Inven;

void demo(const Inven *p){
	printf("The amounts is %f\n",p->price*(*p).stock);
	
}
int main(){
	Inven inven = {123, "carban fibre","kg","uc",128, 100
	};
	demo(&inven);
	return 0;
}

结果:

1.4 用作函数返回值,返回一个左值

#include <stdio.h> 
#include <malloc.h>
#include <stdlib.h> 

void printIntArray(void** array, size_t length) { 
    printf("Array at %p\n", array); 
    while (length--) { 
        printf(" [%zu] at %p -> %p", length, array + length, *(array + length)); 
        if (*(array + length)) { 
            printf(" -> %d", *(int*)*(array + length)); 
        } 
        printf("\n"); 
    } 
} 

void* getElement(void** array, size_t index) { 
    return *(array + index); 
} 

int main(int argc, char** argv) { 
    const size_t n = 5; 
    size_t i; 
    
    /* n element array */ 
    void** test = malloc(sizeof(void*) * n); 
    i = n; 
    while (i--) { 
        *(test + i) = NULL; 
    } 
    
    /* Set element [1] */ 
    int testData = 123; 
    printf("testData at %p -> %d\n", &testData, testData); 
    *(test + 1) = (void*)&testData; 
    
    printIntArray(test, n); 
    
    /* Prints 123, as expected */ 
    printf("Array[1] = %d\n", *(int*)getElement(test, 1)); 
    
    getchar();
    return 0; 
} 

该实例报错(需纠正)
1.5 用于指向函数的函数指针,使用函数指针调用回调函数

//通用的冒泡排序函数的应用

#include <iostream>
#include <cstring>
using namespace std;

template <class T>
void sort(T a[], int size, bool (*f)(T,T));
bool increaseInt(int x, int y){return x<y;

}

bool decreaseInt(int x, int y){return x>y;
}

bool increaseString(char *x, char *y){return strcmp(x, y)<0;}
bool decreaseString(char *x, char *y){return strcmp(x, y)>0;}


int main(){
	
	int a[] = {3,1,4,2,5,8,6,7,0,9},i;
	char *b[] = {"aaa", "bbb", "fff", "ttt","hhh", "ddd","ggg","www","rrr","vvv"};
	sort(a, 10, increaseInt);
	for(i = 0;i<10;++i) cout<<a[i]<<"\t";
	cout<<endl;
	sort(b, 10, increaseString);
	for(i=0;i<10;i++) cout<<b[i]<<"\t";
	cout<<endl;
	while(1);
	return 0;
	}


// 通用的冒泡排序函数
template <class T>
void sort(T a[], int size, bool (*f)(T,T))
{
    bool flag;
    int i, j;
    
    for (i = 1; i < size; ++i) {
        flag = false;
        for (j = 0; j <size - i; ++j)	{
            if (f(a[j+1], a[j]))  {
                T tmp = a[j];
                a[j] = a[j+1];
                a[j+1] = tmp;
                flag = true;
            }
        }
        if (!flag) break;	
    }
}

结果:

2. 用于指向堆内存

实质是通过库函数(malloc.h)返回void*指针

#include<stdio.h>
#include<malloc.h>
int** demo(int r, int c){
	int **ap = (int**)malloc(sizeof(int*)*r);
	for(int i=0;i<c;i++){
		ap[i] = (int*)malloc(sizeof(int)*c);
		
	}
	return ap;
}

int main(){
	int r = 3,c = 5;
	int ** ap = demo(r, c);
	int i, j;
	for(i = 0;i<r;i++){
		
		for(j=0;j<c;j++){
				ap[i][j] = (i+1)*(j+1);
		}
		
	}
		
	
	for(i=0;i<r;i++)
	{
		for(j=0;j<c;j++)
			{
			 	printf("%2d ",ap[i][j]);
			}
		printf("\n");
	}
	return 0;
}

结果:

3. 与void配合使用,用void*来表示一个泛型指针

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

int swap2(void *x, void *y, int size){
	void *tmp;
	if((tmp=malloc(size)) == NULL)
		return -1;
	memcpy(tmp,x, size);
	memcpy(x,y,size);
	memcpy(y,tmp,size);
	free(tmp);
	return 0;
	
}

int main(){
	int a = 3, b= 4;
	swap2(&a, &b, sizeof(int));
	printf("%d %d\n",a, b);
	double c = 3, d = 4;
	swap2(&c, &d, sizeof(double));
	printf("%f %f\n", c, d);
	return 0;
	
	
}

结果:

4. 用于指向数组名(数组指针)

#include<stdio.h>
void funcP(int *p, int r, int c){
	for(int i=0;i<r*c;i++)
		printf((i+1)%(r+1) ==0?"%2d\n":"%2d ",*p++);
	printf("\n");	
	
}
void funcAp(int (*p)[4], int r, int c){
	for(int i=0;i<r;i++){
		for(int j=0;j<c;j++)
			printf("%2d ",*(*(p+i)+j));
		printf("\n");
		
	}
	printf("\n");
}

void funcApp(int (*p)[3][4], int r, int c){
	for(int i =0;i<r;i++){
		
		for(int j=0;j<c;j++)
			printf("%2d ",*(*(*p+i)+j));
		printf("\n");
	}
	printf("\n");
}

int main(){
	int arr[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
	int size = sizeof arr /sizeof *arr;
	funcP((int*)arr,3,4);
	funcAp(arr,3,4);
	funcApp(&arr,3,4);
	return 0;
	
	
}

结果:

5. 用于指向一个字符串常量(字符串常量指针)

const char* demo(){
  const char *sp = "hello";
  return sp;
}

关于字符数组和字符指针可以如下图所示:

在字符指针数组,数组元素是一个字符指针,用于指向一个字符串常量,如:

char *pMonth[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
char *week[10] = { "Mon","Tue","Wed","Thu","Fri","Sat","Sun"};
char* color[]={"红-red","橙-orange","黄-yellow","绿-green","青-cyan","蓝-blue","紫-purple"};
char *gans[10] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
char* zhis[12] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
char* animals[12] = {"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};

6. 在数据结构中,用作链式存储

#define ElementType int
typedef struct LNode{
  ElementType data;
  struct LNode *next;

}LNode, *LinkList;

标签:场景,return,int,void,C语言,char,include,指针
From: https://www.cnblogs.com/bonne-chance/p/17840647.html

相关文章

  • C语言小案例
    在一个整型数组中插入任意一个数字,进行重新排序,用多种方法如何实现?方法1:直接插入排序法#include<stdio.h>voidinsert(intarr[],intn,intx){inti,j;for(i=0;i<n;i++){if(arr[i]>x){for(j=n-1;j>=i;j--){......
  • Vue多页面和单页面的场景
    开发分类实现方式页面性能开发效率用户体验学习成本首屏加载SEO单页一个html页面按需更新性能高高非常好高慢差多页多个html页面整页更新性能低中等一般中等快优场景单页面应用系统类网站内部网站文档类网站移动端站点多页面应用公......
  • 杨辉三角c语言
    #include<stdio.h>#defineM10#defineN10intmain(){  inta[M][N],i,j;  for(i=0;i<M;i++) {  for(j=0;j<=i;j++)                     //先取9*9列的数都赋值为一,再取其中1/2的部分  a[i][j]=1;      ......
  • 引用与指针
    引用只是给已经存在的变量赋一个别名,通过此别名操作变量与通过变量本名操作是一样的效果。为一个变量声明了引用后该变量就可通过两个名称来操作了。例如:inta=10;int&b=a;这样之后通过a与b均可来操作存储10的这块地址空间。而指针是一种变量类型,可被视为与int、char......
  • C语言——数组
    1.字符型数组与字符指针的赋值constchar*pStr="Hello!";charaStr[sizeof("Hello!")]="Hello!";cout<<aStr<<"\n"<<pStr<<endl;cout<<strlen(aStr)<<"\n"......
  • C语言笔记5
    C语言提供三种逻辑运算符:&&逻辑与两边运算量都为非0时,结果为真||逻辑或两边运算量都为0是,结果为假,否则为真。!逻辑非使操做数的值0变1,1变0说明:“&&”和“||”是“双目运算符”,要求有两个操做数。“!"是”单目运算符“,只要求有一个运算量。a&&ba、b均为真,则a&&b为1(......
  • C语言【运算符】
    C语言【运算符、分支控制语句】1、运算符分类按照操作个数分类:一元运算符(一目运算符):只有一个操作数。如负号-1。二元运算符(二目运算符):有两个操作数。如加号1+2。三元运算符(三目运算符):有三个操作数。如?:a>b?1:2。按功能分类:算数运算符:正(+)、负......
  • c语言ATM机案例
    1#include<stdio.h>2intmain()3{4//password初始密码,input输入的密码money取款金额,balance卡余额,select选项,x表示输入密码的次数(错误的机会只有三次)5intpassword=1101,input,money,balance=300;6//select表示选择的选项7intselect......
  • PTAC语言删除字符串中的字串
    这是题目。初见觉得还好,谁知道越分析越操蛋暗含深意。仔细看,假设我们通过遍历s1删除了两个显性的cat,哎,剩下的是什么Tomisamalecat咋样,牛逼不。说明这题肯定会出现删除一次不够的样例sample。假设我们熟知C语言中#include<string.h>中的strcat,strstr,strcpy等函数,那么这题可以比......
  • C++ 指针学习笔记
    C++指针学习笔记引入指针是什么指针是一个变量,其值为另一个变量的地址。指针声明的一般形式为:type*ptr_name;type是指针的基类型,ptr_name是指针的名称,*用来指定一个变量是指针对于一个指针,需要明确四个方面的内容:指针的类型、指针所指向的类型、指针的值(指针所指向的......