IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言入门】笔记十 (指针下) -> 正文阅读

[C++知识库]【C语言入门】笔记十 (指针下)

例8-11 输入5个字符串,输出其中最小的字符串。

#include <stdio.h>
#include <string.h>
int main(void){
    int i;
    char sx[80], smin[80];

    scanf("%s", sx);
    strcpy(smin, sx);
    for (i = 1; i < 5; i++) {
        scanf("%s", sx);
        if (strcmp(sx, smin) < 0) {
            strcpy(smin, sx);
        }
    }
    printf("min is %s\n", smin);
    return 0;
}

C语言便准库中还有许多其他多种用于处理字符和字符串的函数,分别包含在ctype.hstring.h文件中,可参考附录A。

练习8-6

在使用函数?scanf()?时,输入阐述列表需要使用取地址操作符?&,但当参数为字符数组名时并没有使用,为什么?如果在字符数组名前加上取地址操作符?&,会发生什么?

答:因为字符数组名本身就是数组首项的地址,所以不需要使用地址操作符号。如果加上&的话,就是取数组第一项地址存放的地址(木知对不对)

练习8-7

C语言不允许用赋值表达式直接对数组赋值,为什么?

答:因为数组名本身就是一个指针,指向的地址是数组的第一项的地址,所以不能直接对其赋值。

练习8-8

输入一个字符串,把该字符串的前三个字母移到最后,输出变换后的字符串。比如输入"abcdef",输出为"defabc"

(用书上的指定的PTA平台做的题,补全下面的代码)

void Shift( char s[] ){
    int num=strlen(s), i;
    char s2[3];
    for(i=0;i<=2;i++){
        s2[i]=s[i];
    }
    for(i=0;i<=num-3;i++){
        s[i]=s[i+3];
    }
    strcat(s,s2);
}

测试通过:?

*8.5 任意个整数求和

例8-12?先输入一个正整数n,再输入任意n个整数,计算并输出这n个整数的和。要求使用动态内存分配方法为这n个整数分配空间。

#include <stdio.h>
#include <stdlib.h>
int main(void) {
	int n, sum, i, * p;
	printf("Enter n:");
	scanf("%d", &n);
	if ((p = (int*)calloc(n, sizeof(int))) == NULL) {
		printf("Not able allocate memory.\n");
		exit(1);
	}
	printf("Enter %d integers:", n);
	for (i = 0; i < n; i++) {
		scanf("%d", p + i);
	}
	sum = 0;
	for (i = 0; i < n; i++) {
		sum = sum + *(p + i);
	}
	printf("The sum is %d \n", sum);
	free(p);
	return 0;
}

首先通过输入的n的值,使用函数calloc()申请能存放n个int型数据的内存单元。如果申请成功,就得到动态内存的首地址,将该地址存放在指针p中,通过移动指针存入n个整数,再通过移动指针去除各个数并计算它们的和。动态内存申请的存储空间没有名字,只有首地址的连续存储空间,相当于一个一维数组。

此动态内存的首地址经过强制类型转换成int型存放在指针变量p中,通过移动p来存取各个数据。

8.5.2 使用指针实现内存动态分配

程序中需要使用各种变量来保存被处理的数据和各种状态信息,变量在使用前必须被定义且安排好存储空间(起始地址和存储单元大小)。C语言的全局变量、静态局部变量的存储时在编译时确定的,其存储空间的实际分配在程序开始执行前完成。

局部自动变量在执行进入变量定义所在的复合语句时为它们分配存储单元,这种变量的大小也是静态确定的。

静态方法安排存储的好处时实现方便,效率高,程序执行中需要做的事情较简单,但是如例8-7所描述的问题,每次求和的项数可能不同,可能的方法就是定义一个很大的数组,以保证输入的项数不超过数组能容纳的范围。

当在一般情况时,运行中的很多存储要求在写程序时无法确定,所以需要一种机制,可以根据运行时的实际存储需求适当分配存储区,用于存放那些在运行中才能确定数量的数据。C语言为此提供了动态存储管理机制,允许程序动态申请和释放存储空间。

C语言中的两种方法使用内存:

1. 由编译系统分配的内存区

2. 用内存动态分配方式,留给程序动态分配的存储区。动态分配的存储区在用户的程序之外,不是由编译系统分配的,而是由用户在程序中通过动态分配获取的。使用动态内存分配有效地使用内存,同一段存储区域可以被多次使用,使用时申请,用完就释放。

动态内存分配的步骤:

(1) 了解需要多少内存空间。

