當前位置:首頁 » 編程語言 » c語言第二章講解
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言第二章講解

發布時間: 2022-10-22 23:09:43

『壹』 求《c語言程序設計》(譚浩強主編 第三版 清華大學出版社)的教學視頻下載

鏈接:

提取碼: 58zn

C語言程序設計:

『貳』 C語言程序設計這門課程第二章流程式控制制(初級)的知識點有哪些

C語言程序設計這門課第二章流程式控制制(初級)的知識點包含【初級】第10講-IF條件語句,【初級】第11講-Switch條件語句,【初級】第12講-while循環語句,【初級】第13講-For循環語句,。

『叄』 全國計算機二級C語言第二章的考點有哪些

2.3裡面的特徵總共有四條左右,這個要會背。
2.4裡面除了偽代碼跟自然語言兩個小節外,全是重點,選擇題都會考
其他的都不是重點

『肆』 C語言概述

在電驢上找,石油大學曾怡副教授的C語言視頻講座,和譚浩強寫的《C程序設計》教的一樣。

簡介:
C程序設計視頻教程(曾怡):本套視頻教程由曾怡副教授講解,使用教材為:《C程序設計》 譚浩強 清華大學出版社出版。是難得的C語言學習視頻教程。全程共30講,每講45分鍾左右,CSF視頻格式。講課內容如下:

第一講 第一章 C語言概述
第二講 第二章 程序的靈魂—演算法
第三講 第三章 數據類型、運算符與表達式
第四講 第三章 數據類型、運算符與表達式
第五講 第三章 數據類型、運算符與表達式
第六講 第三章 數據類型、運算符與表達式
第四章 最簡單的C程序設計—順序程序設計
第七講 第四章 最簡單的C程序設計—順序程序設計
第八講 第四章 最簡單的C程序設計—順序程序設計
第九講 第五章 選擇結構的程序設計
第十講 第五章 選擇結構的程序設計
第十一講 第五章 選擇結構的程序設計
第十二講 第六章 循環結構程序設計
第十三講 第六章 循環結構程序設計
第十四講 第六章 循環結構程序設計
第十五講 第六章 循環結構程序設計
第七章 數組
第十六講 第七章 數組
第十七講 第七章 數組
第十八講 第七章 數組
第十九講 第七章 數組
第二十講 第七章 數組
第八章 函數
第二十一講 第八章 函數
第二十二講 第八章 函數
第二十三講 第八章 函數
第二十四講 第十章 指針
第二十五講 第十章 指針
第二十六講 第十章 指針
第二十七講 第十章 指針
第十一章 結構體
第二十八講 第十一章 結構體
復習總結第一講
復習總結第二講
參考資料:http://lib.verycd.com/2004/12/06/0000029347.html

『伍』 數據結構c語言版,第二章線性表

說實話,我本學期也開數據結構,只不過教我們的是一個年過60的老爺爺。水平就不說了,你想要答案,我沒有,我這有思路,前5個要求我可以解決。我說一下思路:
如果想按書上的那種方式來編寫代碼,你需要一定的指針知識,不然說了你也看不懂。看下面:
這一步是定義,別說這你也看不懂:
typedef struct LNode /*定義結點*/
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
下面這步是初始化鏈表,這步中,你要注意幾個問題,第一個是LinkList *L,你可以看成雙指針。指針不好可以復習下。:
InitList(LinkList *L) /*初始化*/
{(*L)=(LinkList)malloc(sizeof(LNode));
if(!(*L)) return 0;
(*L)->next=NULL;
}
這一步:是建立和插入操作,你看得懂這步,那麼刪除就不難了
CreatList(LinkList *L,int n) /*建立*/
{ int i,e;
for(i=1;i<=n;i++)
{
scanf("%d",&e);
InsertList(L,i,e);
}
}
InsertList(LinkList *L,int i,ElemType e) /*把e插入第i個位置*/
{LinkList p,s;
int j=0;
p=*L;
while(p!=NULL && j<i-1){p=p->next;j++;}
if(p==NULL || j>i-1) return 0;
s=(LinkList)malloc(sizeof(LNode));
s->next=p->next;
p->next=s;
s->data=e;
return 1;
}
這一步是刪除,看看是不是和書上的很像?
DeleteList(LinkList *L,int i,ElemType e){
LinkList q,p,s;
int j=0;
p=*L;
while(p->next&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1){
return 0;
}
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return e;
}
授之以漁,下面的我就不多說了。不懂得說,

『陸』 c語言中的指針應該怎麼理解

這是我收錄的指針講義

第一章。指針的概念

指針是一個特殊的變數,它裡面存儲的數值被解釋成為內存里的一個地址。

要搞清一個指針需要搞清指針的四方面的內容:指針的類型,指針所指向的 類型,指針的值或者叫指針所指向的內存區,還有指針本身所佔據的內存區。讓 我們分別說明。
先聲明幾個指針放著做例子:
例一:
(1)int *ptr;
(2)char *ptr;
(3)int **ptr;
(4)int (*ptr)[3];
(5)int *(*ptr)[4];

1。 指針的類型。
從語法的角度看,你只要把指針聲明語句里的指針名字去掉,剩下的部分就是這個指針的類型。這是指針本身所具有的類型。讓我們看看例一中各個指針的 類型:
(1)int *ptr; //指針的類型是int *
(2)char *ptr; //指針的類型是char *
(3)int **ptr; //指針的類型是 int **
(4)int (*ptr)[3]; //指針的類型是 int(*)[3]
(5)int *(*ptr)[4]; //指針的類型是 int *(*)[4]
怎麼樣?找出指針的類型的方法是不是很簡單?

2。指針所指向的類型。
當你通過指針來訪問指針所指向的內存區時,指針所指向的類型決定了編譯 器將把那片內存區里的內容當做什麼來看待。
從語法上看,你只須把指針聲明語句中的指針名字和名字左邊的指針聲明符 *去掉,剩下的就是指針所指向的類型。例如:
(1)int *ptr; //指針所指向的類型是int
(2)char *ptr; //指針所指向的的類型是char
(3)int **ptr; //指針所指向的的類型是 int *
(4)int (*ptr)[3]; //指針所指向的的類型是 int()[3]
(5)int *(*ptr)[4]; //指針所指向的的類型是 int *()[4]
在指針的算術運算中,指針所指向的類型有很大的作用。
指針的類型(即指針本身的類型)和指針所指向的類型是兩個概念。當你對C越 來越熟悉時,你會發現,把與指針攪和在一起的"類型"這個概念分成"指針的 類型"和"指針所指向的類型"兩個概念,是精通指針的關鍵點之一。我看了不 少書,發現有些寫得差的書中,就把指針的這兩個概念攪在一起了,所以看起書來前後矛盾,越看越糊塗。

