1. 程式人生 > >Linux C 深入分析結構體指標的定義與引用

Linux C 深入分析結構體指標的定義與引用

     關於結構體的基礎知識,網上書上都一大堆,這裡就不贅述了,下面我們要學習的是結構體指標。

介紹結構體指標之前,先給大家看一個小程式:

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

struct Man
{
	char name[10];
};

int main()
{
	struct Man N;
	N.name = "qiang";
	printf("%s\n",N.name);
}

這段程式很簡單,就是給結構體成員賦值,這裡結構體成員是個陣列,大家看看這種賦值方式有沒有錯,我們編譯一下:

[email protected]:~/qiang/struct$ gcc -o struct4 struct4.c
struct4.c: In function ‘main’:
struct4.c:13:9: error: incompatible types when assigning to type ‘char[10]’ from type ‘char *’
[email protected]:~/qiang/struct$ 

13行報錯,就是賦值那行,報錯原因是“字元分配的型別是不相容的型別”
我們看看這句N.name = "qiang",右邊是字串常量,這裡其實是字串的首地址,就是一個地址,我們以前 char a[] = "qiang"沒錯啊,為什麼這裡報錯了,我們看看左值,N.name, name 是陣列名,是代表陣列的首地址啊,但是我們要記住,這裡name是個地址常量,是不能給常量賦值的,所以會報錯,那我們如何給一個結構體中的字元陣列賦值呢?我們這裡用strcpy(N.name,"qiang") ! 當然我們N.name[1] = 'q',這樣是可以的。

下面開始講結構體指標:

一、指向結構體型別變數的使用

首先讓我們定義結構體:

<span style="color:#000000;">struct stu
{
	char name[20];
	long number;
	float score[4];
};
</span>


再定義指向結構體型別變數的指標變數:
struct stu *p1, *p2 ;
定義指標變數p1、p2,分別指向結構體型別變數。引用形式為:指標變數→成員;這裡我們要注意,非結構體指標引用型別是  結構體型別變數 . 成員;

下面我們看一個例子:

對指向結構體型別變數的正確使用。

輸入一個結構體型別變數的成員,並輸出:

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

struct data 
{
	int day,month,year;
};

struct stu 
{
	char name[20];
	long num;
	struct data birthday; /*巢狀的結構體型別成員*/
};

int main() 
{
	struct stu *student; /*定義結構體型別指標*/
	student = malloc(sizeof(struct stu)); /*為指標變數分配安全的地址*/
	printf("Input name,number,year,month,day:\n");
	scanf("%s",student->name); /*輸入學生姓名、學號、出生年月日*/
	scanf("%ld",&student->num);
	scanf("%d%d%d",&student->birthday.year,&student->birthday.month,
			&student->birthday.day);
	
	printf("\nOutputname,number,year,month,day\n");
/*列印輸出各成員項的值*/
	printf("%8s    %5ld  %d//%d//%d\n",student->name,student->num,
		student->birthday.year,student->birthday.month,
		student->birthday.day);
}

執行結果如下:

[email protected]:~/qiang/struct/tmp$ ./struct1
Input name,number,year,month,day:
xiao
10086
2012
12
22

Outputname,number,year,month,day
    xiao    10086  2012//12//22
[email protected]:~/qiang/struct/tmp$ 

程式中使用結構體型別指標引用結構體變數的成員,需要通過C提供的函式malloc()來為指標分配安全的地址。函式sizeof()返回值是計算給定資料型別所佔記憶體的位元組數。指標所指各成員形式為:

student->name
student->num
student->birthday.year
student->birthday.month
student->birthday.day

二、指向結構體型別陣列的指標的使用
        定義一個結構體型別陣列,其陣列名是陣列的首地址,這一點前面的課程介紹得很清楚。
        定義結構體型別的指標,既可以指向陣列的元素,也可以指向陣列,在使用時要加以區分。

上個例子中定義了結構體型別,根據此型別再定義結構體陣列及指向結構體型別的指標

struct data
{
intday,month,year;
};
struct stu/*定義結構體*/
{
char name[20];
long num;
struct data birthday;/*巢狀的結構體型別成員*/
};
struct stustudent[4],*p;   /*定義結構體陣列及指向結構體型別的指標*/

使p=student,此時指標p就指向了結構體陣列student。
p是指向一維結構體陣列的指標,對陣列元素的引用可採用三種方法。
1)地址法
  student+i和p+i均表示陣列第i個元素的地址,陣列元素各成員的引用形式為:
(student+i)->name、(student+i)->num和(p+i)->name、(p+i)->num等。student+i和p+i與&student[i]意義相同。
2)指標法
若p指向陣列的某一個元素,則p++就指向其後續元素。
3)指標的陣列表示法
若p=student,我們說指標p指向陣列student,p[i]表示陣列的第i個元素,其效果與student[i]等同。對陣列成員的引用描述為:p[i].name、p[i].num等
指向結構體陣列的指標變數的使用

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

struct data/*定義結構體型別*/
{
	int year,month,day;
};

struct stu/*定義結構體型別*/
{
	char name[20];
	long num;
	struct data birthday;
};

int main()
{
	int i;
	struct stu *p,student[4]={{"liying",1,1978,5,23},{"wangping",2,1979,3,14},
		{"libo",3,1980,5,6},{"xuyan",4,1980,4,21}};
	/*定義結構體陣列並初始化*/
	p = student;/*將陣列的首地址賦值給指標p,p指向了一維陣列student*/
	printf("Outputname,number,year,month,day\n");
	for(i = 0;i < 4;i++)/*採用指標法輸出陣列元素的各成員*/
		printf("%8s %6ld   %d//%d//%d\n",(p+i)->name,(p+i)->num,
				(p+i)->birthday.year,(p+i)->birthday.month,
				(p+i)->birthday.day);

	return 0;
}

執行結果如下:

[email protected]:~/qiang/struct/tmp$ ./struct2
Outputname,number,year,month,day
  liying      1   1978//5//23
wangping      2   1979//3//14
    libo      3   1980//5//6
   xuyan      4   1980//4//21
[email protected]:~/qiang/struct/tmp$ 

附:給大家看一個有意思的程式:

寫出一個模擬時鐘程式

分析:我們知道時間有時 分 秒 組成,這裡用結構體表示

程式碼如下:

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

typedef struct Clock
{
	int hour;
	int minute;
	int second;
}Clock;

update(Clock *p)
{
	p->second++;

	if(p->second == 60)
	{
		p->second = 0;
		p->minute++;
	}

	if(p->minute == 60)
	{
		p->minute = 0;
		p->hour++;
	}
	if(p->hour == 24)
		p->hour = 0;
}

Display(Clock *p)
{
	printf("\r%02d:%02d:%02d",p->hour,p->minute,p->second);//%02d中0 輸出數值時指定左面不使用的空位置自動填0,達到00:00:00效果
	fflush(stdout);//前面曾經講過,printf屬於行緩衝,遇到\n或程式結束才會輸出,這裡沒有\n,所以用fflush重新整理;
}

int main()
{
	Clock *clock;
	clock = (Clock *)malloc(sizeof(Clock));
	memset(clock,'\0',sizeof(Clock));//時鐘初始化

	while(1)
	{
		sleep(1);
		update(clock);
		Display(clock);
	}
	free(clock);
	return 0;
}

執行結果如下:

[email protected]:~/qiang/struct$ ./clock
00:00:01
[email protected]:~/qiang/struct$ ./clock
00:00:55

這裡是個動態效果,大家可以打印出來看一下

相關推薦

Linux C 深入分析結構指標定義引用

     關於結構體的基礎知識,網上書上都一大堆,這裡就不贅述了,下面我們要學習的是結構體指標。 介紹結構體指標之前,先給大家看一個小程式: #include <stdio.h> #include <string.h> #include <ma

C語言中結構指標定義引用

指向結構體型別變數的使用 首先讓我們定義結構體: struct stu { char name[20]; long number; float score[4]; } ; 再定義指向結構體型別變數的指標變數: struct stu *p1, *p2 ; 定義指標變數p 1、p 2,分別指向結構體型別變數。

C++:避免結構重複定義的方法

最近在做專案移植工作,將MFC的單文件專案由XP+VC6.0移植到WIn10+VS2017,由於專案本身用到了MFC的第三方可視庫,GuiLib和CJ609Lib,需要從網上下來原始碼在新平臺上移植通過。 在專案使用第三方庫的同時,編譯提示結構體CMenuItemInfo重定義,後來研究

C語言複習 -- 結構指標自增運算子

測試程式碼: #include <stdio.h> #include <stdlib.h> int main() {  struct student {   char *name;   int score;  };  struct stud

結構指標變數結構成員指標變數

C程式碼 #include <stdio.h> #include <stdlib.h> #include <string.h> struct student{    char *name;    int score;  

C/C++開發】函式使用結構結構指標作為返回值分析