(2) 利用C语言提供的动态分配函数来分配所需要的存储空间。

(3) 使指针指向获得的内存空间,以便用指针在该空间内实施运算或操作

动态内存分配的函数(stdlib.h中):

(1) 动态存储分配函数malloc():

函数原型是:void *malloc (unsigned size)

功能:在内存的动态存储区中分配一连续空间,长度为size。如果申请成功,则返回指向所分配内存空间的其实地址的指针;如果申请内存不成功,则返回NULL(值为0)。malloc()的返回值为(void * )类型。在具体使用中,将malloc()的返回值转换为特定指针类型,赋给一个指针。

例题8-12中的申请内存可改为:

	if ((p = (int*)malloc(n*sizeof(int))) == NULL) {
		printf("Not able allocate memory.\n");
		exit(1);
	}

这里的存储块是动态分配的,但是它的大小在分配后是确定的。不要越界使用。

(2) 计数动态存储分配函数calloc():

函数原型是:void *calloc (unsigned n, unsigned size)

功能:在内存的动态存储区中分配n个连续空间,每一个存储空间的长度为size,并且分配后还把存储里全部初始化为0。若申请成功,则返回一个指向被分配内存空间的起始地址的指针;若申请内存空间不成功,则返回NULL(值为0)

malloc()分配存储块后不做任何事,calloc()对整个区域进行初始化

(3) 动态存储释放函数free():

函数原型是:void free (void *ptr)

功能:释放由动态存储分配函数申请到的整块内存空间,ptr为指向要释放空间的首地址。如果ptr的值是空指针,则free什么都不做。

(4) 分配调整函数realloc():

函数原型是:void *realloc (void *ptr, unsigned size)

功能:更改以前的存储分配。ptr必须是以前通过动态存储分配得到的指针。参数size为现在需要的空间大小。如果分配失败,则返回NULL,同时原来ptr指向存储块的内容不变,如果成功,返回一片能存放大小为size的区块,并保证该块的内容与原块的一致。如果size小于原块的大小,则内容为原块前四则范围内的数据;如果新块更大,则原有数据存在新块的前一部分。

练习8-9

使用动态内存分配的方法实现例8-5的冒泡排序。

#include <stdio.h>
#include <stdlib.h>
int main(void) {
	int i, n, j, temp;
	int* p;
	printf("Enter n:");
	scanf("%d", &n);
	if ((p = (int*)calloc(n, sizeof(int))) == NULL) {
		printf("Not able allocate memory.\n");
		exit(1);
	}
	printf("Enter data:");
	for (i = 0; i < n; i++) {
		scanf("%d", (p + i));
	}

	for (i = 0; i < n; i++) {
		for (j = 0; j < n-1; j++) {
			if (*(p + j) < *(p + j + 1)) {
				temp = *(p + j);
				*(p + j) = *(p + j + 1);
				*(p + j + 1) = temp;
			}
		}
	}
	for (j = 0; j < n; j++) {
		printf("%d", *(p + j));
	}
	return 0;
}

习题8

程序设计题1

拆分实验的整数与小数部分:要求自定义一个函数void splitfloat(float x, int *intpart, float * fracpart),其中x是被拆分的实数,* interpart* ftacpart分别是将实数x拆分出来的整数部分与小数部分。编写主函数,并在其中调用函数splitfloat()

#include <stdio.h>
void splitfloat(float x, int* intpart, float* fracpart);
int main(){
    float x, fracpart;
    int intpart;
    scanf("%f", &x);
    splitfloat(x, &intpart, &fracpart);
    printf("The integer part is %d\n", intpart);
    printf("The fractional part is %g\n", fracpart);
    return 0;
}
/* 你的代码将被嵌在这里 */
void splitfloat(float x, int* intpart, float* fracpart) {
    *intpart = x * 1;
    *fracpart = x - *intpart;
}

程序设计题2

在数组中查找指定元素:输入一个正整数n(1<n≤10),然后输入n个整数存入数组a中,再输入一个整数x,在数组a中查找x,若找到则输出相应的下标,否则显示"Not found"。要求定义和调用函数search(int list[], int n, int x),在数组list中查找元素x,若找到则返回相应的下标,否则返回-1,参数n代表数组list中元素的数量。

#include <stdio.h>
#define MAXN 10
int search(int list[], int n, int x);
int main(){
    int i, index, n, x;
    int a[MAXN];
    scanf("%d", &n);
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);
    scanf("%d", &x);
    index = search(a, n, x);
    if (index != -1)
        printf("index = %d\n", index);
    else
        printf("Not found\n");
    return 0;
}
/* 你的代码将被嵌在这里 */
int search(int list[], int n, int x) {
    int i, result=0;
    for (i = 0; i < n; i++) {
        if (list[i] == x) {
            result = 1;
            return i;
        }
    }
    if (result == 0) {
        return -1;
    }
}