3。 指針的值,或者叫指針所指向的內存區或地址。
指針的值是指針本身存儲的數值,這個值將被編譯器當作一個地址,而不是一個一般的數值。在32位程序里,所有類型的指針的值都是一個32位整數,因為32位程序里內存地址全都是32位長。
指針所指向的內存區就是從指針的值所代表的那個內存地址開始,長度為sizeof(指針所指向的類型)的一片內存區。以後,我們說一個指針的值是XX,就相當於說該指針指向了以XX為首地址的一片內存區域;我們說一個指針指向了某塊
內存區域,就相當於說該指針的值是這塊內存區域的首地址。
指針所指向的內存區和指針所指向的類型是兩個完全不同的概念。在例一中,指針所指向的類型已經有了,但由於指針還未初始化,所以它所指向的內存區是不存在的,或者說是無意義的。
以後,每遇到一個指針,都應該問問:這個指針的類型是什麼?指針指向的類型是什麼?該指針指向了哪裡?
4。 指針本身所佔據的內存區。
指針本身佔了多大的內存?你只要用函數sizeof(指針的類型)測一下就知道了。在32位平台里,指針本身占據了4個位元組的長度。
指針本身占據的內存這個概念在判斷一個指針表達式是否是左值時很有用。

第二章。指針的算術運算

指針可以加上或減去一個整數。指針的這種運算的意義和通常的數值的加減運算的意義是不一樣的。例如:
例二:
1。 char a[20];
2。 int *ptr=a;
...
...
3。 ptr++;
在上例中,指針ptr的類型是int*,它指向的類型是int,它被初始化為指向整 形變數a。接下來的第3句中,指針ptr被加了1,編譯器是這樣處理的:它把指針ptr的值加上了sizeof(int),在32位程序中,是被加上了4。由於地址是用位元組做單位的,故ptr所指向的地址由原來的變數a的地址向高地址方向增加了4個位元組。
由於char類型的長度是一個位元組,所以,原來ptr是指向數組a的第0號單元開始的四個位元組,此時指向了數組a中從第4號單元開始的四個位元組。
我們可以用一個指針和一個循環來遍歷一個數組,看例子:
例三:
int array[20];
int *ptr=array;
...
//此處略去為整型數組賦值的代碼。
...
for(i=0;i<20;i++)
{
(*ptr)++;
ptr++;
}
這個例子將整型數組中各個單元的值加1。由於每次循環都將指針ptr加1,所
以每次循環都能訪問數組的下一個單元。
再看例子:
例四:
1。 char a[20];
2。 int *ptr=a;
...
...
3。 ptr+=5;
在這個例子中,ptr被加上了5,編譯器是這樣處理的:將指針ptr的值加上5 乘sizeof(int),在32位程序中就是加上了5乘4=20。由於地址的單位是位元組,故現在的ptr所指向的地址比起加5後的ptr所指向的地址來說,向高地址方向移動了20個位元組。在這個例子中,沒加5前的ptr指向數組a的第0號單元開始的四個位元組,加5後,ptr已經指向了數組a的合法范圍之外了。雖然這種情況在應用上會出問題,但在語法上卻是可以的。這也體現出了指針的靈活性。
如果上例中,ptr是被減去5,那麼處理過程大同小異,只不過ptr的值是被減去5乘sizeof(int),新的ptr指向的地址將比原來的ptr所指向的地址向低地址方向移動了20個位元組。

總結一下,一個指針ptrold加上一個整數n後,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值增加了n乘sizeof(ptrold所指向的類型)個位元組。就是說,ptrnew所指向的內存區將比ptrold所指向的內存區向高地址方向移動了n乘sizeof(ptrold所指向的類型)個位元組。
一個指針ptrold減去一個整數n後,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值減少了n乘sizeof(ptrold所指向的類型)個位元組,就是說,ptrnew所指向的內存區將比ptrold所指向的內存區向低地址方向移動了n乘sizeof(ptrold所指向的類型)個位元組。

第三章。運算?amp;和*

這里&是取地址運算符,*是...書上叫做"間接運算符"。
&a的運算結果是一個指針,指針的類型是a的類型加個*,指針所指向的類型是a的類型,指針所指向的地址嘛,那就是a的地址。
*p的運算結果就五花八門了。總之*p的結果是p所指向的東西,這個東西有這些特點:它的類型是p指向的類型,它所佔用的地址是p所指向的地址。
例五:
int a=12;
int b;
int *p;
int **ptr;
p=&a;//&a的結果是一個指針,類型是int*,指向的類型是int,指向的地址 是a的地址。
*p=24;//*p的結果,在這里它的類型是int,它所佔用的地址是p所指向的地 址,顯然,*p就是變數a。
ptr=&p;//&p的結果是個指針,該指針的類型是p的類型加個*,在這里是int
**。該指針所指向的類型是p的類型,這里是int*。該指針所指向的地址就是指針p自己的地址。
*ptr=&b;//*ptr是個指針,&b的結果也是個指針,且這兩個指針的類型和所 指向的類型是一樣的,所以用&b來給*ptr賦值就是毫無問題的了。
**ptr=34;//*ptr的結果是ptr所指向的東西,在這里是一個指針,對這個指
針再做一次*運算,結果就是一個int類型的變數。

第四章。指針表達式。

一個表達式的最後結果如果是一個指針,那麼這個表達式就叫指針表達式。
下面是一些指針表達式的例子:
例六:
int a,b;
int array[10];
int *pa;
pa=&a;//&a是一個指針表達式。
int **ptr=&pa;//&pa也是一個指針表達式。
*ptr=&b;//*ptr和&b都是指針表達式。
pa=array;
pa++;//這也是指針表達式。
例七:
char *arr[20];
char **parr=arr;//如果把arr看作指針的話,arr也是指針表達式
char *str;
str=*parr;//*parr是指針表達式
str=*(parr+1);//*(parr+1)是指針表達式
str=*(parr+2);//*(parr+2)是指針表達式

