指针的使用
指针真的是重点。当然后面学习数据结构时多使用就会好些的。
1.函数指针
#include <stdio.h>
int getMax(int x, int y);
int getMin(int x, int y);
int add(int x, int y);
int process( int x, int y, int (*p)(int, int) ) // 1
{ //记得这里要加上两个int
return p(x, y); // 2 (关键)
}
int main()
{
int a, b;
printf("请输入两个数字: ");
scanf("%d %d", &a, &b);
printf("max=%d\n", process(a, b, getMax) ); // 3: 转入的是函数名
printf("min=%d\n", process(a, b, getMin) );
printf("add=%d\n", process(a, b, add) );
return 0;
}
int getMax(int x, int y)
{
return x > y ? x : y;
}
int getMin(int x, int y)
{
return x < y ? x : y;
}
int add(int x, int y)
{
return x + y;
}
2.函数指针之通用冒泡排序
#include <stdio.h>
#include <stdbool.h>
bool Ascending(int a, int b)
{
return a > b; //大于为真, 则升序
} //相当于: a[j] > a[j + 1]
bool Descending(int a, int b)
{
return a < b; //小于为真, 则降序
}
/*使用函数指针编写一个通用的排序函数*/
void bubbleSort( int a[], int n, bool (*compare)(int, int) )
{
for(int i = 0; i < n - 1; i++)
{
for(int j = 0; j < n - 1 - i; j++)
{
if( (*compare)(a[j], a[j + 1]) )
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
int main()
{
int Array[5] = {1, 456, 78, 30, 89};
bubbleSort(Array, 5, Ascending); //升序排列
for(int i = 0; i < 5; i++)
{
printf("%d ", Array[i]);
}
return 0;
}
3.函数中的指针
某公司有职员(最多50人),试编写程序打印最高工资、最低工资和平均工资。公司人数在主函数给出,职工工资输入请调用Input函数,计算最高工资、最低工资和平均工资调用Compute函数,打印最高工资、最低工资和平均工资在主函数。请在给定的框架下写出完整程序。
#include <stdio.h>
void Input(double wage[], int n);
double Compute(double wage[], int n, double *pmaxwage, double *pminwage);
int main()
{
int n;
printf("Please input n:\n");
scanf("%d",&n);
double wage[50], maxwage = -1, minwage = -1, avewage;
Input(wage, n);
avewage = Compute(wage, n, &maxwage, &minwage);
printf("maxwage=%.2f, minwage=%.2f, avewage=%.2f\n", maxwage, minwage, avewage);
return 0;
}
void Input(double wage[], int n)
{
for(int i = 0; i < n; i++)
{
scanf("%lf", &wage[i]);
}
}
double Compute(double wage[], int n, double *pmaxwage, double *pminwage)
{
double sum = 0; //这里指针的使用均使用 取内容* 从而间接的更改主函数上的值 关键: 地址不变, 故不需要使用 &号
*pmaxwage = wage[0], *pminwage = wage[0];
for(int i = 0; i < n; i++)
{
sum += wage[i];
if(wage[i] > *pmaxwage)
{
*pmaxwage = wage[i];
}
if(wage[i] < *pminwage)
{
*pminwage = wage[i];
}
}
return sum / n;
}
/*数据:
10
1200.34
2378.48
8600.56
5372.42
6317.25
7265.88
2156.39
1876.31
1792.14
4326.22
*/
4.字符指针数组
字符指针数组: 每个数组元素都是一个指向字符串的指针; 区别: 无括号
其中: 字符串在常量储存区, 数组的里面类型是指针, 分别指向对应的字符串
char *country[5] = {"Aass", "xsax", "scasc", "cdscc", "csdcyjt"};
for(int i = 0; i < 5; i++)
{
printf("%s\n", country[i]);
} //country[i]是一个指针--->代表字符串
//交换: char *temp = pStr[i]; ......
void SortString(char *pStr[], int n) //理解: 二维数组
{
for(int i = 0; i < n; i++) {
for(int j = i + 1; j < n; j++){
if(strcmp(pStr[j], pStr[i]) < 0)
{
char *temp = pStr[i]; //交换指针数组中的字符串指针
pStr[i] = pStr[j]; //指针的指向变了
pStr[j] = temp;
}
}
}
}
5.行指针与列指针
/*指针与数组:
int (*p)[3] = a; //行指针 注意括号, 指向二维数组a[][3]
使用: *(*(p + i) + j)
int *p; //列指针
p = a[0]; //即&a[0][0]
使用: *(p + i*n + j) //其中n为列数 for(int j = 0; j < n; j++)
1.行指针: 使用很少 --> 相当于a[][]
参数: void InputArray(int (*p)[N], int m, int n)
主函数: InputArray(a, m, n);
输出: *(p + i) + j
打印: *( *(p + i) + j )
2.列指针
参数: void InputArray(int *a, int m, int n)
主函数: InputArray(*a, m, n);
输出: &p[i*n+j]
打印: p[i*n+j]
3. 保护数组的数据const
void InputArray(const int (*p)[N], int m, int n)
void InputArray(const int *p, int m, int n)
*/
#include <stdio.h>
#define N 15
void InputArray(int *p, int m, int n); //列指针
int FindMax(int *p, int m, int n, int *pRow, int *pColumn);
int main()
{
int m = 0, n = 0;
printf("Input m,n:\n");
scanf("%d,%d", &m, &n);
int a[N][N] = {0};
printf("Input %d*%d array:\n", m, n);
InputArray(*a, m, n); //列指针
int rowPos = 0, columnPos = 0;
int Max = FindMax(*a, m, n, &rowPos, &columnPos);
printf("max=%d,row=%d,col=%d\n", Max, rowPos, columnPos);
return 0;
}
void InputArray(int *p, int m, int n) //int (*p)[N]
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d", &p[i * n + j]);
} // p++ 打印: *p++ 也就是 *p --> p++
}
}
/*函数返回最大值, pRow和pCol分别返回最大值所在的行列下标*/
int FindMax(int *p, int m, int n, int *pRow, int *pColumn)
{
int max = *p;
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if(p[i * n + j] > max)
{
max = p[i * n + j];
*pRow = i;
*pColumn = j;
}
}
}
return max;
}
/*数据:
1 2 3 4
5 6 7 8
9 0 -1 -2
*/
字符串
1.<string.h>的函数
下面的代码主要是仿写对应的c语言函数
strlen() :求字符串长度
// const其保护作用, 防止在函数中更改str[]
int MyStrlen( const char str[] )
{
int len = 0;
for(int i = 0; str[i] != '\0'; i++)
{
len++;
}
return len;
}
strcpy() :字符串的复制
/*将str2复制给str1(数组)*/
void MyStrcpy(char str1[], const char str2[])
{
int end = 0;
for(int i = 0; str2[i] != '\0'; i++)
{
str1[i] = str2[i];
end = i;
}
str1[end] = '\0'; //这里一定要加结束的标志!
}
/*将str2复制给str1(指针)*/
void MyStrcpy(char *str1, const char *str2)
{
while(*str2 != '\0') //关键: 等价于while(*str2) 为真
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0'; //这里一定要加结束的标志!
}
strcat() :字符串的拼接
#include <stdio.h>
#include <string.h>
char *MyStrcat( char *str1, char *str2 );
int main()
{
char str1[100], str2[30];
printf("please input the first string: \n");
gets(str1);
printf("please input the second string: \n");
gets(str2);
char *pResult = NULL;
pResult = MyStrcat(str1, str2);
printf("The result is: %s\n", pResult);
return 0;
}
/*将str2连接到str1后*/
char *MyStrcat( char *str1, char *str2 )
{
char *pStr = str1; //pStr用来保存str1的首地址, 便于返回
while(*str1 != '\0') //将str1的指针移至末尾\0, 等待连接
{
str1++;
}
//进行连接中的复制操作
while(*str2 != '\0') //画图, 明白指针所指向的位置!!!
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return pStr;
}
strstr() :查询子串
/*关键数据:
How are you!
are 5
abcabc
bc 应该是2而不是5
*/
#include <stdio.h>
#include <string.h>
int SearchString( char s[], char d[] );
int main()
{
char str1[100], str2[100];
printf("Input a string:");
gets(str1);
printf("Input another string:");
gets(str2);
int ans = SearchString(str1, str2);
if(ans == -1)
{
printf("Not found!\n");
}
else
{
printf("Searching results:%d\n", ans);
}
return 0;
}
/*在字符数组s中查找子串d,返回d在s中首次出现的位置,若找不到,则返回-1*/
int SearchString( char s[], char d[] )
{
int position = 0;
int len = strlen(s);
for(int i = 0; i < len; i++)
{
if(s[i] == d[0])
{
int j = 0;
position = i;
while(s[i] == d[j] && d[j] != '\0')
{
i++;
j++;
}
if(d[j] == '\0') //相同到底, 任务结束
{
return position + 1;
}
else //复原以便于下一次循环
{
i = position;
}
}
}
return -1; //查找不到, 返回-1
}
atoi()
函数atoi()将字符串里的数字字符转化为整形数, 返回整形值;
注意:转化时跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,
而再遇到非数字或字符串结束时’\0’才结束转换, 并将结果返回
/*数据:
7hg09y 7
9w2k7m0 9
happy 0
*/
#include <stdio.h>
#include <stdlib.h> //头文件
int main()
{
char str[10];
printf("Input a string:");
scanf("%7s", str);
int ans = atoi(str);
printf("%d\n", ans);
return 0;
}
数字字符串转换为整型数
/*数据:
7hg09y 709
9w2k7m0 9270
happy 0
*/
#include <stdio.h>
#include <string.h>
int Myatoi(char str[]);
int main()
{
char str[10];
printf("Input a string:");
scanf("%7s", str);
int ans = Myatoi(str);
printf("%d\n", ans);
return 0;
}
/*形参数组str[]对应用户输入的字符串,函数返回值为转换后的整型数*/
int Myatoi(char str[])
{
int len = strlen(str);
int bits = 0;
int result[10] = {0}; //用数组储存该字符串中的数字
for(int i = 0; i < len; i++)
{
if(str[i] >= '0' && str[i] <= '9')
{
int temp = str[i] - '0';
result[bits] = temp;
bits++;
}
}
int sum = 0, P = 1; //数组-->int型
for(int i = bits - 1; i >= 0; i--) //逆向输出
{
sum += result[i] * P;
P *= 10;
}
return sum;
}
删除相同字符
#include <stdio.h>
#include <string.h>
int main()
{
char str[110];
printf("Input a string:\n");
gets(str);
char ch;
printf("Input a character:\n");
ch = getchar();
int len = strlen(str);
for(int i = 0; i < len; i++) //关键
{
if(str[i] == ch)
{
int position = i;
while(str[i] != '\0') //循环依次移动
{
str[i] = str[i + 1];
i++;
}
len--; //字符串的长度减1
i = position - 1;
}
}
printf("Results:%s\n", str);
return 0;
}
文件
文件这里确实麻烦,没好好学 。不过看java IO流就会清晰一点的。
读
fgetc
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("C:\\Users\\deng\\Desktop\\zzz.txt", "r"); //read格式
/*关键的代码 */
char ch;
ch = fgetc(fp);
while(ch != EOF)
{
putchar(ch);
ch = fgetc(fp);
}
fclose(fp);
return 0;
}
fgets
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("C:\\Users\\deng\\Desktop\\zzz.txt", "r"); //read格式
/*关键的代码 */
char str[100];
fgets(str, 100*sizeof(str), fp);
puts(str);
fclose(fp);
return 0;
}
fscanf
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("C:\\Users\\deng\\Desktop\\zzz.txt", "r"); //read格式
/*关键的代码 */
char str[20];
fscanf(fp, "%s", str);
puts(str); //显示文件第一行内容(但中文会出现乱码)
fclose(fp);
return 0;
}
写
fputc
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("C:\\Users\\deng\\Desktop\\zzz.txt", "w");
char ch;
ch = getchar();
while(ch != '\n') /* 输入为换行时结束 */
{
fputc(ch, fp); //fputc函数用于向文件写入一个字符
ch = getchar();
}
fclose(fp);
return 0;
}
fputs
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("C:\\Users\\deng\\Desktop\\zzz.txt", "w");
char str[100];
gets(str);
fputs(str, fp); //将str数组的字符串写入fp指向的文件
fclose(fp);
return 0;
}
fprintf
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("C:\\Users\\deng\\Desktop\\zzz.txt", "w");
/*关键的代码 */
int a = 10;
fprintf(fp, "打印一行数\n"); //文件中会有两行...
fprintf(fp, "a=%d\n", a);
fclose(fp);
return 0;
}