C程序設計實驗報告
姓名:黃靜微 實驗地點:宿舍 實驗時間:2020.06.02
實驗項目
8.3.1 指針基礎及指針運算
8.3.2 數據交換
8.3.3 字符串反轉及字符串連接
8.3.4 數組元素奇偶排列
一、實驗目的與要求
- 加強對指針數列的理解
- 熟悉指針的定義、通過指針間接訪問變量的方法
- 理解指針類型作為函數傳遞的方法
- 熟悉對字符指針及將指針作為函數打返回類型的操作
- 加強對使用指針對數組進行操作的理解
二、實驗內容
| 1、實驗練習:8.3.1 指針基礎及指針運算 |
問題的簡單描述:(1)定義一個整型指針變量p,使它指向一個整型變量a,定義一個浮點型指針q,使它指向一個浮點型變量b,同時定義另外一個整型變量c並賦初值3.
(2)使用指針變量,並調用函數scanf()函數分別輸入a和b的值。
(3)通過指針間接訪問並輸出a,b的值。
(4)按十六進制方式輸出p,q的值及a,b的地址。
(5)將p指向c,通過p間接訪問c的值並輸出
(6)輸出p的值及c的地址,並與上面的結果進行比較。
實驗代碼: #include <stdio.h>
int main()
{
int *p,a,c=3;
float *q,b;
p=&a;
q=&b;
printf("Please Input the Value of a,b:");
scanf("%d,%f",p,q);
printf("Result:\n");
printf("%d,%f\n",a,b);
printf("%d,%f\n",*p,*q);
printf("The Address of a,b:%p,%p\n",&a,&b);
printf("The Address of a,b:%p,%p\n",p,q);
p=&c;
printf("c=%d\n",*p);
printf("The Adress of c:%x,%x\n",p,&c);
}
問題分析: 這個問題主要是要熟悉指針的定義和通過指針間接訪問變量的方法,了解了基本的知識就沒什么問題,注意一下不要犯小錯誤,很順利地完成了這個實驗。
運行結果:

| 2、實驗練習:8.3.2 數據交換 |
問題的簡單描述:(1)定義兩個函數,分別為void swap1(int a,int b)和void swap2(int *a, int *b),用於交換a,b的值。
(2)從主函數中分別輸入兩個整形變量a、b。
(3)從主函數中分別調用上述兩個交換函數,並打印輸出變換后a,b的結果。
實驗代碼: #include <stdio.h>
void swap1(int x,int y);
void swap2(int *x,int *y);
int main()
{
int a,b;
printf("Please Input a=:");
scanf("%d",&a);
printf("\nb=:");
scanf("%d",&b);
swap1(a,b);
printf("\nAfter Call swap1:a=%d b=%d\n",a,b);
swap2(&a,&b); /*實參傳遞*/
printf("\nAfter Call swap2:a=%d b=%d\n",a,b);
return 0;
}
void swap1(int x,int y)
{
int temp;
temp=x;
x=y;
y=temp;
}
void swap2(int *x,int *y)
{
int temp;
temp=*x;
*x=*y;
*y=temp; /*交換x,y地址上的值*/
}
問題分析:在填swap2的時候出現了問題,swap2的實參傳遞是a,b的地址,不是a,b,剛開始填的時候直接填a,b就不行,實驗指導書上有說當使用指針作為形參時,實參必須是地址,也應是數組名。還有一點老師在上理論課的時候有說*x和*y交換的時候temp前面不需要加*,加了*表示的是地址交換,就不是值傳遞,這點在實驗的時候也需要注意。
運行結果:

| 3、實驗練習:8.3.3 字符串反轉及字符串連接 |
問題的簡單描述:(1)定義兩個字符指針。
(2)定義一個函數char *reverse(char *str),通過指針移動方式將字符串反轉。
(3)定義一個函數char link(charstr1,char *str2),通過指針移動方式將兩個字符串連接起來。
(4)從主函數中分別調用上述函數,輸入字符串並打印輸出結果。
實驗代碼: #include<stdio.h>
char *reverse(char *str);
char *link(char *str1, char *str2);
main()
{
char str[30], str1[30], *str2;
printf("input reversing character string:");
gets(str);
str2=reverse(str);
printf("\noutput reversed character string:");
puts(str);
printf("input string1:");
gets(str);
printf("input string2:");
gets(str1);
str2=link(str,str1);
puts(str2);
return 0;
}
char *reverse(char *str)
{
char *p,*q,temp;
p=str, q=str;
while(*p !='\0') //判斷是否是最后一個數值
p++;
p--;
while(q<p)
{
temp=*q;
*q=*p;
*p=temp;
p--; //指針做相向移動處理
q++;
}
return str;
}
char *link(char *str1, char *str2)
{
char *p=str1, *q=str2;
while(*p !='\0')
p++;
while(*q !='\0')
{
*p=*q;
p++;
q++;
}
str2=NULL; //令結束字符為空字符
return str1;
}
問題分析: 這個實驗在理解指針做相向移動處理的比較費勁,有些語句不是很理解,通過老師講解思路更清晰了。這里的第一個while里面的p++是它內部的,后面的p--是因為第一個while是對每個字符進行判斷,跳出循環后p指向了\0,所以p--使它回到\0的前一個字符進行調換。第二個while對尾部的字符調換,所以是q++,p--。
運行結果:
<img src="https://img2020.cnblogs.com/blog/1940817/202006/1940817-20200602104037104-489856574.png width="60%">
| 4、實驗練習:8.3.4 數組元素奇偶排列 |
問題的簡單描述:(1)定義一個整型一維數組,任意輸入數組的元素,其中包括奇數和偶數。
(2)定義一個函數,實現將數組元素奇數在左,偶數在右的排列。
(3)在上述定義的函數中,不允許在增加新的數組。
(4)從主函數中分別調用上述函數,打印輸出結果。
實驗代碼: #include <stdio.h>
#define N 10
void arrsort(int a[],int n);
main()
{
int a[N],i;
for(i=0;i<N;i++)
scanf("%d",&a[i]);
arrsort(a,N);
for(i=0;i<N;i++)
printf("%d ",a[i]);
}
void arrsort(int a[],int n)
{
int *p,*q,temp;
p=a;
q=a+n-1;
while(p<q){
while(*p%2!=0)
p++;
while(*q%2==0)
q--;
if(p>q)
break;
temp=*p;
*p=*q;
*q=temp;
p++;
q--;
}
}
問題分析: 一開始寫完這個程序的時候運行出來的輸出結果數字與數字之間沒有間隔,就是一長串的數字,但是順序是對的,通過對代碼的再次檢查,在輸出后面加上空格,就得到了正確的格式,這種小問題發現比較難,在打代碼的時候就要留心。
錯誤運行結果

運行結果:

四、實驗小結
這一章的實驗比較少,一共是4個實驗,但通過實驗還是反映出比較多的問題,我感覺第八章的指針比較難理解,比較頭疼指針,通過老師講解實驗理解會好很多,思路也更清晰很多,但還是要多去理解,也有些東西需要去記憶。比如:一個字符串在內存中是連續存儲的,它的開始地址為指向字符串的指針值,字符串的結束字符為\0。當使用指針作為形參時,實參必須是地址,也應是數組名。總之還是要多去理解代碼,多從錯誤中學習吧,這樣學習指針會好好一點,加油吧。