由於指針表達式的結果是一個指針,所以指針表達式也具有指針所具有的四個要素:指針的類型,指針所指向的類型,指針指向的內存區,指針自身占據的內存。
好了,當一個指針表達式的結果指針已經明確地具有了指針自身占據的內存的話,這個指針表達式就是一個左值,否則就不是一個左值。
在例七中,&a不是一個左值,因為它還沒有占據明確的內存。*ptr是一個左值,因為*ptr這個指針已經占據了內存,其實*ptr就是指針pa,既然pa已經在內存中有了自己的位置,那麼*ptr當然也有了自己的位置。

第五章。數組和指針的關系

如果對聲明數組的語句不太明白的話,請參閱我前段時間貼出的文?lt;>。
數組的數組名其實可以看作一個指針。看下例:
例八:
int array[10]={0,1,2,3,4,5,6,7,8,9},value;
...
...
value=array[0];//也可寫成:value=*array;
value=array[3];//也可寫成:value=*(array+3);
value=array[4];//也可寫成:value=*(array+4);
上例中,一般而言數組名array代表數組本身,類型是int [10],但如果把a
rray看做指針的話,它指向數組的第0個單元,類型是int *,所指向的類型是數組單元的類型即int。因此*array等於0就一點也不奇怪了。同理,array+3是一個指向數組第3個單元的指針,所以*(array+3)等於3。其它依此類推。
例九:
char *str[3]={
"Hello,this is a sample!",
"Hi,good morning.",
"Hello world"
};
char s[80];
strcpy(s,str[0]);//也可寫成strcpy(s,*str);
strcpy(s,str[1]);//也可寫成strcpy(s,*(str+1));
strcpy(s,str[2]);//也可寫成strcpy(s,*(str+2));
上例中,str是一個三單元的數組,該數組的每個單元都是一個指針,這些指針各指向一個字元串。把指針數組名str當作一個指針的話,它指向數組的第0號單元,它的類型是char**,它指向的類型是char *。
*str也是一個指針,它的類型是char*,它所指向的類型是char,它指向的地址是字元串"Hello,this is a sample!"的第一個字元的地址,即』H』的地址。
str+1也是一個指針,它指向數組的第1號單元,它的類型是char**,它指向的類型是char *。
*(str+1)也是一個指針,它的類型是char*,它所指向的類型是char,它指向"Hi,good morning."的第一個字元』H』,等等。

下面總結一下數組的數組名的問題。聲明了一個數組TYPE array[n],則數組名稱array就有了兩重含義:第一,它代表整個數組,它的類型是TYPE [n];第二,它是一個指針,該指針的類型是TYPE*,該指針指向的類型是TYPE,也就是數組單元的類型,該指針指向的內存區就是數組第0號單元,該指針自己佔有單獨的內存區,注意它和數組第0號單元占據的內存區是不同的。該指針的值是不能修改的,即類似array++的表達式是錯誤的。
在不同的表達式中數組名array可以扮演不同的角色。
在表達式sizeof(array)中,數組名array代表數組本身,故這時sizeof函數
測出的是整個數組的大小。
在表達式*array中,array扮演的是指針,因此這個表達式的結果就是數組第0號單元的值。sizeof(*array)測出的是數組單元的大小。
表達式array+n(其中n=0,1,2,....。)中,array扮演的是指針,故arr
ay+n的結果是一個指針,它的類型是TYPE*,它指向的類型是TYPE,它指向數組第n號單元。故sizeof(array+n)測出的是指針類型的大小。
例十:
int array[10];
int (*ptr)[10];
ptr=&array;
上例中ptr是一個指針,它的類型是int (*)[10],他指向的類型是int [10]
,我們用整個數組的首地址來初始化它。在語句ptr=&array中,array代表數組本身。

本節中提到了函數sizeof(),那麼我來問一問,sizeof(指針名稱)測出的究
竟是指針自身類型的大小呢還是指針所指向的類型的大小?答案是前者。例如:

int (*ptr)[10];
則在32位程序中,有:
sizeof(int(*)[10])==4
sizeof(int [10])==40
sizeof(ptr)==4
實際上,sizeof(對象)測出的都是對象自身的類型的大小,而不是別的什麼類型的大小。

第六章。指針和結構類型的關系

可以聲明一個指向結構類型對象的指針。
例十一:
struct MyStruct
{
int a;
int b;
int c;
}
MyStruct ss={20,30,40};//聲明了結構對象ss,並把ss的三個成員初始
化為20,30和40。
MyStruct *ptr=&ss;//聲明了一個指向結構對象ss的指針。它的類型是
MyStruct*,它指向的類型是MyStruct。
int *pstr=(int*)&ss;//聲明了一個指向結構對象ss的指針。但是它的
類型和它指向的類型和ptr是不同的。

請問怎樣通過指針ptr來訪問ss的三個成員變數?
答案:
ptr->a;
ptr->b;
ptr->c;
又請問怎樣通過指針pstr來訪問ss的三個成員變數?
答案:
*pstr;//訪問了ss的成員a。
*(pstr+1);//訪問了ss的成員b。
*(pstr+2)//訪問了ss的成員c。
呵呵,雖然我在我的MSVC++6.0上調式過上述代碼,但是要知道,這樣使用p
str來訪問結構成員是不正規的,為了說明為什麼不正規,讓我們看看怎樣通過指
針來訪問數組的各個單元:
例十二:
int array[3]={35,56,37};
int *pa=array;
通過指針pa訪問數組array的三個單元的方法是:
*pa;//訪問了第0號單元
*(pa+1);//訪問了第1號單元
*(pa+2);//訪問了第2號單元
從格式上看倒是與通過指針訪問結構成員的不正規方法的格式一樣。
所有的C/C++編譯器在排列數組的單元時,總是把各個數組單元存放在連續的存儲區里,單元和單元之間沒有空隙。但在存放結構對象的各個成員時,在某種編譯環境下,可能會需要字對齊或雙字對齊或者是別的什麼對齊,需要在相鄰兩個成員之間加若干?quot;填充位元組",這就導致各個成員之間可能會有若干個位元組的空隙。
所以,在例十二中,即使*pstr訪問到了結構對象ss的第一個成員變數a,也不能保證*(pstr+1)就一定能訪問到結構成員b。因為成員a和成員b之間可能會有若干填充位元組,說不定*(pstr+1)就正好訪問到了這些填充位元組呢。這也證明了指針的靈活性。要是你的目的就是想看看各個結構成員之間到底有沒有填充位元組,
嘿,這倒是個不錯的方法。
通過指針訪問結構成員的正確方法應該是象例十二中使用指針ptr的方法。