程序设计题3

循环后移:有n个整数,使前面各数顺序向后移m个位置,移出的数再从开头移入。编写一个函数实现以上功能,在主函数中输入n个整数并输出调整后的n个数。

#include <stdio.h>
#define MAXN 10
void ArrayShift(int a[], int n, int m);
int main(){
    int a[MAXN], n, m;
    int i;
    scanf("%d %d", &n, &m);
    for (i = 0; i < n; i++) scanf("%d", &a[i]);
    ArrayShift(a, n, m);
    for (i = 0; i < n; i++) {
        if (i != 0) printf(" ");
        printf("%d", a[i]);
    }
    printf("\n");
    return 0;
}
/* 你的代码将被嵌在这里 */
void ArrayShift(int a[], int n, int m) {
    int b[MAXN], c[MAXN];
    int i;
    m = m % n;
    for (i = n - m; i < n; i++) {
        b[i - n + m] = a[i];
    }
    for (i = 0; i < n - m; i++) {
        c[i] = a[i];
    }
    for (i = 0; i <= m-1; i++) {
        a[i] = b[i];
    }
    for (i = m; i < n; i++) {
        a[i] = c[i - m];
    }
}

程序设计题4

报数:有n个人围成一圈,按顺序从1到n编好号。从第一个人开始报数,包到m的人退出圈子,下一个人从1开始报数,报道m的人退出圈子。如此下去,直到留下最后一个人。输入整数n和m,并按退出顺序输出退出圈子的编号。

#include <stdio.h>
#define MAXN 20

void CountOff( int n, int m, int out[] );

int main()
{
    int out[MAXN], n, m;
    int i;

    scanf("%d %d", &n, &m);
    CountOff( n, m, out );   
    for ( i = 0; i < n; i++ )
        printf("%d ", out[i]);
    printf("\n");

    return 0;
}

/* 你的代码将被嵌在这里 */
void CountOff(int n, int m, int out[]) {
    int i, j, count = 0, index = 1, a[MAXN];
    for (i = 0; i < n; i++) {
        a[i] = 1;
    }
    while(index<=n) {
        for (i = 0; i < n; i++) {
            if (a[i] != 0) {
                count++;
                if (count == m) {
                    out[i] = index;
                    index++;
                    a[i] = 0;
                    count = 0;
                }
            }
        }
    }
}

程序设计题5

使用函数实现字符串赋值:输入一个字符串t和一个正整数m,将字符串t中从第m个字符开始的全部字符复制到字符串s中,再输出字符串s。要求自定义并调用函数void strmcpy (char* s, char *t, int m)

#include <stdio.h>
#define MAXN 20

void strmcpy( char *t, int m, char *s );
void ReadString( char s[] ); /* 由裁判实现,略去不表 */

int main()
{
    char t[MAXN], s[MAXN];
    int m;

    scanf("%d\n", &m);
    ReadString(t);
    strmcpy( t, m, s );
    printf("%s\n", s);

    return 0;
}

/* 你的代码将被嵌在这里 */
void strmcpy(char* t, int m, char* s){
    int count=0,i=m-1;
    while(t[i]!='\0'){
        count++;
        i++;
    }
    for(i=m-1;i<=m-1+count;i++){
        s[i-m+1]=t[i];
    }
}

程序设计题6

删除字符:输入一个字符串,再输入一个字符ch,将字符串中所有的ch字符删除后输出该字符串,要求定义和调用函数delchar(s,c),该函数将字符串s中出现的所有c字符删除。

#include <stdio.h>
#define MAXN 20

void delchar( char *str, char c );
void ReadString( char s[] ); /* 由裁判实现,略去不表 */

int main()
{
    char str[MAXN], c;

    scanf("%c\n", &c);
    ReadString(str);
    delchar(str, c);
    printf("%s\n", str);

    return 0;
}

/* 你的代码将被嵌在这里 */
void delchar( char *str, char c ){
    int i=0,j;
    while(str[i]!='\0'){
        if(str[i]==c){
            for(j=i;str[j]!='\0';j++){
                str[j]=str[j+1];
            }
            i--; //重要,如果碰到替换的会跳一次
        }
        i++;
    }
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-29 16:08:07  更:2021-11-29 16:08:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:19:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码