函式使用結構體、結構體指標作為返回值分析 32位機,gcc編譯器 使用結構體作為返回值 分析反彙編程式碼可知,當被呼叫的子函式返回值為結構體的時候,呼叫函式將分配一段空間用於存放返回的結構體(使用一個結構體變數接受返回值),並將這段空間的地址作為呼叫時的引數壓棧。子程式不負責對要返回的結構體分

C-C++語言結構定義另一個結構指標的經驗

本文進行討論的是,在Linux中,C/C++語言的結構體的使用情況。一般情況下,結構體的使用還是相對比較簡單的,它攜帶的一類物體的某一些屬性, 比如 struct person { int age; int height; //... }; 這個結

結構定義結構指標、記憶體分配、指標結構體形參的深入理解

說明:此程式為深入學習資料結構時候,對於資料結構最重要的基礎(結構體、指標、記憶體分配) 方面的一些理解,我自己通過這段程式說明一些自己得到的結論;希望對看到這篇程式的c愛好者 有幫助,如果有理解錯誤的地方希望各位聯絡我,一起討論學習.說實話,我學習c就半年吧,除了 上課自學的,發現最難的部分就是指標了.廢話

C語言 結構指標需要申請記憶體但函式定義指標不需要申請

在函式定義指標或者變數已經為指標本身和變數本身分配了記憶體所以用指標指向一個已經定義的變數時不需再分配記憶體 但是資料結構中用指標指向結構體時只為指標本身分配了記憶體如果要對結結構體填入內容就要分配一個結構體大小的記憶體才可以 但只自己分配的記憶體一定要養成

C++ 結構指標定義

struct node { …… } ; struct node *p1, *p2 ; typedef struct node { …… }Node; typedef Node* pN

C++ 結構定義

ppr lse ref 結構體 c++ pro 方式 其它 AS struct 結構體名稱{ ???數據類型 A; ???數據類型 B; }結構體變量名; 相當於: struct 結構體名稱{ ???數據類型 A; ???數據類型 B; }; struct 結構體名稱 結構

c語言執行linux命令並通過結構返回每行命令的輸出

打印 linux pop sscanf [] #define ufs pan pipe #include <stdio.h> #include <stdlib.h> #include <unistd.h>

c語言typedef 結構指標

轉載部落格:https://blog.csdn.net/developerof/article/details/24885205?utm_source=blogxgwz0  #include<stdio.h> #include<

C程式碼開發遇到的問題 變數初始化和結構指標移動

1. 變數初始化 函式內部的變數如果不初始化的話預設不是0而是一個隨機值。 下面的程式用來列印一個未初始化的無符號的整型值,執行幾遍,每次的結果都會不一樣 #include <stdio.h> void PrintUint() { /* 預設是隨機值,不一定是0 *

C語言(結構、列舉型別、型別定義

結構體的定義 1、`struct 結構體名 { 成員型別 成員名; … }; 2、省略結構體名 struct { 成員型別 成員名; ... }結構體變數名; 成員可以是其他已定義結構體的型別,但不能是自己結構體的型別,可以是自己結構體的指標。 定義

結構指標C語言結構指標詳解

結構體指標,可細分為指向結構體變數的指標和指向結構體陣列的指標。 指向結構體變數的指標 前面我們通過“結構體變數名.成員名”的方式引用結構體變數中的成員,除了這種方法之外還可以使用指標。前面講過,&student1 表示結構體變數 student1 的首地址,即 student1 第一個項的地址

C語言結構定義的時候,各成員後面加冒號是什麼意思?

位域是指資訊在儲存時,並不需要佔用一個完整的位元組, 而只需佔幾個或一個二進位制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省儲存空間,並使處理簡便,C語言又提供了一種資料結構,稱為“位域”或“位段”。所謂“位域”是把一個位元組中的二進位劃分為

結構指標作函式引數(C# 呼叫C++ 的DLL)

1、C++結構體定義:   #pragma pack(1)  struct Person  {      #define Count_favoriteNumbers 6        int id;        fl

Delphi 呼叫 c編寫的動態連結庫,結構指標作為引數

折騰了一天終於把 結構體指標作為在delphi和c動態連結庫之間函式引數傳遞的問題徹底解決了,花了一天時間的主要原因是沒有領會引數傳遞的精髓。現在把c程式碼和delphi程式碼粘上來,以供後來者學習參考。 delphi程式程式碼: unit Unit3; interfac

C++類 給結構成員 函式指標 賦值

myStruct標頭檔案 myStruct.h class CMyClass; struct {  int nFlag;  void (CMyClass::*myinit)(int n);  void (CMyClass::*myopen)(int n,void* arg)