第七章。指針和函數的關系

可以把一個指針聲明成為一個指向函數的指針。
int fun1(char*,int);
int (*pfun1)(char*,int);
pfun1=fun1;
....
....
int a=(*pfun1)("abcdefg",7);//通過函數指針調用函數。
可以把指針作為函數的形參。在函數調用語句中,可以用指針表達式來作為
實參。
例十三:
int fun(char*);
int a;
char str[]="abcdefghijklmn";
a=fun(str);
...
...
int fun(char*s)
{
int num=0;
for(int i=0;i
{
num+=*s;s++;
}
return num;
)
這個例子中的函數fun統計一個字元串中各個字元的ASCII碼值之和。前面說了,數組的名字也是一個指針。在函數調用中,當把str作為實參傳遞給形參s後,實際是把str的值傳遞給了s,s所指向的地址就和str所指向的地址一致,但是str和s各自佔用各自的存儲空間。在函數體內對s進行自加1運算,並不意味著同時對str進行了自加1運算。

第八章。指針類型轉換

當我們初始化一個指針或給一個指針賦值時,賦值號的左邊是一個指針,賦值號的右邊是一個指針表達式。在我們前面所舉的例子中,絕大多數情況下,指針的類型和指針表達式的類型是一樣的,指針所指向的類型和指針表達式所指向的類型是一樣的。
例十四:
1。 float f=12.3;
2。 float *fptr=&f;
3。 int *p;
在上面的例子中,假如我們想讓指針p指向實數f,應該怎麼搞?是用下面的語句嗎?
p=&f;
不對。因為指針p的類型是int*,它指向的類型是int。表達式&f的結果是一
個指針,指針的類型是float*,它指向的類型是float。兩者不一致,直接賦值的方法是不行的。至少在我的MSVC++6.0上,對指針的賦值語句要求賦值號兩邊的類型一致,所指向的類型也一致,其它的編譯器上我沒試過,大家可以試試。為了實現我們的目的,需要進行"強制類型轉換":
p=(int*)&f; 如果有一個指針p,我們需要把它的類型和所指向的類型改為TYEP*和TYPE,
那麼語法格式是:
(TYPE*)p;
這樣強制類型轉換的結果是一個新指針,該新指針的類型是TYPE*,它指向的類型是TYPE,它指向的地址就是原指針指向的地址。而原來的指針p的一切屬性都沒有被修改。

一個函數如果使用了指針作為形參,那麼在函數調用語句的實參和形參的結合過程中,也會發生指針類型的轉換。
例十五:
void fun(char*);
int a=125,b;
fun((char*)&a);
...
...
void fun(char*s)
{
char c;
c=*(s+3);*(s+3)=*(s+0);*(s+0)=c;
c=*(s+2);*(s+2)=*(s+1);*(s+1)=c;
}
}
注意這是一個32位程序,故int類型佔了四個位元組,char類型佔一個位元組。函數fun的作用是把一個整數的四個位元組的順序來個顛倒。注意到了嗎?在函數調用語句中,實參&a的結果是一個指針,它的類型是int *,它指向的類型是int。形參這個指針的類型是char*,它指向的類型是char。這樣,在實參和形參的結合過程中,我們必須進行一次從int*類型到char*類型的轉換。結合這個例子,我們可以這樣來想像編譯器進行轉換的過程:編譯器先構造一個臨時指針 char*temp,然後執行temp=(char*)&a,最後再把temp的值傳遞給s。所以最後的結果是:s的類型是char*,它指向的類型是char,它指向的地址就是a的首地址。

我們已經知道,指針的值就是指針指向的地址,在32位程序中,指針的值其實是一個32位整數。那可不可以把一個整數當作指針的值直接賦給指針呢?就象下面的語句:
unsigned int a;
TYPE *ptr;//TYPE是int,char或結構類型等等類型。
...
...
a=20345686;
ptr=20345686;//我們的目的是要使指針ptr指向地址20345686(十進制

ptr=a;//我們的目的是要使指針ptr指向地址20345686(十進制)
編譯一下吧。結果發現後面兩條語句全是錯的。那麼我們的目的就不能達到了嗎?不,還有辦法:
unsigned int a;
TYPE *ptr;//TYPE是int,char或結構類型等等類型。
...
...
a=某個數,這個數必須代表一個合法的地址;
ptr=(TYPE*)a;//呵呵,這就可以了。
嚴格說來這里的(TYPE*)和指針類型轉換中的(TYPE*)還不一樣。這里的(TYPE*)的意思是把無符號整數a的值當作一個地址來看待。
上面強調了a的值必須代表一個合法的地址,否則的話,在你使用ptr的時候,就會出現非法操作錯誤。

想想能不能反過來,把指針指向的地址即指針的值當作一個整數取出來。完全可以。下面的例子演示了把一個指針的值當作一個整數取出來,然後再把這個整數當作一個地址賦給一個指針:
例十六:
int a=123,b;
int *ptr=&a;
char *str;
b=(int)ptr;//把指針ptr的值當作一個整數取出來。
str=(char*)b;//把這個整數的值當作一個地址賦給指針str。

好了,現在我們已經知道了,可以把指針的值當作一個整數取出來,也可以把一個整數值當作地址賦給一個指針。

第九章。指針的安全問題

