C語言enum(枚舉)、指針、函數指針

  • C enum(枚舉)

枚舉是c語言中的一種數據類型,定義格式爲

enum 枚舉名{枚舉元素1,枚舉元素2......};

用#define定義一星期七天,就要爲每個整數定義一個別名

#define MON 1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define sun 7

用枚舉的方式定義一星期七天

enum DAY
{
	MON=1, TUE, WED, THU, FRI, SAT, SUN
};

第一個枚舉成員的默認值爲整型的0,後續枚舉成員的值在前一個成員上加1

可以在定義枚舉類型時改變枚舉元素的值

enum season {spring, summer=3, autumn, winter};

spring的值爲0,summer的值爲3,autumn的值爲4

枚舉變量的定義

  1. 先定義枚舉類型,再定義枚舉變量
enum DAY
{
	MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;
  1. 定義枚舉類型的同時定義枚舉變量
enum DAY
{
	MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
  1. 省略枚舉名稱,直接定義枚舉變量
enum
{
	MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

在C語言中枚舉是被當作int或者unsigned int 類型處理

枚舉類型必須連續纔可以實現有條件的遍歷

#include<stdio.h>

enum DAY
{
	MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

int mian()
{
	for (day = MON; day <= SUN; day++)
	{
		printf("枚舉元素:%d\n",day);
	}
}

以上輸出結果爲

枚舉元素:1
枚舉元素:2
枚舉元素:3
枚舉元素:4
枚舉元素:5
枚舉元素:6
枚舉元素:7

枚舉在switch中的使用

#include<stdio.h>
#include<stdlib.h>
int mian()
{
	enum color { red=1; green; blue };
	enum color favorite_color;
	printf("請輸入你喜歡的顏色:(1.red,2.green,3.blue):");
	scanf("%d",&favorite_color);
	switch(favorite_color)
	{
	case red:
		printf("你喜歡的顏色是紅色");
		break;
	case green:
		printf("你喜歡的顏色是綠色");
		break;
	case blue:
		printf("你喜歡的顏色是藍色");
		break;
	default:
		printf("你沒有選擇你喜歡的顏色");
	}
	return 0;
}

將整數轉換爲枚舉

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

int main()
{
	enum day
	{
		MON, TUE, WED, THU, FRI, SAT, SUN
	}workday;

	int a=1;
	enum day weekend;
	weekend = ( enum day ) a; //類型轉換 
	printf("weekend:%d",weekend);
	return 0;
}
  • C指針

指針是一個變量,其值爲另一個變量的地址,即內存位置的直接地址

所有的實際數據類型,不管是整型、浮點型,還是其他的數據類型,對應指針的值的類型都是一樣的,都是一個代表內存地址的長的十六進制數

不同數據類型的指針之間唯一的不同是,指針所指的變量或常量的數據類型不同

#include<stdio.h>

int main()
{
	int var = 20;
	int *ip;
	ip = &var;  /* 在指針變量中存儲var的地址 */
	printf("Adress of var variable : %p\n",&var);
	/* 在指針變量中存儲的地址 */
	printf("Adress stored in ip variable : %p\n",ip);
	/* 使用指針訪問值 */
	printf("Value of *ip variable : %d\n",*ip);
	return 0;
}

編譯執行後,結果爲

Adress of var variable : bffd8b3c
Adress stored in ip variable : bffd8b3c
Value of *ip variable : 20
  • C中的NULL指針
    在聲明變量的時候,如果沒有確切的地址可以賦值,爲指針變量賦一個NULL值是一個好習慣。賦值NULL值的指針被稱爲空指針

NULL指針是一個定義在標準庫中的值爲零的常量

#include<stdio.h>

int main()
{
	int *ptr = NULL;
	printf("ptr的地址是:%p\n",ptr);
	return 0;
}

編譯執行後

ptr的地址是:0x0

在大多數操作系統上,程序不允許訪問地址爲0的內存,因爲該內存是操作系統保留的。然而,內存地址0有特別重要的意義,它表明該指針不指向一個可訪問的內存位置。但照慣例,如果指針包含空值(零值),則假定它不指向任何東西

檢查一個空指針,可以用if語句

if(ptr)    /* 如果p非空,則完成 */
if(!ptr)   /* 如果p爲空,則完成 */

遞增一個指針
使用指針代替數組,因爲變量指針可以遞增,而數組不能,數組可以看成一個指針變量

#include<stdio.h>
const MAX = 3;

int main()
{
	int var[] = {100,10,200};
	int i, *ptr;
	ptr = var;   //指針中的數組地址
	for ( i=0; i<MAX; i++)
	{
		printf("存儲地址:var[%d] = %x\n",i,ptr);
		printf("存儲值:var[%d] = %d\n",i,*ptr);
		ptr++;
	}
	return 0;
}

遞減一個指針
對指針進行遞減運算,即把值減去其數據類型的字節數,如下所示:

#include<stdio.h>

const int MAX = 3;
int main()
{
	int var[]={10,100,200};
	int i,*ptr;
	ptr = &var[MAX-1];  // 指針中最後一個元素的地址
	for (i=MAX; i>0; i--)
	{
		printf("存儲地址:var[%d] = %x\n",i-1,ptr);
		printf("存儲值:var[%d] = %d\n",i-1.*ptr);
		ptr--;
	}
	return 0;
}
  • 指針的比較
    只要變量指針所指向的地址小於或等於數組的最後一個元素的地址&var[MAX-1],則把變量指針進行遞增
#include<stdio.h>

int const MAX = 3;
int main()
{
	int var[]={10,100,200};
	int i,*ptr;
	ptr = var;
	i = 0;
	while( ptr<=&var[MAX-1] )
	{
		printf("Adress of var[%d] = %x\n",i,ptr);
		printf("value of var[%d] = %d\n",i,*ptr);
		ptr++;
		i++;
	}
	return 0;
}
  • C指向指針的指針
    指向指針的指針是一種多級間接尋址的形式,或者說是一個指針鏈。通常,一個指針包含一個變量的地址。當我們定義一個指向指針的指針時,第一個指針包含了第二個指針的地址,第二個指針指向包含實際值的位置

