2020年度卒業予定、卒研入門生として9名新メンバーが加入しました。
- 于 澤
- 劉 明宇
- 邱 子豪
- 劉 洋
- 王 天麟
- 張 耀維
- 熊 友启
- 林 嬌龍
- LE NHU NGOC
お花見をしながら歓迎会を開きました。
ユビキタスコンピューティング研究ポータル
| 出題内容 | ||
| 定数 | 浮動小数点定数 | 指数形式を許す 浮動小数点接尾語はf、l、F、Lのいずれか |
|---|---|---|
| 整数定数 | 整数接尾語として長語接尾語(l、L)を含む | |
| 文字定数 | 拡張表記は8進拡張表記、16進拡張表記を含む | |
| 文字列リテラル | 拡張表記は8進拡張表記、16進拡張表記を含む | |
| 列挙定数 | ||
| 演算子 | ビット演算子、条件演算子、代入演算子、キャスト演算子、ポインタ/アドレス演算子、構造体演算子、sizeof演算子 | |
| 宣言指定子 | void、short、long、float、double、構造体共用体指定子(struct、union)、列挙型指定子(enum)、型修飾子(const)、typedef | |
| 変数 | 上記型指定子の単純変数、配列 | |
| 外部定義 | ||
| プリプロセッサ機能 | ファイルの包含 | |
| ライブラリ関数 |
|
|
|
||
|
||
|
||
| その他 |
|
|
※3級出題範囲含む
注)各級とも日本工業規格 (JIS) X3010 で出題・解答する。
http://www.sikaku.gr.jp/js/cp/
C言語は、記述の自由度が高く、使用可能なプラットホームが多いなど、使用できる場面が多いことから、現在最も広く普及しているプログラミング言語です。このC言語のプログラミング能力の測定を目的に、1992年より開始されたのがサーティファイ 情報処理能力認定委員会が主催する「C言語プログラミング能力認定試験」です。
保有スキルのレベルに合わせた3段階の認定基準を設けることにより、これから新たにプログラミングの学習を始める方から、現在プログラマやシステム・エンジニアとして既に活躍されている高度IT技術者の方まで、幅広い皆様から受験いただいています。
「C言語プログラミング能力認定試験」は、これからプログラミングを学び始める方を対象とした「3級」から、プログラマやシステム・エンジニアとして活躍されている方の保有スキルを客観的にアピールできる「1級」まで、幅広いスキルを測定しています。
特に「1級」では、実際にPCを使用して、プログラムの仕様変更やこれに伴うプログラミング作成(コーディング・コンパイル・デバッグ)を行う、極めて実践的な資格・検定試験として、IT業界でも高く評価されています。
「C言語プログラミング能力認定試験」の「2級」及び「3級」は、経済産業省認定「基本情報技術者試験」の「午後問題」の出題形式も意識して作成しています。そのため、「基本情報技術者試験」の学習と連動した活用も多く見られます。保有スキルのレベルに応じた級位取得を目標としていただくことで、C言語のプログラミング能力を高めるだけではなく、「基本情報技術者試験」の合格にもつなげていくことができます。
C言語プログラミング能力認定試験
(C-Language Programming Skills Qualification Test)
C言語を駆使して応用プログラム(言語処理系、ユーティリティなど)を作成する能力を認定します。
| 一級 | C言語を駆使し、応用プログラム(言語処理系、ユーティリティなど)が作成できる能力を有する。また使用しているOSについて理解をしている。 |
| 二級 | 小規模のプログラム(500行程度)が適切に(理路整然、簡潔、正しく、速く)書ける。また各種基本アルゴリズムを理解している。 |
| 三級 | C言語の概念を理解し、簡単なプログラムが書ける。 |
| 出題内容 | ||
| 定数 | 整数定数 | 10進定数、8進定数、16進定数 整数接尾語は符号無し接尾語(u、U)のみ |
|---|---|---|
| 文字定数 | ワイド文字定数(L’c文字の列’)を除く 拡張表記は単純拡張表記のみ |
|
| 文字列リテラル | ワイド文字列リテラル(L”s文字の列”)を除く 拡張表記は単純拡張表記のみ |
|
| 演算子 | 算術演算子、インクリメント演算子、デクリメント演算子、(算術の)代入演算子、関係演算子、等値演算子、論理関係演算子、括弧演算子、コンマ演算子 | |
| 型指定子 | char、int、unsigned、signed | |
| 変数 |
|
|
| 基本制御文 | break、continue、do、for、if、return、switch、while | |
| プリプロセッサ機能 | #define、#include | |
| ライブラリ関数 |
|
|
|
||
| その他 | Cの歴史と特徴 | |
現在使用するC言語教科書には、文字操作関数<ctype.h>の内容について不足するので、
[amazonjs asin=”479815038X” locale=”JP” ]
下記のサイトを参考にしてください。
C#やJavaでは簡単にhttp Clientプログラムができる。C言語ではソケットを作成するところから必要です。またWindowsとLinux両方対応するように書いたのでプログラムが長くなる。
(bcc32で動作確認済み)
プログラムは、最初にsocketを生成してWebサーバに接続し、テキスト形式でHTTPリクエストメッセージを作成してWebサーバに送信する。
HTTPリクエストメッセージは、複数行から成り立つ一連のデータ列。ここでいう1行とは、終端にCR(キャリッジリターン、16進の0x0d)とLF(ラインフィード、16進の0x0a)を持つデータの単位を示す。ほぼ、通常のテキスト・データの1行と等しくなる。メッセージ・ヘッダとメッセージボディ部に分かれ、両者は空行(単独のCR+LF)で分割される。
httpを理解するには、telnetで手入力でHTTPをしゃべってみるがいい方法。
https://www.softel.co.jp/blogs/tech/archives/263
まずプログラムをリストする:
#include <stdio.h> /* printf, sprintf */
#include <stdlib.h> /* exit, atoi, malloc, free */
// #include <unistd.h> /* read, write, close */
#include <string.h> /* memcpy, memset */
#ifdef __linux__
#include <sys/socket.h> /* socket, connect */
#include <netdb.h> /* struct hostent, gethostbyname */
#include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
#elif _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#else
#endif
struct hostent *server;
struct sockaddr_in serv_addr;
int bytes, sent, received;
char response[4096];
int portno;
char *host;
char *path;
void error(const char *msg) { perror(msg); exit(0); }
#ifdef _WIN32
win_send_http(char *message){
WSADATA wsa;
SOCKET s;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
server = gethostbyname(host);
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);
//Connect to remote server
if (connect(s , (struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0)
{
printf("connect failed with error code : %d" , WSAGetLastError());
return 1;
}
puts("Connected");
if( send(s , message , strlen(message) , 0) < 0)
{
printf("Send failed with error code : %d" , WSAGetLastError());
return 1;
}
puts("Data Send\n");
//Receive a reply from the server
if((received = recv(s , response , 2000 , 0)) == SOCKET_ERROR)
{
printf("recv failed with error code : %d" , WSAGetLastError());
}
puts("Reply received\n");
//Add a NULL terminating character to make it a proper string before printing
response[received] = '\0';
puts(response);
closesocket(s);
WSACleanup();
return 0; // everything OK
}
#endif
#ifdef __linux__
linx_send_http(message) {
int sockfd;
int total;
total = strlen(message);
/* lookup the ip address */
server = gethostbyname(host);
if (server == NULL) error("ERROR, no such host");
/* create the socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
/* fill in the structure */
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);
/* connect the socket */
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
/* send the request */
sent = 0;
do {
bytes = write(sockfd,message+sent,total-sent);
if (bytes < 0)
error("ERROR writing message to socket");
if (bytes == 0)
break;
sent+=bytes;
} while (sent < total);
/* receive the response */
memset(response, 0, sizeof(response));
total = sizeof(response)-1;
received = 0;
printf("Response: \n");
do {
printf("%s", response);
memset(response, 0, sizeof(response));
bytes = recv(sockfd, response, 1024, 0);
if (bytes < 0)
printf("ERROR reading response from socket");
if (bytes == 0)
break;
received+=bytes;
} while (1);
if (received == total)
error("ERROR storing complete response from socket");
/* close the socket */
close(sockfd);
return 0; // everything OK
}
#endif
int main(int argc,char *argv[])
{
int i;
char message[4096];
portno = atoi(argv[2])>0?atoi(argv[2]):80;
host = strlen(argv[1])>0?argv[1]:"localhost";
path = strlen(argv[4])>0?argv[4]:"/";
if (argc < 5) { puts("Parameters: <host> <port> <method> <path> [<data> [<headers>]]"); exit(0); }
/* How big is the message? */
if(!strcmp(argv[3],"GET"))
{
if(argc>5)
sprintf(message,"%s %s%s%s HTTP/1.0\r\nHost: %s\r\n",
strlen(argv[3])>0?argv[3]:"GET", /* method */
path, /* path */
strlen(argv[5])>0?"?":"", /* ? */
strlen(argv[5])>0?argv[5]:"",host); /* query string */
else
sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n",
strlen(argv[3])>0?argv[3]:"GET", /* method */
path,host); /* path */
for(i=6;i<argc;i++) /* headers */
{strcat(message,argv[i]);strcat(message,"\r\n");}
strcat(message,"\r\n"); /* blank line */
}
else
{
sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n",
strlen(argv[3])>0?argv[3]:"POST", /* method */
path,host); /* path */
for(i=6;i<argc;i++) /* headers */
{strcat(message,argv[i]);strcat(message,"\r\n");}
if(argc>5) {
sprintf(message+strlen(message),"Content-Length: %d\r\n",(int)strlen(argv[5]));
sprintf(message+strlen(message),"Content-Type: application/x-www-form-urlencoded\r\n");
}
strcat(message,"\r\n"); /* blank line */
if(argc>5)
strcat(message,argv[5]); /* body */
sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n",
strlen(argv[3])>0?argv[3]:"POST", /* method */
path,host); /* path */
for(i=6;i<argc;i++) /* headers */
{strcat(message,argv[i]);strcat(message,"\r\n");}
if(argc>5) {
sprintf(message+strlen(message),"Content-Length: %d\r\n",(int)strlen(argv[5]));
sprintf(message+strlen(message),"Content-Type: application/x-www-form-urlencoded\r\n");
}
strcat(message,"\r\n"); /* blank line */
if(argc>5)
strcat(message,argv[5]); /* body */
}
printf("Processed\n");
/* What are we going to send? */
printf("Request:\n%s\n",message);
#ifdef _WIN32
win_send_http(message);
#endif
#ifdef __linux__
linx_send_http(message);
#endif
return 0;
}
このプログラムを利用して、例のTinyWebDBを読み書きしてみる。
まずPostで、データを書き込む
C:\Users\chen\Documents\C\http-client>http-client-3 tinydb.work 80 POST /api/storeavalue/ “tag=presentationtimer&value=Just a TEST from C3”
Process 2 Allocating... Processed Request: POST /api/storeavalue/ HTTP/1.0 Host: tinydb.work Content-Length: 47 Content-Type: application/x-www-form-urlencoded tag=presentationtimer&value=Just a TEST from C3 Initialising Winsock...Initialised. Socket created. Connected Data Send Reply received HTTP/1.1 200 OK Server: nginx Date: Tue, 12 Dec 2017 06:56:12 GMT Content-Type: application/json Content-Length: 52 Connection: close X-Powered-By: PHP/5.6.31 Vary: Cookie Set-Cookie: wfvt_2029330401=5a2f7d8c36e15; expires=Tue, 12-Dec-2017 07:26:12 GMT; Max-Age=1800; path=/; httponly Expires: Mon, 26 Jul 1997 05:00:00 GMT Cache-Control: no-cache, must-revalidate ["STORED","presentationtimer","Just a TEST from C3"]
次は、Getで、書き込んだデータを取得
C:\Users\chen\Documents\C\http-client>http-client-3 tinydb.work 80 POST /api/getvalue/ “tag=presentationtimer”
Process 2 Allocating... Processed Request: POST /api/getvalue/ HTTP/1.0 Host: tinydb.work Content-Length: 21 Content-Type: application/x-www-form-urlencoded tag=presentationtimer Initialising Winsock...Initialised. Socket created. Connected Data Send Reply received HTTP/1.1 200 OK Server: nginx Date: Tue, 12 Dec 2017 06:57:10 GMT Content-Type: application/json Content-Length: 51 Connection: close X-Powered-By: PHP/5.6.31 Vary: Cookie Set-Cookie: wfvt_2029330401=5a2f7dc61d61c; expires=Tue, 12-Dec-2017 07:27:10 GMT; Max-Age=1800; path=/; httponly Expires: Mon, 26 Jul 1997 05:00:00 GMT Cache-Control: no-cache, must-revalidate ["VALUE","presentationtimer","Just a TEST from C3"]
DUMP で出力された内容を ダンプリスト と呼ぶ
ダンプリスト左端はアドレス(ファイル先頭からの位置)
ダンプリスト中央にある16進数(バイト)が列挙されてる部分がマシン語プログラム(バイトコード)を表している。
ダンプリスト右端は、バイトコードをキャラクタコードで表現したときの内容。ただしバイトで表現可能な数値はキャラクタコードの範疇を超えることがあるため、そのような場合はピリオドで表現される。
dump.c
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE *fp;
unsigned char buf[16]; /* 読み込みバッファ */
unsigned long addr = 0; /* 先頭からのアドレス */
int readnum, i;
if(argc <= 1) {
printf("usage:dump filename\n");
return 1;
}
if(!(fp = fopen(argv[1], "rb"))) {
printf("file open error.\n");
return 1;
}
while(1) {
printf("%08x ", addr);
readnum = fread(buf, 1, 16, fp);
/* パイナリデータの表示 */
for(i = 0; i < readnum; i++) {
if( i == 8)
printf(" ");
printf("%02x ", buf[i]);
}
for(i =readnum; i < 16; i++) {
if(i == 8)
printf(" ");
printf(" ");
}
printf(" ");
for(i = 0; i < readnum; i++)
printf("%c", (32 <= buf[i] && buf[i] <= 126) ? buf[i] : '.');
printf("\n");
addr += 16;
if(feof(fp))
break;
}
fclose(fp);
return 0;
}

C言語の最小限の開発環境を作る手順
Atomという新世代のエディター(Windows、Mac OS X、Linux対応)をインストールしてください。
LinuxでのC言語開発環境について解説しています。「GNU Compiler Collection」が一般的です。
それでは gcc をインストールしていきます。
Debianでは、apt-getコマンドを使ってgccをインストールします。
# apt-get install gcc
UbuntuはDebianベースのディストリビューションなので、Debianと同じようにa apt-getコマンドを使います。ただ、Ubuntuにはrootユーザーという概念がないので、sudoコマンドでインストールしていきます。
$ sudo apt-get install gcc
CentOSでは、yumコマンドを使ってgccをインストールします。
# yum install gcc
以上で、コンパイラ(gcc)のインストールは完了です。
不要です。
C言語プログラムのファイル名を「hello.c」というファイルを作成します。ファイルの中身は「Hello, World!」という文字列を出力するプログラムです。
hello.cをコンパイルします。
$ gcc hello.c
エラーが表示されなければ、OKです。
実行します。
$ ./a.out Hello, World
無事に実行できましたね。