看下面的例子:
例十七:
char s=』a』;
int *ptr;
ptr=(int*)&s;
*ptr=1298;
指針ptr是一個int*類型的指針,它指向的類型是int。它指向的地址就是s的首地址。在32位程序中,s佔一個位元組,int類型佔四個位元組。最後一條語句不但改變了s所佔的一個位元組,還把和s相臨的高地址方向的三個位元組也改變了。這三個位元組是干什麼的?只有編譯程序知道,而寫程序的人是不太可能知道的。也許這三個位元組里存儲了非常重要的數據,也許這三個位元組里正好是程序的一條代碼,而由於你對指針的馬虎應用,這三個位元組的值被改變了!這會造成崩潰性的錯誤。
讓我們再來看一例:
例十八:
1。 char a;
2。 int *ptr=&a;
...
...
3。 ptr++;
4。 *ptr=115;
該例子完全可以通過編譯,並能執行。但是看到沒有?第3句對指針ptr進行自加1運算後,ptr指向了和整形變數a相鄰的高地址方向的一塊存儲區。這塊存儲區里是什麼?我們不知道。有可能它是一個非常重要的數據,甚至可能是一條代碼。而第4句竟然往這片存儲區里寫入一個數據!這是嚴重的錯誤。所以在使用指針時,程序員心裡必須非常清楚:我的指針究竟指向了哪裡。
在用指針訪問數組的時候,也要注意不要超出數組的低端和高端界限,否則也會造成類似的錯誤。
在指針的強制類型轉換:ptr1=(TYPE*)ptr2中,如果sizeof(ptr2的類型)大
於sizeof(ptr1的類型),那麼在使用指針ptr1來訪問ptr2所指向的存儲區時是安全的。如果sizeof(ptr2的類型)小於sizeof(ptr1的類型),那麼在使用指針ptr1來訪問ptr2所指向的存儲區時是不安全的。至於為什麼,讀者結合例十七來想一想,應該會明白的。

如果對你有所幫助,請記得採納最佳答案,謝謝

『柒』 C語言的指針是什麼

第一章。指針的概念

指針是一個特殊的變數,它裡面存儲的數值被解釋成為內存里的一個地址。要搞清一個指針需要搞清指針的四方面的內容:指針的類型,指針

所指向的類型,指針的值或者叫指針所指向的內存區,還有指針本身所佔據的內存區。讓我們分別說明。

先聲明幾個指針放著做例子:

例一:

(1)int *ptr;

(2)char *ptr;

(3)int **ptr;

(4)int (*ptr)[3];

(5)int *(*ptr)[4];

如果看不懂後幾個例子的話,請參閱我前段時間貼出的文章 < <如何理解c和c++的復雜類型聲明>>。

1。 指針的類型。

從語法的角度看,你只要把指針聲明語句里的指針名字去掉,剩下的部分就是這個指針的類型。這是指針本身所具有的類型。讓我們看看例一

中各個指針的類型:

(1)int *ptr; //指針的類型是int *

(2)char *ptr; //指針的類型是char *

(3)int **ptr; //指針的類型是 int **

(4)int (*ptr)[3]; //指針的類型是 int(*)[3]

(5)int *(*ptr)[4]; //指針的類型是 int *(*)[4]

怎麼樣?找出指針的類型的方法是不是很簡單?

2。指針所指向的類型。

當你通過指針來訪問指針所指向的內存區時,指針所指向的類型決定了編譯器將把那片內存區里的內容當做什麼來看待。

從語法上看,你只須把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針所指向的類型。例如:

(1)int *ptr; //指針所指向的類型是int

(2)char *ptr; //指針所指向的的類型是char

(3)int **ptr; //指針所指向的的類型是 int *

(4)int (*ptr)[3]; //指針所指向的的類型是 int()[3]

(5)int *(*ptr)[4]; //指針所指向的的類型是 int *()[4]

在指針的算術運算中,指針所指向的類型有很大的作用。

指針的類型(即指針本身的類型)和指針所指向的類型是兩個概念。當你對C越來越熟悉時,你會發現,把與指針攪和在一起的「類型」這個概念

分成「指針的類型」和「指針所指向的類型」兩個概念,是精通指針的關鍵點之一。我看了不少書,發現有些寫得差的書中,就把指針的這兩

個概念攪在一起了,所以看起書來前後矛盾,越看越糊塗。

3。 指針的值,或者叫指針所指向的內存區或地址。

指針的值是指針本身存儲的數值,這個值將被編譯器當作一個地址,而不是一個一般的數值。在32位程序里,所有類型的指針的值都是一個32

位整數,因為32位程序里內存地址全都是32位長。

指針所指向的內存區就是從指針的值所代表的那個內存地址開始,長度為sizeof(指針所指向的類型)的一片內存區。以後,我們說一個指針的

值是XX,就相當於說該指針指向了以XX為首地址的一片內存區域;我們說一個指針指向了某塊內存區域,就相當於說該指針的值是這塊內存區

域的首地址。

指針所指向的內存區和指針所指向的類型是兩個完全不同的概念。在例一中,指針所指向的類型已經有了,但由於指針還未初始化,所以它所

指向的內存區是不存在的,或者說是無意義的。

以後,每遇到一個指針,都應該問問:這個指針的類型是什麼?指針指向的類型是什麼?該指針指向了哪裡?

4。 指針本身所佔據的內存區。

指針本身佔了多大的內存?你只要用函數sizeof(指針的類型)測一下就知道了。在32位平台里,指針本身占據了4個位元組的長度。

指針本身占據的內存這個概念在判斷一個指針表達式是否是左值時很有用。

第二章。指針的算術運算

指針可以加上或減去一個整數。指針的這種運算的意義和通常的數值的加減運算的意義是不一樣的。例如:

例二:

1。 char a[20];

2。 int *ptr=a;

...

...

3。 ptr++;

在上例中,指針ptr的類型是int*,它指向的類型是int,它被初始化為指向整形變數a。接下來的第3句中,指針ptr被加了1,編譯器是這樣處理

的:它把指針ptr的值加上了sizeof(int),在32位程序中,是被加上了4。由於地址是用位元組做單位的,故ptr所指向的地址由原來的變數a的地

址向高地址方向增加了4個位元組。

由於char類型的長度是一個位元組,所以,原來ptr是指向數組a的第0號單元開始的四個位元組,此時指向了數組a中從第4號單元開始的四個位元組。

我們可以用一個指針和一個循環來遍歷一個數組,看例子:

例三:

int array[20];

int *ptr=array;

...

//此處略去為整型數組賦值的代碼。

...

for(i=0;i <20;i++)

{

(*ptr)++;

ptr++;

}

這個例子將整型數組中各個單元的值加1。由於每次循環都將指針ptr加1,所以每次循環都能訪問數組的下一個單元。再看例子:

例四:

1。 char a[20];

2。 int *ptr=a;

...

...

3。 ptr+=5;

在這個例子中,ptr被加上了5,編譯器是這樣處理的:將指針ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。由於地址的單

位是位元組,故現在的ptr所指向的地址比起加5後的ptr所指向的地址來說,向高地址方向移動了20個位元組。在這個例子中,沒加5前的ptr指向數