  • C傳遞指針給函數
    傳遞一個無符號的long型指針給函數,並在函數內改變這個值:

#include<stdio.h>
#include<time.h>

void getSeconds(unsigned long *ptr)

int main()
{
	unsigned long sec;
	getSeconds(&sec);
	printf("Number of seconds:%ld\n",sec);
	return 0;
}

void getSeconds(unsigned long *ptr)
{
	*ptr=time(NULL);  //獲取當前的秒數
	return;
}

能夠接收指針作爲參數的函數,也能接收數組作爲參數

#include<stdio.h>
double getAverage(int *arr,int size);

int main()
{
	int balance[5]={1000,2,3,17,50);
	double avg;
	avg = getAverage(balance,5);  //傳遞一個指向數組的指針作爲參數
	printf("Average value is:%f\n".avg);
	return 0;
}

double getAverage(int *arr,int size)
{
	int i,sum=0;
	double avg;
	for (i=0; i<size; ++i)
	{
		sum += arr[i];
	}
	avg = (double)sum/size;
	return avg;
}
  • C函數指針

函數指針是指向函數的指針變量
函數指針可以像一般函數一樣,用於調用函數、傳遞參數
函數指針變量的聲明:

typedef int (*fun_ptr)(int,int); //聲明一個指向同樣參數、返回值的函數指針類型

一下實例聲明瞭函數指針變量p,指向函數max:

#include<stdio.h>

int max(int x,int y)
{
	return x > y ? x : y;
}

int main(void)
{
	int(*p)(int,int) = &max;  //&可以省略
	int a,b,c,d;
	printf("Please enter three numbers:");
	scanf("%d%d%d",&a&b&c);
	/* 與直接調用函數等價,d=max(max(a,b),c) */
	d = p(p(a,b),c);
	printf("max is:%d\n",d);
	return 0;
}
  • 回調函數
    函數指針作爲某個函數的參數
    函數指針變量可以作爲某個函數的參數來使用的,回調函數就是一個通過函數指針調用的函數

實例中populate_array函數定義了三個參數,其中第三個參數是函數的指針,通過該函數來設置數組的值

實例中定義了回調函數getNextRandomValue,它返回一個隨機值,它作爲一個函數指針傳遞給populate_array函數

populate_array將調用10次回調函數,並將回調函數的返回值賦值給數組

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

//回調函數
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{
	for (size_t i=0; i<arraySize; i++)
		array[i]=getNextValue();
}

//獲取隨機值
int getNextRandomValue(void)
{
	return rand();
}

int main(void)
{
	int myarray[10];
	populate_array(myarray, 10, getNextRandomValue);
	for(int i = 0; i<10; i++)
	{
		printf("%d",myarray[i]);
	}
	printf("\n");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章