組a的第0號單元開始的四個位元組,加5後,ptr已經指向了數組a的合法范圍之外了。雖然這種情況在應用上會出問題,但在語法上卻是可以的。

這也體現出了指針的靈活性。

如果上例中,ptr是被減去5,那麼處理過程大同小異,只不過ptr的值是被減去5乘sizeof(int),新的ptr指向的地址將比原來的 ptr所指向的地

址向低地址方向移動了20個位元組。

總結一下,一個指針ptrold加上一個整數n後,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold

所指向的類型也相同。ptrnew的值將比ptrold的值增加了n乘sizeof(ptrold所指向的類型)個位元組。就是說,ptrnew所指向的內存區將比ptrold

所指向的內存區向高地址方向移動了n乘sizeof(ptrold所指向的類型)個位元組。一個指針ptrold減去一個整數n後,結果是一個新的指針ptrnew

,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值減少了n乘sizeof

(ptrold所指向的類型)個位元組,就是說,ptrnew所指向的內存區將比ptrold所指向的內存區向低地址方向移動了n乘 sizeof(ptrold所指向的類

型)個位元組。

第三章。運算符&和*

這里&是取地址運算符,*是...書上叫做「間接運算符」。&a的運算結果是一個指針,指針的類型是a的類型加個*,指針所指向的類型是a的類

型,指針所指向的地址嘛,那就是a的地址。*p的運算結果就五花八門了。總之*p的結果是p所指向的東西,這個東西有這些特點:它的類型是p

指向的類型,它所佔用的地址是p所指向的地址。

例五:

int a=12;

int b;

int *p;

int **ptr;

p=&a;//&a的結果是一個指針,類型是int*,指向的類型是int,指向的地址是a的地址。

*p=24;//*p的結果,在這里它的類型是int,它所佔用的地址是p所指向的地址,顯然,*p就是變數a。

ptr=&p;//&p的結果是個指針,該指針的類型是p的類型加個*,在這里是int**。該指針所指向的類型是p的類型,這里是int*。該指針所指向的

地址就是指針p自己的地址。

*ptr=&b;//*ptr是個指針,&b的結果也是個指針,且這兩個指針的類型和所指向的類型是一樣的,所以?amp;b來給*ptr賦值就是毫無問題的了



**ptr=34;//*ptr的結果是ptr所指向的東西,在這里是一個指針,對這個指針再做一次*運算,結果就是一個int類型的變數。

第四章。指針表達式。

一個表達式的最後結果如果是一個指針,那麼這個表達式就叫指針表達式。下面是一些指針表達式的例子:

例六:

int a,b;

int array[10];

int *pa;

pa=&a;//&a是一個指針表達式。

int **ptr=&pa;//&pa也是一個指針表達式。

*ptr=&b;//*ptr和&b都是指針表達式。

pa=array;

pa++;//這也是指針表達式。

例七:

char *arr[20];

char **parr=arr;//如果把arr看作指針的話,arr也是指針表達式

char *str;

str=*parr;//*parr是指針表達式

str=*(parr+1);//*(parr+1)是指針表達式

str=*(parr+2);//*(parr+2)是指針表達式

由於指針表達式的結果是一個指針,所以指針表達式也具有指針所具有的四個要素:指針的類型,指針所指向的類型,指針指向的內存區,指

針自身占據的內存。

好了,當一個指針表達式的結果指針已經明確地具有了指針自身占據的內存的話,這個指針表達式就是一個左值,否則就不是一個左值。 在例

七中,&a不是一個左值,因為它還沒有占據明確的內存。*ptr是一個左值,因為*ptr這個指針已經占據了內存,其實*ptr就是指針 pa,既然pa

已經在內存中有了自己的位置,那麼*ptr當然也有了自己的位置。

第五章。數組和指針的關系

如果對聲明數組的語句不太明白的話,請參閱我前段時間貼出的文章 < <如何理解c和c++的復雜類型聲明>>。 數組的數組名其實可以看作一個

指針。看下例:

例八:

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

...

...

value=array[0];//也可寫成:value=*array;

value=array[3];//也可寫成:value=*(array+3);

value=array[4];//也可寫成:value=*(array+4);

上例中,一般而言數組名array代表數組本身,類型是int [10],但如果把array看做指針的話,它指向數組的第0個單元,類型是int *,所指

向的類型是數組單元的類型即int。因此*array等於0就一點也不奇怪了。同理,array+3是一個指向數組第3個單元的指針,所以* (array+3)等

於3。其它依此類推。

例九:

char *str[3]={

"Hello,this is a sample!",

"Hi,good morning.",

"Hello world"

};

char s[80];

strcpy(s,str[0]);//也可寫成strcpy(s,*str);

strcpy(s,str[1]);//也可寫成strcpy(s,*(str+1));

strcpy(s,str[2]);//也可寫成strcpy(s,*(str+2));

上例中,str是一個三單元的數組,該數組的每個單元都是一個指針,這些指針各指向一個字元串。把指針數組名str當作一個指針的話,它指

向數組的第0號單元,它的類型是char**,它指向的類型是char *。

*str也是一個指針,它的類型是char*,它所指向的類型是char,它指向的地址是字元串"Hello,this is a sample!"的第一個字元的地址,

即'H'的地址。 str+1也是一個指針,它指向數組的第1號單元,它的類型是char**,它指向的類型是char *。

*(str+1)也是一個指針,它的類型是char*,它所指向的類型是char,它指向"Hi,good morning."的第一個字元'H',等等。

下面總結一下數組的數組名的問題。聲明了一個數組TYPE array[n],則數組名稱array就有了兩重含義:第一,它代表整個數組,它的類型是

TYPE [n];第二,它是一個指針,該指針的類型是TYPE*,該指針指向的類型是TYPE,也就是數組單元的類型,該指針指向的內存區就是數組第

0號單元,該指針自己佔有單獨的內存區,注意它和數組第0號單元占據的內存區是不同的。該指針的值是不能修改的,即類似array++的表達式

是錯誤的。

在不同的表達式中數組名array可以扮演不同的角色。

在表達式sizeof(array)中,數組名array代表數組本身,故這時sizeof函數測出的是整個數組的大小。

在表達式*array中,array扮演的是指針,因此這個表達式的結果就是數組第0號單元的值。sizeof(*array)測出的是數組單元的大小。

表達式array+n(其中n=0,1,2,....。)中,array扮演的是指針,故array+n的結果是一個指針,它的類型是TYPE*,它指向的類型是TYPE,

它指向數組第n號單元。故sizeof(array+n)測出的是指針類型的大小。

例十:

int array[10];

int (*ptr)[10];

ptr=&array;

上例中ptr是一個指針,它的類型是int (*)[10],他指向的類型是int [10],我們用整個數組的首地址來初始化它。在語句ptr=&array中,

array代表數組本身。

本節中提到了函數sizeof(),那麼我來問一問,sizeof(指針名稱)測出的究竟是指針自身類型的大小呢還是指針所指向的類型的大小?答案是

前者。例如:

int (*ptr)[10];

則在32位程序中,有:

sizeof(int(*)[10])==4

sizeof(int [10])==40

sizeof(ptr)==4

實際上,sizeof(對象)測出的都是對象自身的類型的大小,而不是別的什麼類型的大小。

第六章。指針和結構類型的關系

可以聲明一個指向結構類型對象的指針。

例十一:

struct MyStruct

{

int a;

int b;

int c;

}

MyStruct ss={20,30,40};//聲明了結構對象ss,並把ss的三個成員初始化為20,30和40。

MyStruct *ptr=&ss;//聲明了一個指向結構對象ss的指針。它的類型是

MyStruct*,它指向的類型是MyStruct。

int *pstr=(int*)&ss;//聲明了一個指向結構對象ss的指針。但是它的類型和它指向的類型和ptr是不同的。

請問怎樣通過指針ptr來訪問ss的三個成員變數?

答案:

ptr->a;

ptr->b;

ptr->c;

又請問怎樣通過指針pstr來訪問ss的三個成員變數?

答案:

*pstr;//訪問了ss的成員a。

*(pstr+1);//訪問了ss的成員b。

*(pstr+2)//訪問了ss的成員c。

呵呵,雖然我在我的MSVC++6.0上調式過上述代碼,但是要知道,這樣使用pstr來訪問結構成員是不正規的,為了說明為什麼不正規,讓我們看

看怎樣通過指針來訪問數組的各個單元:

例十二:

int array[3]={35,56,37};

int *pa=array;

通過指針pa訪問數組array的三個單元的方法是:

*pa;//訪問了第0號單元

*(pa+1);//訪問了第1號單元

*(pa+2);//訪問了第2號單元

從格式上看倒是與通過指針訪問結構成員的不正規方法的格式一樣。

所有的C/C++編譯器在排列數組的單元時,總是把各個數組單元存放在連續的存儲區里,單元和單元之間沒有空隙。但在存放結構對象的各個成

員時,在某種編譯環境下,可能會需要字對齊或雙字對齊或者是別的什麼對齊,需要在相鄰兩個成員之間加若干個「填充位元組」,這就導致各

個成員之間可能會有若干個位元組的空隙。

所以,在例十二中,即使*pstr訪問到了結構對象ss的第一個成員變數a,也不能保證*(pstr+1)就一定能訪問到結構成員b。因為成員a和成員b

之間可能會有若干填充位元組,說不定*(pstr+1)就正好訪問到了這些填充位元組呢。這也證明了指針的靈活性。要是你的目的就是想看看各個結構

成員之間到底有沒有填充位元組,嘿,這倒是個不錯的方法。

通過指針訪問結構成員的正確方法應該是象例十二中使用指針ptr的方法。

第七章。指針和函數的關系

可以把一個指針聲明成為一個指向函數的指針。

int fun1(char*,int);

int (*pfun1)(char*,int);

pfun1=fun1;

....

....

int a=(*pfun1)("abcdefg",7);//通過函數指針調用函數。

可以把指針作為函數的形參。在函數調用語句中,可以用指針表達式來作為實參。
例十三:

int fun(char*);

int a;

char str[]="abcdefghijklmn";

a=fun(str);

...

...

int fun(char*s)

{

int num=0;

for(int i=0;i <strlen(s);i++)

{

num+=*s;s++;

}

return num;

}

這個例子中的函數fun統計一個字元串中各個字元的ASCII碼值之和。前面說了,數組的名字也是一個指針。在函數調用中,當把str作為實參傳

遞給形參s後,實際是把str的值傳遞給了s,s所指向的地址就和str所指向的地址一致,但是str和s各自佔用各自的存儲空間。在函數體內對s

進行自加1運算,並不意味著同時對str進行了自加1運算。

第八章。指針類型轉換

當我們初始化一個指針或給一個指針賦值時,賦值號的左邊是一個指針,賦值號的右邊是一個指針表達式。在我們前面所舉的例子中,絕大多

數情況下,指針的類型和指針表達式的類型是一樣的,指針所指向的類型和指針表達式所指向的類型是一樣的。

例十四:

1。 float f=12.3;

2。 float *fptr=&f;

3。 int *p;

在上面的例子中,假如我們想讓指針p指向實數f,應該怎麼搞?是用下面的語句嗎?

p=&f;

不對。因為指針p的類型是int*,它指向的類型是int。表達式&f的結果是一個指針,指針的類型是float*,它指向的類型是 float。兩者不一致

,直接賦值的方法是不行的。至少在我的MSVC++6.0上,對指針的賦值語句要求賦值號兩邊的類型一致,所指向的類型也一致,其它的編譯器上

我沒試過,大家可以試試。為了實現我們的目的,需要進行「強制類型轉換」:

p=(int*)&f;

如果有一個指針p,我們需要把它的類型和所指向的類型改為TYEP*和TYPE,那麼語法格式是:

(TYPE*)p;

這樣強制類型轉換的結果是一個新指針,該新指針的類型是TYPE*,它指向的類型是TYPE,它指向的地址就是原指針指向的地址。而原來的指針

p的一切屬性都沒有被修改。

一個函數如果使用了指針作為形參,那麼在函數調用語句的實參和形參的結合過程中,也會發生指針類型的轉換。

例十五:

void fun(char*);

int a=125,b;

fun((char*)&a);

...

...

void fun(char*s)

{

char c;

c=*(s+3);*(s+3)=*(s+0);*(s+0)=c;

c=*(s+2);*(s+2)=*(s+1);*(s+1)=c;

}

注意這是一個32位程序,故int類型佔了四個位元組,char類型佔一個位元組。函數fun的作用是把一個整數的四個位元組的順序來個顛倒。注意到了

嗎?在函數調用語句中,實?amp;a的結果是一個指針,它的類型是int *,它指向的類型是int。形參這個指針的類型是char*,它指向的類型是

char。這樣,在實參和形參的結合過程中,我們必須進行一次從int*類型到char*類型的轉換。結合這個例子,我們可以這樣來想像編譯器進行

轉換的過程:編譯器先構造一個臨時指針 char*temp,然後執行temp=(char*)&a,最後再把temp的值傳遞給s。所以最後的結果是:s的類型是

char*,它指向的類型是char,它指向的地址就是a的首地址。

我們已經知道,指針的值就是指針指向的地址,在32位程序中,指針的值其實是一個32位整數。那可不可以把一個整數當作指針的值直接賦給

指針呢?就象下面的語句:

unsigned int a;

TYPE *ptr;//TYPE是int,char或結構類型等等類型。

...

...

a=20345686;

ptr=20345686;//我們的目的是要使指針ptr指向地址20345686(十進制)

ptr=a;//我們的目的是要使指針ptr指向地址20345686(十進制)

編譯一下吧。結果發現後面兩條語句全是錯的。那麼我們的目的就不能達到了嗎?不,還有辦法:

unsigned int a;

TYPE *ptr;//TYPE是int,char或結構類型等等類型。

...

...

a=某個數,這個數必須代表一個合法的地址;

ptr=(TYPE*)a;//呵呵,這就可以了。

嚴格說來這里的(TYPE*)和指針類型轉換中的(TYPE*)還不一樣。這里的(TYPE*)的意思是把無符號整數a的值當作一個地址來看待。

上面強調了a的值必須代表一個合法的地址,否則的話,在你使用ptr的時候,就會出現非法操作錯誤。

想想能不能反過來,把指針指向的地址即指針的值當作一個整數取出來。完全可以。下面的例子演示了把一個指針的值當作一個整數取出來,

然後再把這個整數當作一個地址賦給一個指針:

例十六:

int a=123,b;

int *ptr=&a;

char *str;

b=(int)ptr;//把指針ptr的值當作一個整數取出來。

str=(char*)b;//把這個整數的值當作一個地址賦給指針str。

好了,現在我們已經知道了,可以把指針的值當作一個整數取出來,也可以把一個整數值當作地址賦給一個指針。

第九章。指針的安全問題

看下面的例子:

例十七:

char s='a';

int *ptr;

ptr=(int*)&s;

*ptr=1298;

指針ptr是一個int*類型的指針,它指向的類型是int。它指向的地址就是s的首地址。在32位程序中,s佔一個位元組,int類型佔四個位元組。最後

一條語句不但改變了s所佔的一個位元組,還把和s相臨的高地址方向的三個位元組也改變了。這三個位元組是干什麼的?只有編譯程序知道,而寫程

序的人是不太可能知道的。也許這三個位元組里存儲了非常重要的數據,也許這三個位元組里正好是程序的一條代碼,而由於你對指針的馬虎應用

,這三個位元組的值被改變了!這會造成崩潰性的錯誤。讓我們再來看一例:

例十八:

1。 char a;

2。 int *ptr=&a;

...

...

3。 ptr++;

4。 *ptr=115;

該例子完全可以通過編譯,並能執行。但是看到沒有?第3句對指針ptr進行自加1運算後,ptr指向了和整形變數a相鄰的高地址方向的一塊存儲

區。這塊存儲區里是什麼?我們不知道。有可能它是一個非常重要的數據,甚至可能是一條代碼。而第4句竟然往這片存儲區里寫入一個數據!

這是嚴重的錯誤。所以在使用指針時,程序員心裡必須非常清楚:我的指針究竟指向了哪裡。

在用指針訪問數組的時候,也要注意不要超出數組的低端和高端界限,否則也會造成類似的錯誤。

在指針的強制類型轉換:ptr1=(TYPE*)ptr2中,如果sizeof(ptr2的類型)大於sizeof(ptr1的類型),那麼在使用指針ptr1來訪問ptr2所指向的

存儲區時是安全的。如果sizeof(ptr2的類型)小於sizeof(ptr1的類型),那麼在使用指針ptr1來訪問ptr2所指向的存儲區時是不安全的。至於

為什麼,讀者結合例十七來想一想,應該會明白的。

請寫出以下程序的運行結果:

#include <stdio.h>
int *p;
pp(int a,int *b);
main()
{
int a=1,b=2,c=3;
p=&b;
pp(a+c,&b);
printf("(1)%d%d%dn",a,b,*p);
}
pp(int a,int *b)
{int c=4;
*p=*b+c;
a=*p-c;
printf("(2)%d%d%dn",a,*b,*p);
}

『捌』 C語言考試教程◆全國計算機等級考試二級C語言視頻教程(完整版) 下載

計算機等級考試二級C語言

首先我們先看下軟體展示圖,最後是軟體!

圖:

3、未來教育2017二級msoffice模擬軟體

以其模式的高專業度,題庫權威度而聞名業界,它聚合歷年真題加以分析從而提出權威預測,效果非常不錯。

2、捷成全國計算機等級考試練習系統。

上機考試系統提供了歷屆考試題100套,並附有試題分析和參考答案,可以幫助考生熟悉考試模式,提高應試能力,測試實際操作和應變能力,自己評定成績,對正式考試時能否通過進行初步的估計。

1、全國計算機等級考試超級模擬軟體。

匯聚了多年開發全國計算機等級考試模擬軟體的豐富經驗,並綜合有經驗的命題專家、教授和全國各地考點一線教師的建議基礎上研製而成。本套軟體採用模擬考試形式,以大量的習題練習,強化考生的應考能力。

『玖』 在C語言里有哪些數據類型

C語言中的數據類型:一、基本類型二、構造類型三、指針類型四、空類型其中基本類型有:整型、字元型、實型(浮點型)、枚舉類型構造類型有:數組類型、結構體類型、共用體類型

『拾』 譚浩強C語言程序設計 第二章 演算法里的 例:2.2該怎麼用C語言解啊

int n[50]={n1,...,ni,...,n50}; // 填上學號
int g[50]={g1,...,gi,...,g50}; // 填上成績
for(i=1,i<=50;i++)
{
if(g[i-1]>=80)
printf("學號%d,成績%d\n",n[i-1],g[i-1]);
}